Commit ce001b30 by Jonathan Wakely Committed by Jonathan Wakely

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
parent 41167956
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.
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment