replaced try blocks with scope guards

This commit is contained in:
joaquintides
2022-10-18 16:14:29 +02:00
parent a200af610f
commit 2290375515

View File

@@ -1147,21 +1147,15 @@ public:
} }
else{ else{
reserve(x.size()); reserve(x.size());
BOOST_TRY{ clear_on_exit c{x};
/* This works because subsequent x.clear() does not depend on the (void)c; /* unused var warning */
* elements' values.
*/
x.for_all_elements([this](value_type* p){ /* This works because subsequent x.clear() does not depend on the
unchecked_insert(type_policy::move(*p)); * elements' values.
}); */
} x.for_all_elements([this](value_type* p){
BOOST_CATCH(...){ unchecked_insert(type_policy::move(*p));
x.clear(); });
BOOST_RETHROW
}
BOOST_CATCH_END
x.clear();
} }
} }
@@ -1209,19 +1203,6 @@ public:
static constexpr auto pocma= static constexpr auto pocma=
alloc_traits::propagate_on_container_move_assignment::value; 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)){ if(this!=std::addressof(x)){
clear(); clear();
h()=std::move(x.h()); h()=std::move(x.h());
@@ -1234,28 +1215,19 @@ public:
swap(arrays,x.arrays); swap(arrays,x.arrays);
swap(ml,x.ml); swap(ml,x.ml);
} }
else if_constexpr<!alloc_traits::is_always_equal::value>([&,this]{ else{
/* 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.
*/
/* noshrink: favor memory reuse over tightness */ /* noshrink: favor memory reuse over tightness */
noshrink_reserve(x.size()); noshrink_reserve(x.size());
BOOST_TRY{ clear_on_exit c{x};
/* This works because subsequent x.clear() does not depend on the (void)c; /* unused var warning */
* elements' values.
*/
x.for_all_elements(move_element); /* This works because subsequent x.clear() does not depend on the
} * elements' values.
BOOST_CATCH(...){ */
x.clear(); x.for_all_elements([this](value_type* p){
BOOST_RETHROW unchecked_insert(type_policy::move(*p));
} });
BOOST_CATCH_END }
x.clear();
});
} }
return *this; return *this;
} }
@@ -1452,6 +1424,12 @@ private:
template<typename,typename,typename,typename> friend class table; template<typename,typename,typename,typename> friend class table;
using arrays_type=table_arrays<value_type,group_type,size_policy>; using arrays_type=table_arrays<value_type,group_type,size_policy>;
struct clear_on_exit
{
~clear_on_exit(){x.clear();}
table& x;
};
Hash& h(){return hash_base::get();} Hash& h(){return hash_base::get();}
const Hash& h()const{return hash_base::get();} const Hash& h()const{return hash_base::get();}
Pred& pred(){return pred_base::get();} Pred& pred(){return pred_base::get();}