aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std/array
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-12-05 00:42:06 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2019-12-05 00:42:06 +0000
commit3a4cc6281b56c52136cc755e46776c025114d865 (patch)
tree204b53d72bcd8d72a429ccc276d959002b69f048 /libstdc++-v3/include/std/array
parent880c7b8c2570544ae4218374688a10a98c9d6542 (diff)
downloadgcc-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/include/std/array')
-rw-r--r--libstdc++-v3/include/std/array20
1 files changed, 20 insertions, 0 deletions
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>