commit b5b6317a7d969dc65d853a2d461bf7c07ff88d28 Author: Jonathan Wakely Date: Wed Nov 6 08:08:19 2019 +0000 libstdc++: Add compare_three_way and install header * include/Makefile.in: Regenerate. * libsupc++/Makefile.in: Regenerate. * libsupc++/compare (__3way_builtin_ptr_cmp): Define helper. (compare_three_way): Add missing implementation. diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare index 379b2d48582..2e518ccbffd 100644 --- a/libstdc++-v3/libsupc++/compare +++ b/libstdc++-v3/libsupc++/compare @@ -519,7 +519,8 @@ namespace std // [cmp.common], common comparison category type template - struct common_comparison_category { + struct common_comparison_category + { // using type = TODO }; @@ -527,7 +528,7 @@ namespace std using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; -#if __cpp_concepts +#if __cpp_lib_concepts namespace __detail { template @@ -604,20 +605,42 @@ namespace std using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::__type; +#if __cpp_lib_concepts + namespace __detail + { + // BUILTIN-PTR-THREE-WAY(T, U) + template + concept __3way_builtin_ptr_cmp + = convertible_to<_Tp, const volatile void*> + && convertible_to<_Up, const volatile void*> + && ! requires(_Tp&& __t, _Up&& __u) + { operator<=>(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u)); } + && ! requires(_Tp&& __t, _Up&& __u) + { static_cast<_Tp&&>(__t).operator<=>(static_cast<_Up&&>(__u)); }; + } // namespace __detail + // [cmp.object], typename compare_three_way struct compare_three_way { - // TODO -#if 0 template requires (three_way_comparable_with<_Tp, _Up> - || BUILTIN-PTR-THREE-WAY(_Tp, _Up)) + || __detail::__3way_builtin_ptr_cmp<_Tp, _Up>) constexpr auto operator()(_Tp&& __t, _Up&& __u) const noexcept { - // TODO + if constexpr (__detail::__3way_builtin_ptr_cmp<_Tp, _Up>) + { + auto __pt = static_cast(__t); + auto __pu = static_cast(__u); + if (__builtin_is_constant_evaluated()) + return __pt <=> __pu; + auto __it = reinterpret_cast<__UINTPTR_TYPE__>(__pt); + auto __iu = reinterpret_cast<__UINTPTR_TYPE__>(__pu); + return __it <=> __iu; + } + else + return static_cast<_Tp&&>(__t) <=> static_cast<_Up&&>(__u); } -#endif using is_transparent = void; }; @@ -635,7 +658,8 @@ namespace std inline constexpr unspecified compare_partial_order_fallback = unspecified; #endif } -} +#endif +} // namespace std #pragma GCC visibility pop