On 05/12/2019 13:46, Jonathan Wakely wrote:
commit 5012548fd62526fdf5e04aeacee2b127efbac0e0
Author: Jonathan Wakely <jwak...@redhat.com>
Date: Thu Dec 5 12:23:53 2019 +0000
libstdc++: Define std::lexicographical_compare_three_way for C++20
* include/bits/stl_algobase.h (lexicographical_compare_three_way):
Define for C++20.
* testsuite/25_algorithms/lexicographical_compare_three_way/1.cc:
New
test.
* testsuite/25_algorithms/lexicographical_compare_three_way/
constexpr.cc: New test.
diff --git a/libstdc++-v3/include/bits/stl_algobase.h
b/libstdc++-v3/include/bits/stl_algobase.h
index 98d324827ed..a2fd306e6d0 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
[...]
@@ -1456,6 +1459,104 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__gnu_cxx::__ops::__iter_comp_iter(__comp));
}
+#if __cpp_lib_three_way_comparison
+#if __cpp_lib_concepts
+ // Iter points to a contiguous range of unsigned narrow character type
+ // or std::byte, suitable for comparison by memcmp.
+ template<typename _Iter>
+ concept __is_byte_iter = contiguous_iterator<_Iter>
+ && __is_byte<iter_value_t<_Iter>>::__value != 0
+ && !__gnu_cxx::__numeric_traits<iter_value_t<_Iter>>::__is_signed;
+
+ // Return a struct with two members, initialized to the smaller of x and y
+ // (or x if they compare equal) and the result of the comparison x <=> y.
+ template<typename _Tp>
+ constexpr auto
+ __min_cmp(_Tp __x, _Tp __y)
+ {
+ struct _Res {
+ _Tp _M_min;
+ decltype(__x <=> __y) _M_cmp;
+ };
+ auto __c = __x <=> __y;
+ if (__c > 0)
+ return _Res{__y, __c};
+ return _Res{__x, __c};
+ }
+#endif
[...]
+
+ template<typename _InputIter1, typename _InputIter2>
+ constexpr auto
+ lexicographical_compare_three_way(_InputIter1 __first1,
+ _InputIter1 __last1,
+ _InputIter2 __first2,
+ _InputIter2 __last2)
+ {
+ return std::lexicographical_compare_three_way(__first1, __last1,
+ __first2, __last2,
+ compare_three_way{});
FYI, the above fails with -std=c++2a and recent Clang trunk after
<https://github.com/llvm/llvm-project/commit/bc633a42dd409dbeb456263e3388b8caa4680aa0>
"Mark the major papers for C++20 consistent comparisons as 'done', and
start publishing the corresponding feature-test macro": Clang now
defines __cpp_impl_three_way_comparison (so
libstdc++-v3/include/std/version defines __cpp_lib_three_way_comparison)
but still doesn't define __cpp_lib_concepts, so
libstdc++-v3/libsupc++/compare doesn't define compare_three_way.
I locally managed that for now with extending the surrounding
#if __cpp_lib_three_way_comparison
with
&& __cpp_lib_concepts
+ }
+#endif // three_way_comparison