On 03/01/20 14:54 +0000, Jonathan Wakely wrote:
On 29/12/19 12:07 +0100, Stephan Bergmann wrote:
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
                                                    );

After writing that, I realised that a better approach might be:

--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -40,7 +40,9 @@

 namespace std
 {
-#define __cpp_lib_three_way_comparison 201711L
+#if __cpp_lib_concepts
+# define __cpp_lib_three_way_comparison 201711L
+#endif

   // [cmp.categories], comparison category types


i.e. don't pretend the library supports three-way comparison if that
support is incomplete. That will still fix the Clang problem because
if that macro isn't defined then we don't define either overload of
std::lexicographical_compare_three_way.

That seems cleaner to me. Anybody disagree?

Reply via email to