diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-10-30 17:42:04 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-10-30 17:42:04 +0000 |
commit | ce001b300fc7bd22cbb2712b6d06e5043fe6354f (patch) | |
tree | b2683f18d18e9fffb66104d9f990fc5557782463 | |
parent | 411679568b2e3b1ca9b84673c430f2fdc9360368 (diff) | |
download | gcc-ce001b300fc7bd22cbb2712b6d06e5043fe6354f.zip gcc-ce001b300fc7bd22cbb2712b6d06e5043fe6354f.tar.gz gcc-ce001b300fc7bd22cbb2712b6d06e5043fe6354f.tar.bz2 |
Use if-constexpr instead of overloading for customization point
This combines two of the std::ranges::swap.operator() overloads into a
single function template. Using if-constexpr to choose between
implementations should give the compiler less work to do than using
overloading.
* include/std/concepts (std::ranges::swap): Use a single overload for
the non-array cases, and switch using if-constexpr.
From-SVN: r277635
-rw-r--r-- | libstdc++-v3/ChangeLog | 3 | ||||
-rw-r--r-- | libstdc++-v3/include/std/concepts | 42 |
2 files changed, 30 insertions, 15 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 864c8aa..059976e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,8 @@ 2019-10-30 Jonathan Wakely <jwakely@redhat.com> + * include/std/concepts (std::ranges::swap): Use a single overload for + the non-array cases, and switch using if-constexpr. + * include/bits/stl_iterator.h (__normal_iterator::iterator_concept): Guard with __cpp_lib_concepts macro. diff --git a/libstdc++-v3/include/std/concepts b/libstdc++-v3/include/std/concepts index 68cbba9..c4acfd2 100644 --- a/libstdc++-v3/include/std/concepts +++ b/libstdc++-v3/include/std/concepts @@ -173,12 +173,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _Swap { + private: + template<typename _Tp, typename _Up> + static constexpr bool + _S_noexcept() + { + if constexpr (__adl_swap<_Tp, _Up>) + return noexcept(swap(std::declval<_Tp>(), std::declval<_Up>())); + else + return is_nothrow_move_constructible_v<remove_reference_t<_Tp>> + && is_nothrow_move_assignable_v<remove_reference_t<_Tp>>; + } + + public: template<typename _Tp, typename _Up> requires __adl_swap<_Tp, _Up> + || (same_as<_Tp, _Up> && is_lvalue_reference_v<_Tp> + && move_constructible<remove_reference_t<_Tp>> + && assignable_from<_Tp, remove_reference_t<_Tp>>) constexpr void operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))) - { swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u)); } + noexcept(_S_noexcept<_Tp, _Up>()) + { + if constexpr (__adl_swap<_Tp, _Up>) + swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u)); + else + { + auto __tmp = static_cast<remove_reference_t<_Tp>&&>(__t); + __t = static_cast<remove_reference_t<_Tp>&&>(__u); + __u = static_cast<remove_reference_t<_Tp>&&>(__tmp); + } + } template<typename _Tp, typename _Up, size_t _Num> requires requires(const _Swap& __swap, _Tp& __e1, _Up& __e2) { @@ -191,19 +216,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION for (size_t __n = 0; __n < _Num; ++__n) (*this)(__e1[__n], __e2[__n]); } - - template<typename _Tp> - requires (!__adl_swap<_Tp&, _Tp&> - && move_constructible<_Tp> && assignable_from<_Tp&, _Tp>) - constexpr void - operator()(_Tp& __e1, _Tp& __e2) const - noexcept(is_nothrow_move_constructible_v<_Tp> - && is_nothrow_move_assignable_v<_Tp>) - { - _Tp __tmp = static_cast<_Tp&&>(__e1); - __e1 = static_cast<_Tp&&>(__e2); - __e2 = static_cast<_Tp&&>(__tmp); - } }; } // namespace __cust_swap |