aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-11-28 12:32:59 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2024-12-02 19:38:57 +0000
commit1467409beb27a693e96994899f30e4db015b5c2c (patch)
tree9e3d113b6fd05d7345ec6fd0b7e5761568d4c275
parent4df8e6fc0cbc8358f88e81bb64b790af2a848a35 (diff)
downloadgcc-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.h33
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>