libstdc++: define std::common_comparison_category for C++20
* libsupc++/compare (common_comparison_category) (common_comparison_category_t): Define for C++20. * testsuite/18_support/comparisons/common/1.cc: New test. From-SVN: r277943
This commit is contained in:
parent
780bc8922b
commit
2966952166
|
@ -1,5 +1,9 @@
|
||||||
2019-11-07 Jonathan Wakely <jwakely@redhat.com>
|
2019-11-07 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
* libsupc++/compare (common_comparison_category)
|
||||||
|
(common_comparison_category_t): Define for C++20.
|
||||||
|
* testsuite/18_support/comparisons/common/1.cc: New test.
|
||||||
|
|
||||||
* include/bits/stl_algo.h (for_each_n): Handle negative count.
|
* include/bits/stl_algo.h (for_each_n): Handle negative count.
|
||||||
* testsuite/25_algorithms/for_each/for_each_n_debug.cc: New test.
|
* testsuite/25_algorithms/for_each/for_each_n_debug.cc: New test.
|
||||||
|
|
||||||
|
|
|
@ -385,18 +385,81 @@ namespace std
|
||||||
is_gteq(partial_ordering __cmp) noexcept
|
is_gteq(partial_ordering __cmp) noexcept
|
||||||
{ return __cmp >= 0; }
|
{ return __cmp >= 0; }
|
||||||
|
|
||||||
|
#if __cpp_lib_concepts
|
||||||
|
namespace __detail
|
||||||
|
{
|
||||||
|
template<typename _Tp>
|
||||||
|
inline constexpr unsigned __cmp_cat_id = 1;
|
||||||
|
template<>
|
||||||
|
inline constexpr unsigned __cmp_cat_id<strong_ordering> = 2;
|
||||||
|
template<>
|
||||||
|
inline constexpr unsigned __cmp_cat_id<weak_ordering> = 4;
|
||||||
|
template<>
|
||||||
|
inline constexpr unsigned __cmp_cat_id<partial_ordering> = 8;
|
||||||
|
|
||||||
|
template<typename... _Ts>
|
||||||
|
constexpr unsigned __cmp_cat_ids()
|
||||||
|
{ return (__cmp_cat_id<_Ts> | ...); }
|
||||||
|
|
||||||
|
template<unsigned>
|
||||||
|
struct __common_cmp_cat;
|
||||||
|
|
||||||
|
// If any Ti is not a comparison category type, U is void.
|
||||||
|
template<unsigned _Bits>
|
||||||
|
requires ((_Bits & 1) == 1)
|
||||||
|
struct __common_cmp_cat<_Bits> { using type = void; };
|
||||||
|
|
||||||
|
// Otherwise, if at least one Ti is std::partial_ordering,
|
||||||
|
// U is std::partial_ordering.
|
||||||
|
template<unsigned _Bits>
|
||||||
|
requires ((_Bits & 0b1001) == 0b1000)
|
||||||
|
struct __common_cmp_cat<_Bits> { using type = partial_ordering; };
|
||||||
|
|
||||||
|
// Otherwise, if at least one Ti is std::weak_ordering,
|
||||||
|
// U is std::weak_ordering.
|
||||||
|
template<unsigned _Bits>
|
||||||
|
requires ((_Bits & 0b1101) == 0b0100)
|
||||||
|
struct __common_cmp_cat<_Bits> { using type = weak_ordering; };
|
||||||
|
|
||||||
|
// Otherwise, U is std::strong_ordering.
|
||||||
|
template<>
|
||||||
|
struct __common_cmp_cat<0b0010> { using type = strong_ordering; };
|
||||||
|
} // namespace __detail
|
||||||
|
|
||||||
// [cmp.common], common comparison category type
|
// [cmp.common], common comparison category type
|
||||||
template<typename... _Ts>
|
template<typename... _Ts>
|
||||||
struct common_comparison_category
|
struct common_comparison_category
|
||||||
{
|
{
|
||||||
// using type = TODO
|
using type
|
||||||
|
= __detail::__common_cmp_cat<__detail::__cmp_cat_ids<_Ts...>()>::type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Partial specializations for one and zero argument cases.
|
||||||
|
|
||||||
|
template<typename _Tp>
|
||||||
|
struct common_comparison_category<_Tp>
|
||||||
|
{ using type = void; };
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct common_comparison_category<partial_ordering>
|
||||||
|
{ using type = partial_ordering; };
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct common_comparison_category<weak_ordering>
|
||||||
|
{ using type = weak_ordering; };
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct common_comparison_category<strong_ordering>
|
||||||
|
{ using type = strong_ordering; };
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct common_comparison_category<>
|
||||||
|
{ using type = strong_ordering; };
|
||||||
|
|
||||||
template<typename... _Ts>
|
template<typename... _Ts>
|
||||||
using common_comparison_category_t
|
using common_comparison_category_t
|
||||||
= typename common_comparison_category<_Ts...>::type;
|
= typename common_comparison_category<_Ts...>::type;
|
||||||
|
|
||||||
#if __cpp_lib_concepts
|
|
||||||
namespace __detail
|
namespace __detail
|
||||||
{
|
{
|
||||||
template<typename _Tp, typename _Cat>
|
template<typename _Tp, typename _Cat>
|
||||||
|
@ -493,22 +556,22 @@ namespace std
|
||||||
template<typename _Tp, typename _Up>
|
template<typename _Tp, typename _Up>
|
||||||
requires (three_way_comparable_with<_Tp, _Up>
|
requires (three_way_comparable_with<_Tp, _Up>
|
||||||
|| __detail::__3way_builtin_ptr_cmp<_Tp, _Up>)
|
|| __detail::__3way_builtin_ptr_cmp<_Tp, _Up>)
|
||||||
constexpr auto
|
constexpr auto
|
||||||
operator()(_Tp&& __t, _Up&& __u) const noexcept
|
operator()(_Tp&& __t, _Up&& __u) const noexcept
|
||||||
{
|
{
|
||||||
if constexpr (__detail::__3way_builtin_ptr_cmp<_Tp, _Up>)
|
if constexpr (__detail::__3way_builtin_ptr_cmp<_Tp, _Up>)
|
||||||
{
|
{
|
||||||
auto __pt = static_cast<const volatile void*>(__t);
|
auto __pt = static_cast<const volatile void*>(__t);
|
||||||
auto __pu = static_cast<const volatile void*>(__u);
|
auto __pu = static_cast<const volatile void*>(__u);
|
||||||
if (__builtin_is_constant_evaluated())
|
if (__builtin_is_constant_evaluated())
|
||||||
return __pt <=> __pu;
|
return __pt <=> __pu;
|
||||||
auto __it = reinterpret_cast<__UINTPTR_TYPE__>(__pt);
|
auto __it = reinterpret_cast<__UINTPTR_TYPE__>(__pt);
|
||||||
auto __iu = reinterpret_cast<__UINTPTR_TYPE__>(__pu);
|
auto __iu = reinterpret_cast<__UINTPTR_TYPE__>(__pu);
|
||||||
return __it <=> __iu;
|
return __it <=> __iu;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return static_cast<_Tp&&>(__t) <=> static_cast<_Up&&>(__u);
|
return static_cast<_Tp&&>(__t) <=> static_cast<_Up&&>(__u);
|
||||||
}
|
}
|
||||||
|
|
||||||
using is_transparent = void;
|
using is_transparent = void;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++2a" }
|
||||||
|
// { dg-do compile { target c++2a } }
|
||||||
|
|
||||||
|
#include <compare>
|
||||||
|
|
||||||
|
template<typename Cat, typename... T>
|
||||||
|
constexpr bool check()
|
||||||
|
{
|
||||||
|
return std::same_as<Cat, std::common_comparison_category_t<T...>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
using std::partial_ordering;
|
||||||
|
using std::weak_ordering;
|
||||||
|
using std::strong_ordering;
|
||||||
|
|
||||||
|
static_assert(check<strong_ordering>());
|
||||||
|
static_assert(check<void, int>());
|
||||||
|
static_assert(check<void, int, int>());
|
||||||
|
static_assert(check<void, weak_ordering, int>());
|
||||||
|
static_assert(check<void, int, partial_ordering>());
|
||||||
|
static_assert(check<partial_ordering, partial_ordering>());
|
||||||
|
static_assert(check<partial_ordering, weak_ordering, partial_ordering>());
|
||||||
|
|
||||||
|
using PO = std::partial_ordering;
|
||||||
|
using WO = std::weak_ordering;
|
||||||
|
using SO = std::strong_ordering;
|
||||||
|
|
||||||
|
static_assert(check<PO, SO, PO, SO, SO>());
|
||||||
|
static_assert(check<PO, SO, PO, SO, WO>());
|
||||||
|
static_assert(check<WO, SO, WO, SO, WO>());
|
||||||
|
static_assert(check<SO, SO, SO, SO, SO>());
|
Loading…
Reference in New Issue