From 225c87668c39c43ae4552ae683bdced38e4919f0 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 27 Oct 2024 12:46:10 +0800 Subject: [PATCH 1/2] `requires` for `chrono::parse` and comparison category detection Drive-by: Simply `sub_match` by reusing `_Get_comparison_category_t`. --- stl/inc/__msvc_string_view.hpp | 5 +++-- stl/inc/chrono | 39 +++++++++++++++++----------------- stl/inc/regex | 28 +++++++----------------- 3 files changed, 30 insertions(+), 42 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 676fedf943f..d7d8bdbdcf6 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -1756,13 +1756,14 @@ _NODISCARD constexpr bool operator==(const basic_string_view<_Elem, _Traits> _Lh return _Lhs._Equal(_Rhs); } -template +template struct _Get_comparison_category { using type = weak_ordering; }; template -struct _Get_comparison_category<_Traits, void_t> { + requires requires { typename _Traits::comparison_category; } +struct _Get_comparison_category<_Traits> { using type = _Traits::comparison_category; static_assert(_Is_any_of_v, diff --git a/stl/inc/chrono b/stl/inc/chrono index 598f806836f..3eb013ff2fd 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -4612,57 +4612,56 @@ namespace chrono { minutes* _Offset; }; - template - using _Has_from_stream = - decltype(static_cast(from_stream(_STD declval&>(), - _STD declval(), _STD declval<_Parsable&>(), _STD declval<_Rest>()...)), - 0); // intentional ADL + template + concept _Can_from_stream = requires( + basic_istream<_CharT, _Traits>& __istr, const _CharT* __s, _Parsable& __parsed, _Rest&&... __rest_args) { + from_stream(__istr, +__s, __parsed, _STD forward<_Rest>(__rest_args)...); // intentional ADL + }; - _EXPORT_STD template , _Parsable> = 0> + _EXPORT_STD template > _Parsable> _NODISCARD auto parse(const _CharT* _Fmt, _Parsable& _Tp) { return _Time_parse_iomanip_c_str<_CharT, char_traits<_CharT>, allocator<_CharT>, _Parsable>{_Fmt, _Tp}; } - _EXPORT_STD template = 0> + _EXPORT_STD template _Parsable> _NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp) { return _Time_parse_iomanip{_Fmt, _Tp}; } - _EXPORT_STD template *> = 0> + _EXPORT_STD template *> _Parsable> _NODISCARD auto parse(const _CharT* _Fmt, _Parsable& _Tp, basic_string<_CharT, _Traits, _Alloc>& _Abbrev) { return _Time_parse_iomanip_c_str{_Fmt, _Tp, _STD addressof(_Abbrev)}; } - _EXPORT_STD template *> = 0> + _EXPORT_STD template > _Parsable> _NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp, basic_string<_CharT, _Traits, _Alloc>& _Abbrev) { return _Time_parse_iomanip{_Fmt, _Tp, _STD addressof(_Abbrev)}; } - _EXPORT_STD template , _Parsable, basic_string<_CharT>*, minutes*> = 0> + _EXPORT_STD template , basic_string<_CharT>*, minutes*> _Parsable> _NODISCARD auto parse(const _CharT* _Fmt, _Parsable& _Tp, minutes& _Offset) { return _Time_parse_iomanip_c_str{_Fmt, _Tp, static_cast*>(nullptr), &_Offset}; } - _EXPORT_STD template *, minutes*> = 0> + _EXPORT_STD template *, minutes*> _Parsable> _NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp, minutes& _Offset) { return _Time_parse_iomanip{_Fmt, _Tp, static_cast*>(nullptr), &_Offset}; } - _EXPORT_STD template *, minutes*> = 0> + _EXPORT_STD template *, minutes*> _Parsable> _NODISCARD auto parse( const _CharT* _Fmt, _Parsable& _Tp, basic_string<_CharT, _Traits, _Alloc>& _Abbrev, minutes& _Offset) { return _Time_parse_iomanip_c_str{_Fmt, _Tp, _STD addressof(_Abbrev), &_Offset}; } - _EXPORT_STD template *, minutes*> = 0> + _EXPORT_STD template *, minutes*> _Parsable> _NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp, basic_string<_CharT, _Traits, _Alloc>& _Abbrev, minutes& _Offset) { return _Time_parse_iomanip{_Fmt, _Tp, _STD addressof(_Abbrev), &_Offset}; diff --git a/stl/inc/regex b/stl/inc/regex index 374689ae9d0..8d31ac7854a 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -605,18 +605,6 @@ bool _Is_word(_Elem _Ch) { return _UCh <= static_cast<_UElem>('z') && _Is_word(static_cast(_UCh)); } -#if _HAS_CXX20 -template -struct _Get_member_comparison_category { - using type = weak_ordering; -}; - -template -struct _Get_member_comparison_category<_Ty, void_t> { - using type = _Ty::comparison_category; -}; -#endif // _HAS_CXX20 - _EXPORT_STD template class sub_match : public pair<_BidIt, _BidIt> { // class to hold contents of a capture group public: @@ -630,10 +618,6 @@ public: // Note that _Size_type should always be std::size_t using _Size_type = typename string_type::size_type; -#if _HAS_CXX20 - using _Comparison_category = _Get_member_comparison_category<_Traits>::type; -#endif // _HAS_CXX20 - constexpr sub_match() : _Mybase(), matched(false) {} bool matched; @@ -744,7 +728,8 @@ _NODISCARD bool operator==(const sub_match<_BidIt>& _Left, const sub_match<_BidI #if _HAS_CXX20 _EXPORT_STD template _NODISCARD auto operator<=>(const sub_match<_BidIt>& _Left, const sub_match<_BidIt>& _Right) { - return static_cast::_Comparison_category>(_Left.compare(_Right) <=> 0); + using _Comparison_category = _Get_comparison_category_t>>; + return static_cast<_Comparison_category>(_Left.compare(_Right) <=> 0); } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template @@ -781,7 +766,8 @@ _NODISCARD bool operator==(const sub_match<_BidIt>& _Left, const _Iter_value_t<_ #if _HAS_CXX20 _EXPORT_STD template _NODISCARD auto operator<=>(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>* _Right) { - return static_cast::_Comparison_category>(_Left.compare(_Right) <=> 0); + using _Comparison_category = _Get_comparison_category_t>>; + return static_cast<_Comparison_category>(_Left.compare(_Right) <=> 0); } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template @@ -848,7 +834,8 @@ _NODISCARD bool operator==(const sub_match<_BidIt>& _Left, const _Iter_value_t<_ #if _HAS_CXX20 _EXPORT_STD template _NODISCARD auto operator<=>(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>& _Right) { - return static_cast::_Comparison_category>(_Left._Compare(_STD addressof(_Right), 1) <=> 0); + using _Comparison_category = _Get_comparison_category_t>>; + return static_cast<_Comparison_category>(_Left._Compare(_STD addressof(_Right), 1) <=> 0); } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template @@ -917,7 +904,8 @@ _NODISCARD bool operator==( _EXPORT_STD template _NODISCARD auto operator<=>( const sub_match<_BidIt>& _Left, const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Right) { - return static_cast::_Comparison_category>(_Left._Compare(_Right.data(), _Right.size()) <=> 0); + using _Comparison_category = _Get_comparison_category_t>>; + return static_cast<_Comparison_category>(_Left._Compare(_Right.data(), _Right.size()) <=> 0); } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template From e906ea59d88b25a657c5a7a85dee444fa9e03f02 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Sun, 27 Oct 2024 08:18:35 -0700 Subject: [PATCH 2/2] Restore inadvertently removed `*` --- stl/inc/chrono | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/chrono b/stl/inc/chrono index 3eb013ff2fd..20caee89735 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -4635,7 +4635,7 @@ namespace chrono { } _EXPORT_STD template > _Parsable> + _Can_from_stream<_CharT, _Traits, basic_string<_CharT, _Traits, _Alloc>*> _Parsable> _NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp, basic_string<_CharT, _Traits, _Alloc>& _Abbrev) { return _Time_parse_iomanip{_Fmt, _Tp, _STD addressof(_Abbrev)};