diff --git a/include/boost/unordered/detail/foa.hpp b/include/boost/unordered/detail/foa.hpp index d75d842b..0de4782c 100644 --- a/include/boost/unordered/detail/foa.hpp +++ b/include/boost/unordered/detail/foa.hpp @@ -1147,21 +1147,15 @@ public: } else{ reserve(x.size()); - BOOST_TRY{ - /* This works because subsequent x.clear() does not depend on the - * elements' values. - */ + clear_on_exit c{x}; + (void)c; /* unused var warning */ - x.for_all_elements([this](value_type* p){ - unchecked_insert(type_policy::move(*p)); - }); - } - BOOST_CATCH(...){ - x.clear(); - BOOST_RETHROW - } - BOOST_CATCH_END - x.clear(); + /* This works because subsequent x.clear() does not depend on the + * elements' values. + */ + x.for_all_elements([this](value_type* p){ + unchecked_insert(type_policy::move(*p)); + }); } } @@ -1209,19 +1203,6 @@ public: static constexpr auto pocma= alloc_traits::propagate_on_container_move_assignment::value; - /* Avoid using nested lambdas with a `this` capture as it seems to trigger - * a bug in GCC: - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80947 - * - * Rather than directly attempting to manipulate the visibility of the - * table class, it's easier to work around the bug by simply un-nesting the - * lambda. - */ - - auto const move_element=[this](value_type* p){ - unchecked_insert(type_policy::move(*p)); - }; - if(this!=std::addressof(x)){ clear(); h()=std::move(x.h()); @@ -1234,28 +1215,19 @@ public: swap(arrays,x.arrays); swap(ml,x.ml); } - else if_constexpr([&,this]{ - /* The check above is redundant: we're setting up a compile-time - * barrier so that the compiler is convinced we're not throwing - * under noexcept(true) conditions. - */ - + else{ /* noshrink: favor memory reuse over tightness */ noshrink_reserve(x.size()); - BOOST_TRY{ - /* This works because subsequent x.clear() does not depend on the - * elements' values. - */ + clear_on_exit c{x}; + (void)c; /* unused var warning */ - x.for_all_elements(move_element); - } - BOOST_CATCH(...){ - x.clear(); - BOOST_RETHROW - } - BOOST_CATCH_END - x.clear(); - }); + /* This works because subsequent x.clear() does not depend on the + * elements' values. + */ + x.for_all_elements([this](value_type* p){ + unchecked_insert(type_policy::move(*p)); + }); + } } return *this; } @@ -1452,6 +1424,12 @@ private: template friend class table; using arrays_type=table_arrays; + struct clear_on_exit + { + ~clear_on_exit(){x.clear();} + table& x; + }; + Hash& h(){return hash_base::get();} const Hash& h()const{return hash_base::get();} Pred& pred(){return pred_base::get();}