aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-10-30 17:42:04 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2019-10-30 17:42:04 +0000
commitce001b300fc7bd22cbb2712b6d06e5043fe6354f (patch)
treeb2683f18d18e9fffb66104d9f990fc5557782463
parent411679568b2e3b1ca9b84673c430f2fdc9360368 (diff)
downloadgcc-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/ChangeLog3
-rw-r--r--libstdc++-v3/include/std/concepts42
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