On 29/12/19 12:07 +0100, Stephan Bergmann wrote:
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
Should be fixed at r279861 on trunk (also attached). This leaves the
five-argument overload defined for Clang, just not the four-argument
one that uses std::compare_three_way.
We could define that overload unconditionally and do something like
this, but I prefer to just omit it rather than define it badly:
return std::lexicographical_compare_three_way(__first1, __last1,
__first2, __last2,
#if __cpp_lib_concepts
compare_three_way{}
#else
[](auto&& __l, auto&& __r)
{ return __l <=> __r; }
#endif // concepts
);
commit 9b51d80f860841ea80be6c420970ec8b881c0f9e
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Fri Jan 3 14:44:39 2020 +0000
libstdc++: Only use std::compare_three_way when concepts are supported
Clang now supports three-way comparisons. That causes both overloads of
std::lexicographical_compare_three_way to be defined, but the second one
uses std::compare_three_way which depends on concepts. Clang does not
yet support concepts, so the second overload should also depend on
__cpp_lib_concepts.
* include/bits/stl_algobase.h (lexicographical_compare_three_way):
Only define four-argument overload when __cpp_lib_concepts is defined.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@279861 138bc75d-0d04-0410-961f-82ee72b054a4
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 13de6aecc6c..76c323ab21b 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -1751,6 +1751,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
: __first2 != __last2 ? strong_ordering::less : strong_ordering::equal;
}
+#if __cpp_lib_concepts
template<typename _InputIter1, typename _InputIter2>
constexpr auto
lexicographical_compare_three_way(_InputIter1 __first1,
@@ -1762,6 +1763,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__first2, __last2,
compare_three_way{});
}
+#endif // concepts
#endif // three_way_comparison
template<typename _InputIterator1, typename _InputIterator2,