aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-03-18 16:58:23 +0000
committerJonathan Wakely <jwakely@redhat.com>2024-06-07 10:26:18 +0100
commit94997567ea5cbeb35571e94cf76d7f99ea3f9c43 (patch)
treeabd7036e5416199e5adee3f84648aa3cafe9e04d
parente4f1c1be61d916345655d5edba309502046c9473 (diff)
downloadgcc-94997567ea5cbeb35571e94cf76d7f99ea3f9c43.zip
gcc-94997567ea5cbeb35571e94cf76d7f99ea3f9c43.tar.gz
gcc-94997567ea5cbeb35571e94cf76d7f99ea3f9c43.tar.bz2
libstdc++: Optimize std::to_address
We can use if-constexpr and variable templates to simplify and optimize std::to_address. This should compile faster (and run faster for -O0) than dispatching to the pre-C++20 std::__to_address overloads. libstdc++-v3/ChangeLog: * include/bits/ptr_traits.h (to_address): Optimize. * testsuite/20_util/to_address/1_neg.cc: Adjust dg-error text.
-rw-r--r--libstdc++-v3/include/bits/ptr_traits.h47
-rw-r--r--libstdc++-v3/testsuite/20_util/to_address/1_neg.cc2
2 files changed, 28 insertions, 21 deletions
diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h
index 6c65001..ca67fee 100644
--- a/libstdc++-v3/include/bits/ptr_traits.h
+++ b/libstdc++-v3/include/bits/ptr_traits.h
@@ -200,36 +200,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Ptr, typename _Tp>
using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>;
+#ifndef __glibcxx_to_address // C++ < 20
template<typename _Tp>
+ [[__gnu__::__always_inline__]]
constexpr _Tp*
__to_address(_Tp* __ptr) noexcept
{
- static_assert(!std::is_function<_Tp>::value, "not a function pointer");
+ static_assert(!std::is_function<_Tp>::value, "std::to_address argument "
+ "must not be a function pointer");
return __ptr;
}
-#ifndef __glibcxx_to_address // C++ < 20
template<typename _Ptr>
constexpr typename std::pointer_traits<_Ptr>::element_type*
__to_address(const _Ptr& __ptr)
{ return std::__to_address(__ptr.operator->()); }
#else
- template<typename _Ptr>
- constexpr auto
- __to_address(const _Ptr& __ptr) noexcept
- -> decltype(std::pointer_traits<_Ptr>::to_address(__ptr))
- { return std::pointer_traits<_Ptr>::to_address(__ptr); }
-
- template<typename _Ptr, typename... _None>
- constexpr auto
- __to_address(const _Ptr& __ptr, _None...) noexcept
- {
- if constexpr (is_base_of_v<__gnu_debug::_Safe_iterator_base, _Ptr>)
- return std::__to_address(__ptr.base().operator->());
- else
- return std::__to_address(__ptr.operator->());
- }
-
/**
* @brief Obtain address referenced by a pointer to an object
* @param __ptr A pointer to an object
@@ -237,9 +223,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @ingroup pointer_abstractions
*/
template<typename _Tp>
+ [[__gnu__::__always_inline__]]
constexpr _Tp*
to_address(_Tp* __ptr) noexcept
- { return std::__to_address(__ptr); }
+ {
+ static_assert(!is_function_v<_Tp>, "std::to_address argument "
+ "must not be a function pointer");
+ return __ptr;
+ }
/**
* @brief Obtain address referenced by a pointer to an object
@@ -251,7 +242,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Ptr>
constexpr auto
to_address(const _Ptr& __ptr) noexcept
- { return std::__to_address(__ptr); }
+ {
+ if constexpr (requires { pointer_traits<_Ptr>::to_address(__ptr); })
+ return pointer_traits<_Ptr>::to_address(__ptr);
+ else if constexpr (is_base_of_v<__gnu_debug::_Safe_iterator_base, _Ptr>)
+ return std::to_address(__ptr.base().operator->());
+ else
+ return std::to_address(__ptr.operator->());
+ }
+
+ /// @cond undocumented
+ /// Compatibility for use in code that is also compiled as pre-C++20.
+ template<typename _Ptr>
+ [[__gnu__::__always_inline__]]
+ constexpr auto
+ __to_address(const _Ptr& __ptr) noexcept
+ { return std::to_address(__ptr); }
+ /// @endcond
#endif // __glibcxx_to_address
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/testsuite/20_util/to_address/1_neg.cc b/libstdc++-v3/testsuite/20_util/to_address/1_neg.cc
index 7385f0f..10e9197 100644
--- a/libstdc++-v3/testsuite/20_util/to_address/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/to_address/1_neg.cc
@@ -16,7 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++20 } }
-// { dg-error "not a function pointer" "" { target *-*-* } 0 }
+// { dg-error "must not be a function pointer" "" { target *-*-* } 0 }
#include <memory>