Skip to content

Commit 68ab956

Browse files
committed
✨ Add iterator comparisons to byterator
Problem: - A `byterator` can be equality-compared with a regular iterator, but it cannot be compared for less/greater. Solution: - Add comparison operators between `byterator` and corresponding iterators.
1 parent 768a457 commit 68ab956

File tree

2 files changed

+89
-14
lines changed

2 files changed

+89
-14
lines changed

include/stdx/byterator.hpp

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ template <typename T> class byterator {
3838
byterator const &y) -> bool {
3939
return x.ptr == y.ptr;
4040
}
41-
4241
template <typename It,
4342
std::enable_if_t<std::is_same_v<detail::iterator_value_t<It>, T>,
4443
int> = 0>
@@ -49,47 +48,103 @@ template <typename T> class byterator {
4948
}
5049

5150
#if __cpp_impl_three_way_comparison >= 201907L
52-
[[nodiscard]] constexpr friend auto operator<=>(byterator const &x,
51+
[[nodiscard]] friend constexpr auto operator<=>(byterator const &x,
5352
byterator const &y) {
5453
return x.ptr <=> y.ptr;
5554
}
56-
#else
57-
[[nodiscard]] constexpr friend auto operator!=(byterator const &x,
58-
byterator const &y) -> bool {
59-
return not(x == y);
55+
template <typename It,
56+
std::enable_if_t<std::is_same_v<detail::iterator_value_t<It>, T>,
57+
int> = 0>
58+
[[nodiscard]] friend constexpr auto operator<=>(byterator const &x, It y) {
59+
return static_cast<void const *>(x.ptr) <=>
60+
static_cast<void const *>(stdx::to_address(y));
6061
}
61-
62+
#else
6263
template <typename It>
63-
[[nodiscard]] friend constexpr auto operator==(It y, byterator const &x)
64+
[[nodiscard]] friend constexpr auto operator==(It x, byterator const &y)
6465
-> bool {
65-
return x == y;
66+
return y == x;
67+
}
68+
69+
[[nodiscard]] friend constexpr auto operator!=(byterator const &x,
70+
byterator const &y) -> bool {
71+
return not(x == y);
6672
}
6773
template <typename It>
6874
[[nodiscard]] friend constexpr auto operator!=(byterator const &x, It y)
6975
-> bool {
7076
return not(x == y);
7177
}
7278
template <typename It>
73-
[[nodiscard]] friend constexpr auto operator!=(It y, byterator const &x)
79+
[[nodiscard]] friend constexpr auto operator!=(It x, byterator const &y)
7480
-> bool {
75-
return not(x == y);
81+
return y != x;
7682
}
7783

7884
[[nodiscard]] friend constexpr auto operator<(byterator const &x,
7985
byterator const &y) -> bool {
8086
return std::less{}(x.ptr, y.ptr);
8187
}
88+
template <typename It,
89+
std::enable_if_t<std::is_same_v<detail::iterator_value_t<It>, T>,
90+
int> = 0>
91+
[[nodiscard]] friend constexpr auto operator<(byterator const &x, It y)
92+
-> bool {
93+
return std::less{}(static_cast<void const *>(x.ptr),
94+
static_cast<void const *>(stdx::to_address(y)));
95+
}
96+
template <typename It,
97+
std::enable_if_t<std::is_same_v<detail::iterator_value_t<It>, T>,
98+
int> = 0>
99+
[[nodiscard]] friend constexpr auto operator<(It x, byterator const &y)
100+
-> bool {
101+
return std::less{}(static_cast<void const *>(stdx::to_address(x)),
102+
static_cast<void const *>(y.ptr));
103+
}
104+
82105
[[nodiscard]] friend constexpr auto operator<=(byterator const &x,
83106
byterator const &y) -> bool {
84-
return std::less_equal{}(x.ptr, y.ptr);
107+
return not(y < x);
108+
}
109+
template <typename It>
110+
[[nodiscard]] friend constexpr auto operator<=(byterator const &x, It y)
111+
-> bool {
112+
return not(y < x);
85113
}
114+
template <typename It>
115+
[[nodiscard]] friend constexpr auto operator<=(It x, byterator const &y)
116+
-> bool {
117+
return not(y < x);
118+
}
119+
86120
[[nodiscard]] friend constexpr auto operator>(byterator const &x,
87121
byterator const &y) -> bool {
88-
return std::greater{}(x.ptr, y.ptr);
122+
return y < x;
89123
}
124+
template <typename It>
125+
[[nodiscard]] friend constexpr auto operator>(byterator const &x, It y)
126+
-> bool {
127+
return y < x;
128+
}
129+
template <typename It>
130+
[[nodiscard]] friend constexpr auto operator>(It x, byterator const &y)
131+
-> bool {
132+
return y < x;
133+
}
134+
90135
[[nodiscard]] friend constexpr auto operator>=(byterator const &x,
91136
byterator const &y) -> bool {
92-
return std::greater_equal{}(x.ptr, y.ptr);
137+
return not(x < y);
138+
}
139+
template <typename It>
140+
[[nodiscard]] friend constexpr auto operator>=(byterator const &x, It y)
141+
-> bool {
142+
return not(x < y);
143+
}
144+
template <typename It>
145+
[[nodiscard]] friend constexpr auto operator>=(It x, byterator const &y)
146+
-> bool {
147+
return not(x < y);
93148
}
94149
#endif
95150

test/byterator.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,26 @@ TEST_CASE("equality comparable to iterator", "[byterator]") {
2121
CHECK((std::end(a) != b));
2222
}
2323

24+
TEST_CASE("comparable to iterator", "[byterator]") {
25+
auto const a = std::array{1, 2, 3, 4};
26+
auto const b = stdx::byterator{std::begin(a)};
27+
auto const c = std::next(b);
28+
29+
CHECK((b < std::end(a)));
30+
CHECK((std::begin(a) < c));
31+
CHECK((b <= std::end(a)));
32+
CHECK((std::begin(a) <= c));
33+
CHECK((b <= std::begin(a)));
34+
CHECK((std::begin(a) <= b));
35+
36+
CHECK((std::end(a) > b));
37+
CHECK((c > std::begin(a)));
38+
CHECK((std::end(a) >= b));
39+
CHECK((c >= std::begin(a)));
40+
CHECK((b >= std::begin(a)));
41+
CHECK((std::begin(a) >= b));
42+
}
43+
2444
TEST_CASE("copy constructible", "[byterator]") {
2545
auto const a = std::array{stdx::to_be<std::uint16_t>(0x0102),
2646
stdx::to_be<std::uint16_t>(0x0304)};

0 commit comments

Comments
 (0)