Skip to content

Commit 7b7ea28

Browse files
committed
enable C++20 three_way_operator when supported
1 parent c7d2bb2 commit 7b7ea28

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

include/frozen/bits/defines.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,23 @@
2929

3030
// Code taken from https://stackoverflow.com/questions/43639122/which-values-can-msvc-lang-have
3131
#if defined(FROZEN_LETITGO_IS_MSVC)
32-
#if _MSVC_LANG > 201402
32+
#if _MSVC_LANG > 201703L
33+
#define FROZEN_LETITGO_HAS_CXX20 1
34+
#else
35+
#define FROZEN_LETITGO_HAS_CXX20 0
36+
#endif
37+
#if _MSVC_LANG > 201402L
3338
#define FROZEN_LETITGO_HAS_CXX17 1
3439
#else /* _MSVC_LANG > 201402 */
3540
#define FROZEN_LETITGO_HAS_CXX17 0
3641
#endif /* _MSVC_LANG > 201402 */
3742
#else /* _MSVC_LANG etc. */
38-
#if __cplusplus > 201402
43+
#if __cplusplus > 201703L
44+
#define FROZEN_LETITGO_HAS_CXX20 1
45+
#else /* __cplusplus > 201402 */
46+
#define FROZEN_LETITGO_HAS_CXX20 0
47+
#endif /* __cplusplus > 201402 */
48+
#if __cplusplus > 201402L
3949
#define FROZEN_LETITGO_HAS_CXX17 1
4050
#else /* __cplusplus > 201402 */
4151
#define FROZEN_LETITGO_HAS_CXX17 0
@@ -51,6 +61,12 @@
5161
#endif
5262
#endif
5363

64+
#if FROZEN_LETITGO_HAS_CXX20 && __has_include(<compare>)
65+
#if defined(_cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907
66+
#define FROZEN_LETITGO_HAS_THREE_WAY_COMPARISON
67+
#endif
68+
#endif
69+
5470
#ifdef __cpp_char8_t
5571
#define FROZEN_LETITGO_HAS_CHAR8T
5672
#endif

include/frozen/string.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
#ifdef FROZEN_LETITGO_HAS_STRING_VIEW
3636
#include <string_view>
3737
#endif
38+
39+
#ifdef FROZEN_LETITGO_HAS_THREE_WAY_COMPARISON
40+
#include <compare>
41+
#endif
3842
#endif
3943

4044
namespace frozen {
@@ -57,7 +61,7 @@ class basic_string {
5761
constexpr basic_string(std::basic_string_view<chr_t> data)
5862
: data_(data.data()), size_(data.size()) {}
5963

60-
explicit constexpr operator std::basic_string_view<chr_t>() const {
64+
constexpr explicit operator std::basic_string_view<chr_t>() const {
6165
return std::basic_string_view<chr_t>(data_, size_);
6266
}
6367
#endif
@@ -70,7 +74,32 @@ class basic_string {
7074

7175
constexpr chr_t operator[](std::size_t i) const { return data_[i]; }
7276

73-
constexpr bool operator==(basic_string other) const {
77+
#ifdef FROZEN_LETITGO_HAS_THREE_WAY_COMPARISON
78+
constexpr std::weak_ordering operator<=>(const basic_string &other) const {
79+
bool equal = true;
80+
if(size_ == other.size_)
81+
for (std::size_t i = 0; i < size_; ++i)
82+
if (data_[i] != other.data_[i]) {
83+
equal = false;
84+
break;
85+
}
86+
87+
if(equal) return std::weak_ordering::equivalent;
88+
89+
unsigned i = 0;
90+
while (i < size() && i < other.size()) {
91+
if ((*this)[i] < other[i]) {
92+
return std::weak_ordering::less;
93+
}
94+
if ((*this)[i] > other[i]) {
95+
return std::weak_ordering::greater;
96+
}
97+
++i;
98+
}
99+
return size() < other.size() ? std::weak_ordering::less : std::weak_ordering::greater;
100+
}
101+
#else
102+
constexpr bool operator==(const basic_string &other) const {
74103
if (size_ != other.size_)
75104
return false;
76105
for (std::size_t i = 0; i < size_; ++i)
@@ -79,6 +108,10 @@ class basic_string {
79108
return true;
80109
}
81110

111+
friend constexpr bool operator!=(const basic_string &lhs, const basic_string &rhs) {
112+
return !(lhs == rhs);
113+
}
114+
82115
constexpr bool operator<(const basic_string &other) const {
83116
unsigned i = 0;
84117
while (i < size() && i < other.size()) {
@@ -102,6 +135,7 @@ class basic_string {
102135
friend constexpr bool operator<=(const basic_string& lhs, const basic_string& rhs) {
103136
return !(lhs > rhs);
104137
}
138+
#endif
105139

106140
constexpr const chr_t *data() const { return data_; }
107141
constexpr const chr_t *begin() const { return data(); }

0 commit comments

Comments
 (0)