`requires` for `chrono::parse` and comparison category detection (#5044)

Co-authored-by: Casey Carter <cartec69@gmail.com>
This commit is contained in:
A. Jiang 2024-10-30 22:50:12 +08:00 коммит произвёл GitHub
Родитель 51d34c4b78
Коммит 30c9391b91
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 30 добавлений и 42 удалений

Просмотреть файл

@ -1756,13 +1756,14 @@ _NODISCARD constexpr bool operator==(const basic_string_view<_Elem, _Traits> _Lh
return _Lhs._Equal(_Rhs);
}
template <class _Traits, class = void>
template <class _Traits>
struct _Get_comparison_category {
using type = weak_ordering;
};
template <class _Traits>
struct _Get_comparison_category<_Traits, void_t<typename _Traits::comparison_category>> {
requires requires { typename _Traits::comparison_category; }
struct _Get_comparison_category<_Traits> {
using type = _Traits::comparison_category;
static_assert(_Is_any_of_v<type, partial_ordering, weak_ordering, strong_ordering>,

Просмотреть файл

@ -4612,57 +4612,56 @@ namespace chrono {
minutes* _Offset;
};
template <class _CharT, class _Traits, class _Parsable, class... _Rest>
using _Has_from_stream =
decltype(static_cast<void>(from_stream(_STD declval<basic_istream<_CharT, _Traits>&>(),
_STD declval<const _CharT*>(), _STD declval<_Parsable&>(), _STD declval<_Rest>()...)),
0); // intentional ADL
template <class _Parsable, class _CharT, class _Traits, class... _Rest>
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 <class _CharT, class _Parsable, _Has_from_stream<_CharT, char_traits<_CharT>, _Parsable> = 0>
_EXPORT_STD template <class _CharT, _Can_from_stream<_CharT, char_traits<_CharT>> _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 <class _CharT, class _Traits, class _Alloc, class _Parsable,
_Has_from_stream<_CharT, _Traits, _Parsable> = 0>
_EXPORT_STD template <class _CharT, class _Traits, class _Alloc, _Can_from_stream<_CharT, _Traits> _Parsable>
_NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp) {
return _Time_parse_iomanip{_Fmt, _Tp};
}
_EXPORT_STD template <class _CharT, class _Traits, class _Alloc, class _Parsable,
_Has_from_stream<_CharT, _Traits, _Parsable, basic_string<_CharT, _Traits, _Alloc>*> = 0>
_EXPORT_STD template <class _CharT, class _Traits, class _Alloc,
_Can_from_stream<_CharT, _Traits, basic_string<_CharT, _Traits, _Alloc>*> _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 <class _CharT, class _Traits, class _Alloc, class _Parsable,
_Has_from_stream<_CharT, _Traits, _Parsable, basic_string<_CharT, _Traits, _Alloc>*> = 0>
_EXPORT_STD template <class _CharT, class _Traits, class _Alloc,
_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)};
}
_EXPORT_STD template <class _CharT, class _Parsable,
_Has_from_stream<_CharT, char_traits<_CharT>, _Parsable, basic_string<_CharT>*, minutes*> = 0>
_EXPORT_STD template <class _CharT,
_Can_from_stream<_CharT, char_traits<_CharT>, 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<basic_string<_CharT>*>(nullptr), &_Offset};
}
_EXPORT_STD template <class _CharT, class _Traits, class _Alloc, class _Parsable,
_Has_from_stream<_CharT, _Traits, _Parsable, basic_string<_CharT, _Traits, _Alloc>*, minutes*> = 0>
_EXPORT_STD template <class _CharT, class _Traits, class _Alloc,
_Can_from_stream<_CharT, _Traits, basic_string<_CharT, _Traits, _Alloc>*, minutes*> _Parsable>
_NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp, minutes& _Offset) {
return _Time_parse_iomanip{_Fmt, _Tp, static_cast<basic_string<_CharT, _Traits, _Alloc>*>(nullptr), &_Offset};
}
_EXPORT_STD template <class _CharT, class _Traits, class _Alloc, class _Parsable,
_Has_from_stream<_CharT, _Traits, _Parsable, basic_string<_CharT, _Traits, _Alloc>*, minutes*> = 0>
_EXPORT_STD template <class _CharT, class _Traits, class _Alloc,
_Can_from_stream<_CharT, _Traits, basic_string<_CharT, _Traits, _Alloc>*, 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 <class _CharT, class _Traits, class _Alloc, class _Parsable,
_Has_from_stream<_CharT, _Traits, _Parsable, basic_string<_CharT, _Traits, _Alloc>*, minutes*> = 0>
_EXPORT_STD template <class _CharT, class _Traits, class _Alloc,
_Can_from_stream<_CharT, _Traits, basic_string<_CharT, _Traits, _Alloc>*, 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};

Просмотреть файл

@ -605,18 +605,6 @@ bool _Is_word(_Elem _Ch) {
return _UCh <= static_cast<_UElem>('z') && _Is_word(static_cast<unsigned char>(_UCh));
}
#if _HAS_CXX20
template <class _Ty, class = void>
struct _Get_member_comparison_category {
using type = weak_ordering;
};
template <class _Ty>
struct _Get_member_comparison_category<_Ty, void_t<typename _Ty::comparison_category>> {
using type = _Ty::comparison_category;
};
#endif // _HAS_CXX20
_EXPORT_STD template <class _BidIt>
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 <class _BidIt>
_NODISCARD auto operator<=>(const sub_match<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return static_cast<sub_match<_BidIt>::_Comparison_category>(_Left.compare(_Right) <=> 0);
using _Comparison_category = _Get_comparison_category_t<char_traits<_Iter_value_t<_BidIt>>>;
return static_cast<_Comparison_category>(_Left.compare(_Right) <=> 0);
}
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _BidIt>
@ -781,7 +766,8 @@ _NODISCARD bool operator==(const sub_match<_BidIt>& _Left, const _Iter_value_t<_
#if _HAS_CXX20
_EXPORT_STD template <class _BidIt>
_NODISCARD auto operator<=>(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>* _Right) {
return static_cast<sub_match<_BidIt>::_Comparison_category>(_Left.compare(_Right) <=> 0);
using _Comparison_category = _Get_comparison_category_t<char_traits<_Iter_value_t<_BidIt>>>;
return static_cast<_Comparison_category>(_Left.compare(_Right) <=> 0);
}
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _BidIt>
@ -848,7 +834,8 @@ _NODISCARD bool operator==(const sub_match<_BidIt>& _Left, const _Iter_value_t<_
#if _HAS_CXX20
_EXPORT_STD template <class _BidIt>
_NODISCARD auto operator<=>(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>& _Right) {
return static_cast<sub_match<_BidIt>::_Comparison_category>(_Left._Compare(_STD addressof(_Right), 1) <=> 0);
using _Comparison_category = _Get_comparison_category_t<char_traits<_Iter_value_t<_BidIt>>>;
return static_cast<_Comparison_category>(_Left._Compare(_STD addressof(_Right), 1) <=> 0);
}
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _BidIt>
@ -917,7 +904,8 @@ _NODISCARD bool operator==(
_EXPORT_STD template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD auto operator<=>(
const sub_match<_BidIt>& _Left, const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Right) {
return static_cast<sub_match<_BidIt>::_Comparison_category>(_Left._Compare(_Right.data(), _Right.size()) <=> 0);
using _Comparison_category = _Get_comparison_category_t<char_traits<_Iter_value_t<_BidIt>>>;
return static_cast<_Comparison_category>(_Left._Compare(_Right.data(), _Right.size()) <=> 0);
}
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _BidIt, class _Traits, class _Alloc>