There's no need to keep using std::find_if from the beginning of the
container after every removal, just update the iterator after erasing an
element.
This is how C++20 std::erase_if is implemented.
gcc/cobol/ChangeLog:
* except.cc (cbl_enabled_exceptions_t::turn_on_off): Replace
quadratic loop with a single pass.
---
Tested x86_64-linux with make check-gcc-cobol.
gcc/cobol/except.cc | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/gcc/cobol/except.cc b/gcc/cobol/except.cc
index 5374201b4c8..43339627f1d 100644
--- a/gcc/cobol/except.cc
+++ b/gcc/cobol/except.cc
@@ -116,31 +116,27 @@ cbl_enabled_exceptions_t::turn_on_off( bool enabled,
return true;
}
- /*
- * std::remove_if cannot be used with std::set because its elements are
const.
- * std::set::erase_if became available only in C++20.
- */
+ // std::set::erase_if became available only in C++20.
if( enabled ) { // remove any disabled
if( files.empty() ) {
auto p = begin();
- while( end() != (p = std::find_if( begin(), end(),
- [ec = type]( const auto& elem ) {
- return
- !elem.enabled &&
- ec_cmp(ec, elem.ec); } )) ) {
- erase(p);
+ while( p != end() ) {
+ if( !p->enabled && ec_cmp(type, p->ec) ) {
+ p = erase(p);
+ } else {
+ ++p;
+ }
}
} else {
for( size_t file: files ) {
auto p = begin();
- while( end() != (p = std::find_if( begin(), end(),
- [ec = type, file]( const auto& elem
) {
- return
- !elem.enabled &&
- file == elem.file &&
- ec_cmp(ec, elem.ec); } )) ) {
- erase(p);
- }
+ while( p != end() ) {
+ if( !p->enabled && file == p->file && ec_cmp(type, p->ec) ) {
+ p = erase(p);
+ } else {
+ ++p;
+ }
+ }
}
}
auto elem = cbl_enabled_exception_t(enabled, location, type);
--
2.48.1