Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions stl/inc/xstring
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
#include <xpolymorphic_allocator.h>
#endif // _HAS_CXX17

#if _HAS_CXX20
#include <compare>
#endif // _HAS_CXX20

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
Expand All @@ -39,6 +43,9 @@ struct _Char_traits { // properties of a string or stream element
using pos_type = streampos;
using off_type = streamoff;
using state_type = _Mbstatet;
#if _HAS_CXX20
using comparison_category = strong_ordering;
#endif // _HAS_CXX20

// For copy/move, we can uniformly call memcpy/memmove (or their builtin versions) for all element types.

Expand Down Expand Up @@ -217,6 +224,9 @@ public:
using pos_type = streampos;
using off_type = streamoff;
using state_type = mbstate_t;
#if _HAS_CXX20
using comparison_category = strong_ordering;
#endif // _HAS_CXX20

using _Primary_char_traits::_Copy_s;
using _Primary_char_traits::copy;
Expand Down Expand Up @@ -355,6 +365,9 @@ public:
using pos_type = streampos;
using off_type = streamoff;
using state_type = mbstate_t;
#if _HAS_CXX20
using comparison_category = strong_ordering;
#endif // _HAS_CXX20

using _Primary_char_traits::_Copy_s;
using _Primary_char_traits::copy;
Expand Down Expand Up @@ -4511,16 +4524,19 @@ _NODISCARD bool operator==(
return _Left._Equal(_Right);
}

#if !_HAS_CXX20
template <class _Elem, class _Traits, class _Alloc>
_NODISCARD bool operator==(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) {
return _Right._Equal(_Left);
}
#endif // !_HAS_CXX20

template <class _Elem, class _Traits, class _Alloc>
_NODISCARD bool operator==(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) {
return _Left._Equal(_Right);
}

#if !_HAS_CXX20
template <class _Elem, class _Traits, class _Alloc>
_NODISCARD bool operator!=(
const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept {
Expand Down Expand Up @@ -4600,6 +4616,31 @@ template <class _Elem, class _Traits, class _Alloc>
_NODISCARD bool operator>=(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) {
return !(_Left < _Right);
}
#endif // !_HAS_CXX20

#if _HAS_CXX20
template <class _Elem, class _Traits, class _Alloc>
_NODISCARD strong_ordering operator<=>(
const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept {
int _comparison = _Left.compare(_Right);
if (_comparison == 0) {
return strong_ordering::equivalent;
} else if (_comparison < 0) {
return strong_ordering::less;
}
return strong_ordering::greater;
}
template <class _Elem, class _Traits, class _Alloc>
_NODISCARD strong_ordering operator<=>(const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem* _Right) {
int _comparison = _Left.compare(_Right);
if (_comparison == 0) {
return strong_ordering::equivalent;
} else if (_comparison < 0) {
return strong_ordering::less;
}
return strong_ordering::greater;
}
#endif // _HAS_CXX20

using string = basic_string<char, char_traits<char>, allocator<char>>;
using wstring = basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>;
Expand Down
30 changes: 30 additions & 0 deletions tests/std/tests/P1614R2_spaceship/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,36 @@ void ordering_test_cases() {
static_assert(std::is_same_v<SpaceshipType<WeaklyOrderdByOmissionMatch>, std::weak_ordering>);
static_assert(std::is_same_v<SpaceshipType<PartiallyOrderedMatch>, std::partial_ordering>);
}
{ // Strings library
std::string a1 = "abcdef";
std::string a2 = "abcdef";
std::string a3 = "abcdefg";
std::string a4 = "abcde";
std::string a5 = "abddef";
std::string a6 = "abbdef";

assert((a1 <=> a2) == std::strong_ordering::equivalent);
assert((a1 <=> a3) == std::strong_ordering::less);
assert((a1 <=> a4) == std::strong_ordering::greater);
assert((a1 <=> a5) == std::strong_ordering::less);
assert((a1 <=> a6) == std::strong_ordering::greater);

assert(a1 == a2);
assert(a1 >= a2);
assert(a1 <= a2);
assert(a1 < a3);
assert(a1 <= a3);
assert(a1 != a3);
assert(a1 > a4);
assert(a1 >= a4);
assert(a1 != a4);
assert(a1 < a5);
assert(a1 <= a5);
assert(a1 != a5);
assert(a1 > a6);
assert(a1 >= a6);
assert(a1 != a6);
}
{ // Diagnostics Library
diagnostics_test<std::error_code>();
diagnostics_test<std::error_condition>();
Expand Down