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

Reply via email to