Skip to content

Commit 74806ac

Browse files
committed
Remove <=> operators since AppleClang doesn't support it
1 parent a83bb79 commit 74806ac

File tree

5 files changed

+188
-251
lines changed

5 files changed

+188
-251
lines changed

include/graphqlservice/GraphQLResponse.h

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
#include "graphqlservice/internal/Awaitable.h"
2222

23-
#include <compare>
2423
#include <cstdint>
2524
#include <initializer_list>
2625
#include <memory>
@@ -91,13 +90,12 @@ struct IdType
9190
ValueType release();
9291

9392
// Comparison
94-
GRAPHQLRESPONSE_EXPORT std::strong_ordering operator<=>(const IdType& rhs) const noexcept;
9593
GRAPHQLRESPONSE_EXPORT bool operator==(const IdType& rhs) const noexcept;
96-
GRAPHQLRESPONSE_EXPORT std::strong_ordering operator<=>(const ByteData& rhs) const noexcept;
9794
GRAPHQLRESPONSE_EXPORT bool operator==(const ByteData& rhs) const noexcept;
98-
GRAPHQLRESPONSE_EXPORT std::strong_ordering operator<=>(const OpaqueString& rhs) const noexcept;
9995
GRAPHQLRESPONSE_EXPORT bool operator==(const OpaqueString& rhs) const noexcept;
10096

97+
GRAPHQLRESPONSE_EXPORT bool operator<(const IdType& rhs) const noexcept;
98+
10199
// Check the Type
102100
GRAPHQLRESPONSE_EXPORT bool isBase64() const noexcept;
103101

@@ -190,7 +188,6 @@ struct Value
190188
Value& operator=(const Value& rhs) = delete;
191189

192190
// Comparison
193-
GRAPHQLRESPONSE_EXPORT std::partial_ordering operator<=>(const Value& rhs) const noexcept;
194191
GRAPHQLRESPONSE_EXPORT bool operator==(const Value& rhs) const noexcept;
195192

196193
// Check the Type
@@ -243,24 +240,16 @@ struct Value
243240
// Type::Map
244241
struct MapData
245242
{
246-
std::partial_ordering operator<=>(const MapData& rhs) const;
243+
bool operator==(const MapData& rhs) const;
247244

248245
MapType map;
249246
std::vector<size_t> members;
250247
};
251248

