@@ -34,11 +34,12 @@ _STD_BEGIN
3434// STRUCT TEMPLATE _Char_traits (FROM <string>)
3535template <class _Elem, class _Int_type>
3636struct _Char_traits { // properties of a string or stream element
37- using char_type = _Elem;
38- using int_type = _Int_type;
39- using pos_type = streampos;
40- using off_type = streamoff;
41- using state_type = _Mbstatet;
37+ using char_type = _Elem;
38+ using int_type = _Int_type;
39+ using pos_type = streampos;
40+ using off_type = streamoff;
41+ using state_type = _Mbstatet;
42+ using comparison_category = strong_ordering;
4243
4344 // For copy/move, we can uniformly call memcpy/memmove (or their builtin versions) for all element types.
4445
@@ -212,11 +213,12 @@ private:
212213 using _Primary_char_traits = _Char_traits<_Elem, unsigned short>;
213214
214215public:
215- using char_type = _Elem;
216- using int_type = unsigned short;
217- using pos_type = streampos;
218- using off_type = streamoff;
219- using state_type = mbstate_t;
216+ using char_type = _Elem;
217+ using int_type = unsigned short;
218+ using pos_type = streampos;
219+ using off_type = streamoff;
220+ using state_type = mbstate_t;
221+ using comparison_category = strong_ordering;
220222
221223 using _Primary_char_traits::_Copy_s;
222224 using _Primary_char_traits::copy;
@@ -350,11 +352,12 @@ private:
350352 using _Primary_char_traits = _Char_traits<_Elem, _Int_type>;
351353
352354public:
353- using char_type = _Elem;
354- using int_type = _Int_type;
355- using pos_type = streampos;
356- using off_type = streamoff;
357- using state_type = mbstate_t;
355+ using char_type = _Elem;
356+ using int_type = _Int_type;
357+ using pos_type = streampos;
358+ using off_type = streamoff;
359+ using state_type = mbstate_t;
360+ using comparison_category = strong_ordering;
358361
359362 using _Primary_char_traits::_Copy_s;
360363 using _Primary_char_traits::copy;
@@ -4511,16 +4514,19 @@ _NODISCARD bool operator==(
45114514 return _Left._Equal(_Right);
45124515}
45134516
4517+ #if !_HAS_CXX20
45144518template <class _Elem, class _Traits, class _Alloc>
45154519_NODISCARD bool operator==(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) {
45164520 return _Right._Equal(_Left);
45174521}
4522+ #endif // !_HAS_CXX20
45184523
45194524template <class _Elem, class _Traits, class _Alloc>
45204525_NODISCARD bool operator==(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) {
45214526 return _Left._Equal(_Right);
45224527}
45234528
4529+ #if !_HAS_CXX20
45244530template <class _Elem, class _Traits, class _Alloc>
45254531_NODISCARD bool operator!=(
45264532 const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept {
@@ -4600,6 +4606,19 @@ template <class _Elem, class _Traits, class _Alloc>
46004606_NODISCARD bool operator>=(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) {
46014607 return !(_Left < _Right);
46024608}
4609+ #endif // !_HAS_CXX20
4610+
4611+ #if _HAS_CXX20
4612+ template <class _Elem, class _Traits, class _Alloc>
4613+ _NODISCARD int operator<=>(
4614+ const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept {
4615+ return _Left.compare(_Right);
4616+ }
4617+ template <class _Elem, class _Traits, class _Alloc>
4618+ _NODISCARD int operator<=>(const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem* _Right) {
4619+ return _Left.compare(_Right);
4620+ }
4621+ #endif // _HAS_CXX20
46034622
46044623using string = basic_string<char, char_traits<char>, allocator<char>>;
46054624using wstring = basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>;
0 commit comments