diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-12-05 00:42:06 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-12-05 00:42:06 +0000 |
commit | 3a4cc6281b56c52136cc755e46776c025114d865 (patch) | |
tree | 204b53d72bcd8d72a429ccc276d959002b69f048 /libstdc++-v3 | |
parent | 880c7b8c2570544ae4218374688a10a98c9d6542 (diff) | |
download | gcc-3a4cc6281b56c52136cc755e46776c025114d865.zip gcc-3a4cc6281b56c52136cc755e46776c025114d865.tar.gz gcc-3a4cc6281b56c52136cc755e46776c025114d865.tar.bz2 |
libstdc++: Implement spaceship for std::array (P1614R2)
As done for std::pair, this defines operator<=> as a non-member function
template and does not alter operator==, as expected to be proposed as
the resolution to an unpublished LWG issue.
Instead of calling std::lexicographical_compare_three_way the <=>
overload is implemented by hand to take advantage of the fact the
element types and array sizes are known to be the same.
* include/bits/cpp_type_traits.h (__is_byte<char8_t>): Add
specialization.
* include/std/array (operator<=>): Likewise.
* testsuite/23_containers/array/comparison_operators/constexpr.cc:
Test three-way comparisons and arrays of unsigned char.
* testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust
dg-error line numbers.
From-SVN: r278981
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/cpp_type_traits.h | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/std/array | 20 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/array/comparison_operators/constexpr.cc | 20 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc | 6 |
5 files changed, 62 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 50f506c..ec5c0ef 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2019-12-05 Jonathan Wakely <jwakely@redhat.com> + + * include/bits/cpp_type_traits.h (__is_byte<char8_t>): Add + specialization. + * include/std/array (operator<=>): Likewise. + * testsuite/23_containers/array/comparison_operators/constexpr.cc: + Test three-way comparisons and arrays of unsigned char. + * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust + dg-error line numbers. + 2019-12-03 Jonathan Wakely <jwakely@redhat.com> * include/bits/stl_pair.h [__cpp_lib_three_way_comparison] diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h index 3e165c7..28180bf 100644 --- a/libstdc++-v3/include/bits/cpp_type_traits.h +++ b/libstdc++-v3/include/bits/cpp_type_traits.h @@ -411,6 +411,15 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3) }; #endif // C++17 +#ifdef _GLIBCXX_USE_CHAR8_T + template<> + struct __is_byte<char8_t> + { + enum { __value = 1 }; + typedef __true_type __type; + }; +#endif + // // Move iterator type // diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 9ad1e65..ad3f651 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -253,6 +253,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return std::equal(__one.begin(), __one.end(), __two.begin()); } +#if __cpp_lib_three_way_comparison && __cpp_lib_concepts + template<typename _Tp, size_t _Nm> + constexpr __detail::__synth3way_t<_Tp> + operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) + { + if constexpr (_Nm && __is_byte<_Tp>::__value) + return __builtin_memcmp(__a.data(), __b.data(), _Nm) <=> 0; + else + { + for (size_t __i = 0; __i < _Nm; ++__i) + { + auto __c = __detail::__synth3way(__a[__i], __b[__i]); + if (__c != 0) + return __c; + } + } + return strong_ordering::equal; + } +#else template<typename _Tp, std::size_t _Nm> _GLIBCXX20_CONSTEXPR inline bool @@ -285,6 +304,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER inline bool operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one < __two); } +#endif // three_way_comparison && concepts // Specialized algorithms. template<typename _Tp, std::size_t _Nm> diff --git a/libstdc++-v3/testsuite/23_containers/array/comparison_operators/constexpr.cc b/libstdc++-v3/testsuite/23_containers/array/comparison_operators/constexpr.cc index 8655a9b..91a8a24 100644 --- a/libstdc++-v3/testsuite/23_containers/array/comparison_operators/constexpr.cc +++ b/libstdc++-v3/testsuite/23_containers/array/comparison_operators/constexpr.cc @@ -31,3 +31,23 @@ static_assert(a1 < a3); static_assert(a4 > a1); static_assert(a1 <= a3); static_assert(a4 >= a1); +static_assert(std::is_eq(a1 <=> a1)); +static_assert(std::is_neq(a1 <=> a2)); +static_assert(std::is_lt(a1 <=> a3)); +static_assert(std::is_gt(a4 <=> a1)); + +constexpr std::array<unsigned char, 3> a5{{1, 2, 3}}; +constexpr std::array<unsigned char, 3> a6{{4, 5, 6}}; +constexpr std::array<unsigned char, 3> a7{{1, 2, 4}}; +constexpr std::array<unsigned char, 3> a8{{1, 3, 3}}; + +static_assert(a5 == a5); +static_assert(a5 != a6); +static_assert(a5 < a7); +static_assert(a8 > a5); +static_assert(a5 <= a7); +static_assert(a8 >= a5); +static_assert(std::is_eq(a5 <=> a5)); +static_assert(std::is_neq(a5 <=> a6)); +static_assert(std::is_lt(a5 <=> a7)); +static_assert(std::is_gt(a8 <=> a5)); diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc index 2ae8a5e..7833748 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc @@ -27,6 +27,6 @@ int n1 = std::get<1>(a); int n2 = std::get<1>(std::move(a)); int n3 = std::get<1>(ca); -// { dg-error "static assertion failed" "" { target *-*-* } 316 } -// { dg-error "static assertion failed" "" { target *-*-* } 325 } -// { dg-error "static assertion failed" "" { target *-*-* } 333 } +// { dg-error "static assertion failed" "" { target *-*-* } 336 } +// { dg-error "static assertion failed" "" { target *-*-* } 345 } +// { dg-error "static assertion failed" "" { target *-*-* } 353 } |