252-
// Type::List
253-
struct ListData
254-
{
255-
std::partial_ordering operator<=>(const ListData& rhs) const;
256-
257-
std::vector<Value> entries;
258-
};
259-
260249
// Type::String
261250
struct StringData
262251
{
263-
std::strong_ordering operator<=>(const StringData& rhs) const;
252+
bool operator==(const StringData& rhs) const;
264253

265254
StringType string;
266255
bool from_json = false;
@@ -270,7 +259,7 @@ struct Value
270259
// Type::Null
271260
struct NullData
272261
{
273-
std::strong_ordering operator<=>(const NullData& rhs) const;
262+
bool operator==(const NullData& rhs) const;
274263
};
275264

276265
// Type::EnumValue
@@ -279,14 +268,14 @@ struct Value
279268
// Type::Scalar
280269
struct ScalarData
281270
{
282-
std::partial_ordering operator<=>(const ScalarData& rhs) const;
271+
bool operator==(const ScalarData& rhs) const;
283272

284273
std::unique_ptr<ScalarType> scalar;
285274
};
286275

287276
using SharedData = std::shared_ptr<const Value>;
288277

289-
using TypeData = std::variant<MapData, ListData, StringData, NullData, BooleanType, IntType,
278+
using TypeData = std::variant<MapData, ListType, StringData, NullData, BooleanType, IntType,
290279
FloatType, EnumData, IdType, ScalarData, SharedData>;
291280

292281
const TypeData& data() const noexcept;

include/graphqlservice/internal/Base64.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
// clang-format on
2020

2121
#include <cstdint>
22+
#include <optional>
2223
#include <string>
2324
#include <string_view>
2425
#include <vector>
@@ -56,11 +57,20 @@ class Base64
5657
// Convert a set of bytes to Base64.
5758
GRAPHQLRESPONSE_EXPORT static std::string toBase64(const std::vector<std::uint8_t>& bytes);
5859

59-
// Compare a set of bytes to possible Base64.
60-
GRAPHQLRESPONSE_EXPORT static bool compareBase64(
60+
enum class Comparison
61+
{
62+
LessThan = -1,
63+
EqualTo = 0,
64+
GreaterThan = 1,
65+
66+
InvalidBase64 = 2,
67+
};
68+
69+
// Compare a set of bytes to a possible Base64 string without performing any heap allocations.
70+
GRAPHQLRESPONSE_EXPORT static Comparison compareBase64(
6171
const std::vector<std::uint8_t>& bytes, std::string_view maybeEncoded) noexcept;
6272

63-
// Validate a whether or not a string is valid Base64.
73+
// Validate a whether or not a string is valid Base64 without performing any heap allocations.
6474
GRAPHQLRESPONSE_EXPORT static bool validateBase64(std::string_view maybeEncoded) noexcept;
6575

6676
private:

src/Base64.cpp

Lines changed: 80 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,22 @@ std::string Base64::toBase64(const std::vector<std::uint8_t>& bytes)
149149
return result;
150150
}
151151

152-
bool Base64::compareBase64(
152+
Base64::Comparison Base64::compareBase64(
153153
const std::vector<std::uint8_t>& bytes, std::string_view maybeEncoded) noexcept
154154
{
155-
if (bytes.empty() || maybeEncoded.empty())
155+
if (bytes.empty())
156156
{
157-
return bytes.empty() && maybeEncoded.empty();
157+
if (maybeEncoded.empty())
158+
{
159+
return Comparison::EqualTo;
160+
}
161+
}
162+
else if (maybeEncoded.empty())
163+
{
164+
return Comparison::GreaterThan;
158165
}
159166

167+
auto result = Comparison::EqualTo;
160168
auto itr = bytes.cbegin();
161169
const auto itrEnd = bytes.cend();
162170

@@ -171,18 +179,34 @@ bool Base64::compareBase64(
171179
if (((a | b | c | d) & 0xC0) != 0)
172180
{
173181
// Invalid Base64 characters
174-
return false;
182+
return Comparison::InvalidBase64;
175183
}
176184

177-
const uint32_t segment = (static_cast<uint32_t>(a) << 18) | (static_cast<uint32_t>(b) << 12)
178-
| (static_cast<uint32_t>(c) << 6) | static_cast<uint32_t>(d);
179-
180-
if (itr == itrEnd || *itr++ != static_cast<std::uint8_t>((segment & 0xFF0000) >> 16)
181-
|| itr == itrEnd || *itr++ != static_cast<std::uint8_t>((segment & 0xFF00) >> 8)
182-
|| itr == itrEnd || *itr++ != static_cast<std::uint8_t>(segment & 0xFF))
185+
if (Comparison::EqualTo == result)
183186
{
184-
// Decoded bytes did not match
185-
return false;
187+
const uint32_t segment = (static_cast<uint32_t>(a) << 18)
188+
| (static_cast<uint32_t>(b) << 12) | (static_cast<uint32_t>(c) << 6)
189+
| static_cast<uint32_t>(d);
190+
const std::array decoded { static_cast<std::uint8_t>((segment & 0xFF0000) >> 16),
191+
static_cast<std::uint8_t>((segment & 0xFF00) >> 8),
192+
static_cast<std::uint8_t>(segment & 0xFF) };
193+
194+
for (auto value : decoded)
195+
{
196+
if (itr == itrEnd)
197+
{
198+
result = Comparison::LessThan;
199+
break;
200+
}
201+
202+
if (*itr != value)
203+
{
204+
result = *itr < value ? Comparison::LessThan : Comparison::GreaterThan;
205+
break;
206+
}
207+
208+
++itr;
209+
}
186210
}
187211

188212
maybeEncoded = maybeEncoded.substr(4);
@@ -199,55 +223,81 @@ bool Base64::compareBase64(
199223
if (((a | b | c) & 0xC0) != 0 || (c & 0x3) != 0)
200224
{
201225
// Invalid Base64 characters or padding
202-
return false;
226+
return Comparison::InvalidBase64;
203227
}
204228

205229
const uint16_t segment = (static_cast<uint16_t>(a) << 10) | (static_cast<uint16_t>(b) << 4)
206230
| (static_cast<uint16_t>(c) >> 2);
231+
const std::array decoded { static_cast<std::uint8_t>((segment & 0xFF00) >> 8),
232+
static_cast<std::uint8_t>(segment & 0xFF) };
207233

208234
if (triplet)
209235
{
210-
if (itr == itrEnd || *itr++ != static_cast<std::uint8_t>((segment & 0xFF00) >> 8)
211-
|| itr == itrEnd || *itr++ != static_cast<std::uint8_t>(segment & 0xFF))
236+
if (Comparison::EqualTo == result)
212237
{
213-
// Decoded bytes did not match
214-
return false;
238+
for (auto value : decoded)
239+
{
240+
if (itr == itrEnd)
241+
{
242+
result = Comparison::LessThan;
243+
break;
244+
}
245+
246+
if (*itr != value)
247+
{
248+
result = *itr < value ? Comparison::LessThan : Comparison::GreaterThan;
249+
break;
250+
}
251+
252+
++itr;
253+
}
215254
}
216255

217256
maybeEncoded = maybeEncoded.substr(3);
218257
}
219258
else
220259
{
221-
if ((segment & 0xFF) != 0)
260+
if (decoded[1] != 0)
222261
{
223262
// Invalid padding
224-
return false;
263+
return Comparison::InvalidBase64;
225264
}
226265

227-
if (itr == itrEnd || *itr++ != static_cast<std::uint8_t>((segment & 0xFF00) >> 8))
266+
if (Comparison::EqualTo == result)
228267
{
229-
// Decoded byte did not match
230-
return false;
268+
if (itr == itrEnd)
269+
{
270+
result = Comparison::LessThan;
271+
}
272+
else if (*itr != decoded[0])
273+
{
274+
result = *itr < decoded[0] ? Comparison::LessThan : Comparison::GreaterThan;
275+
}
276+
277+
++itr;
231278
}
232279

233280
maybeEncoded = maybeEncoded.substr(2);
234281
}
235282
}
236283

237-
// We should reach the end of the byte vector
238-
if (itr != itrEnd)
239-
{
240-
return false;
241-
}
242-
243284
// Make sure anything that's left is 0 - 2 characters of padding
244285
if ((maybeEncoded.size() > 0 && padding != maybeEncoded[0])
245286
|| (maybeEncoded.size() > 1 && padding != maybeEncoded[1]) || maybeEncoded.size() > 2)
246287
{
247-
return false;
288+
return Comparison::InvalidBase64;
248289
}
249290

250-
return true;
291+
if (Comparison::EqualTo == result)
292+
{
293+
// We should reach the end of the byte vector
294+
if (itr != itrEnd)
295+
{
296+
result = Comparison::GreaterThan;
297+
}
298+
}
299+
300+
return result;
251301
}
252302

253303
bool Base64::validateBase64(std::string_view maybeEncoded) noexcept

0 commit comments

Comments
 (0)