diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2024-11-28 12:32:59 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2024-12-02 19:38:57 +0000 |
commit | 1467409beb27a693e96994899f30e4db015b5c2c (patch) | |
tree | 9e3d113b6fd05d7345ec6fd0b7e5761568d4c275 | |
parent | 4df8e6fc0cbc8358f88e81bb64b790af2a848a35 (diff) | |
download | gcc-1467409beb27a693e96994899f30e4db015b5c2c.zip gcc-1467409beb27a693e96994899f30e4db015b5c2c.tar.gz gcc-1467409beb27a693e96994899f30e4db015b5c2c.tar.bz2 |
libstdc++: Simplify std::_Destroy using 'if constexpr'
This is another place where we can use 'if constexpr' to replace
dispatching to a specialized class template, improving compile times and
avoiding a function call.
libstdc++-v3/ChangeLog:
* include/bits/stl_construct.h (_Destroy(FwdIter, FwdIter)): Use
'if constexpr' instead of dispatching to a member function of a
class template.
(_Destroy_n(FwdIter, Size)): Likewise.
(_Destroy_aux, _Destroy_n_aux): Only define for C++98.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
-rw-r--r-- | libstdc++-v3/include/bits/stl_construct.h | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h index 9d61113..6889a9b 100644 --- a/libstdc++-v3/include/bits/stl_construct.h +++ b/libstdc++-v3/include/bits/stl_construct.h @@ -166,6 +166,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // for if-constexpr + +#if __cplusplus < 201103L template<bool> struct _Destroy_aux { @@ -185,6 +189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static void __destroy(_ForwardIterator, _ForwardIterator) { } }; +#endif /** * Destroy a range of objects. If the value_type of the object has @@ -201,15 +206,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // A deleted destructor is trivial, this ensures we reject such types: static_assert(is_destructible<_Value_type>::value, "value type is destructible"); -#endif + if constexpr (!__has_trivial_destructor(_Value_type)) + for (; __first != __last; ++__first) + std::_Destroy(std::__addressof(*__first)); #if __cpp_constexpr_dynamic_alloc // >= C++20 - if (std::__is_constant_evaluated()) - return std::_Destroy_aux<false>::__destroy(__first, __last); + else if (std::__is_constant_evaluated()) + for (; __first != __last; ++__first) + std::destroy_at(std::__addressof(*__first)); #endif +#else std::_Destroy_aux<__has_trivial_destructor(_Value_type)>:: __destroy(__first, __last); +#endif } +#if __cplusplus < 201103L template<bool> struct _Destroy_n_aux { @@ -234,6 +245,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __first; } }; +#endif /** * Destroy a range of objects. If the value_type of the object has @@ -250,14 +262,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // A deleted destructor is trivial, this ensures we reject such types: static_assert(is_destructible<_Value_type>::value, "value type is destructible"); -#endif + if constexpr (!__has_trivial_destructor(_Value_type)) + for (; __count > 0; (void)++__first, --__count) + std::_Destroy(std::__addressof(*__first)); #if __cpp_constexpr_dynamic_alloc // >= C++20 - if (std::__is_constant_evaluated()) - return std::_Destroy_n_aux<false>::__destroy_n(__first, __count); + else if (std::__is_constant_evaluated()) + for (; __count > 0; (void)++__first, --__count) + std::destroy_at(std::__addressof(*__first)); #endif + else + std::advance(__first, __count); + return __first; +#else return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>:: __destroy_n(__first, __count); +#endif } +#pragma GCC diagnostic pop #if __glibcxx_raw_memory_algorithms // >= C++17 template <typename _ForwardIterator> |