diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2024-03-18 16:58:23 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2024-06-07 10:26:18 +0100 |
commit | 94997567ea5cbeb35571e94cf76d7f99ea3f9c43 (patch) | |
tree | abd7036e5416199e5adee3f84648aa3cafe9e04d | |
parent | e4f1c1be61d916345655d5edba309502046c9473 (diff) | |
download | gcc-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.h | 47 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/to_address/1_neg.cc | 2 |
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> |