Skip to content

Commit 07a3e71

Browse files
authored
Upgrade to C++23 (#676)
Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent fa159a6 commit 07a3e71

23 files changed

Lines changed: 414 additions & 379 deletions

File tree

src/compiler/compile.cc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33

44
#include <sourcemeta/core/jsonschema.h>
55

6-
#include <algorithm> // std::move, std::sort, std::unique
7-
#include <cassert> // assert
6+
#include <algorithm> // std::move, std::sort, std::unique
7+
#include <cassert> // assert
8+
// TODO(C++23): Consider std::flat_map/std::flat_set when available in libc++
89
#include <map> // std::map
910
#include <set> // std::set
1011
#include <string_view> // std::string_view
@@ -161,14 +162,14 @@ auto compile(const sourcemeta::core::JSON &schema,
161162
const auto effective_tweaks{tweaks.value_or(Tweaks{})};
162163

163164
const auto maybe_entrypoint_location{frame.traverse(entrypoint)};
164-
if (!maybe_entrypoint_location.has_value()) {
165+
if (!maybe_entrypoint_location.has_value()) [[unlikely]] {
165166
throw CompilerInvalidEntryPoint{
166167
entrypoint, "The given entry point URI does not exist in the schema"};
167168
}
168169

169170
const auto &entrypoint_location{maybe_entrypoint_location->get()};
170171
if (entrypoint_location.type ==
171-
sourcemeta::core::SchemaFrame::LocationType::Pointer) {
172+
sourcemeta::core::SchemaFrame::LocationType::Pointer) [[unlikely]] {
172173
throw CompilerInvalidEntryPoint{
173174
entrypoint, "The given entry point URI is not a valid subschema"};
174175
}
@@ -367,7 +368,8 @@ auto compile(const sourcemeta::core::JSON &schema,
367368

368369
if (entry.type != sourcemeta::core::SchemaFrame::LocationType::Subschema &&
369370
entry.type != sourcemeta::core::SchemaFrame::LocationType::Resource &&
370-
entry.type != sourcemeta::core::SchemaFrame::LocationType::Anchor) {
371+
entry.type != sourcemeta::core::SchemaFrame::LocationType::Anchor)
372+
[[unlikely]] {
371373
assert(reference_pointer != nullptr);
372374
const auto parent_size{entry.parent ? entry.parent->size() : 0};
373375
throw CompilerReferenceTargetNotSchemaError(
@@ -462,7 +464,8 @@ auto compile(const Context &context, const SchemaContext &schema_context,
462464

463465
// Otherwise the recursion attempt is non-sense
464466
if (!context.frame.locations().contains(
465-
{sourcemeta::core::SchemaReferenceType::Static, destination})) {
467+
{sourcemeta::core::SchemaReferenceType::Static, destination}))
468+
[[unlikely]] {
466469
throw sourcemeta::core::SchemaReferenceError(
467470
destination, to_pointer(schema_context.relative_pointer),
468471
"The target of the reference does not exist in the schema");

src/compiler/default_compiler_draft4.h

Lines changed: 66 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
#include <sourcemeta/core/regex.h>
88

9-
#include <algorithm> // std::sort, std::any_of, std::all_of, std::find_if, std::none_of
10-
#include <cassert> // assert
11-
#include <set> // std::set
12-
#include <utility> // std::move
9+
#include <algorithm> // std::sort, std::ranges::any_of, std::ranges::all_of, std::find_if, std::ranges::none_of
10+
#include <cassert> // assert
11+
#include <set> // std::set
12+
#include <utility> // std::move, std::to_underlying
1313

1414
#include "compile_helpers.h"
1515

@@ -18,7 +18,7 @@ static auto parse_regex(const std::string &pattern,
1818
const sourcemeta::core::WeakPointer &schema_location)
1919
-> sourcemeta::core::Regex {
2020
const auto result{sourcemeta::core::to_regex(pattern)};
21-
if (!result.has_value()) {
21+
if (!result.has_value()) [[unlikely]] {
2222
throw sourcemeta::blaze::CompilerInvalidRegexError(
2323
base, to_pointer(schema_location), pattern);
2424
}
@@ -154,6 +154,7 @@ static auto to_string_hashes(
154154
// marks the starting and end positions for a string where the size
155155
// is equal to the index.
156156
result.second.resize(hashes.back().first.size() + 1, std::make_pair(0, 0));
157+
// TODO(C++23): Use std::views::enumerate when available in libc++
157158
for (std::size_t index = 0; index < hashes.size(); index++) {
158159
result.first.push_back(hashes[index].second);
159160
const auto string_size{hashes[index].first.size()};
@@ -187,7 +188,7 @@ auto compiler_draft4_core_ref(const Context &context,
187188
const auto &entry{static_frame_entry(context, schema_context)};
188189
const auto type{sourcemeta::core::SchemaReferenceType::Static};
189190
const auto reference{context.frame.reference(type, entry.pointer)};
190-
if (!reference.has_value()) {
191+
if (!reference.has_value()) [[unlikely]] {
191192
throw sourcemeta::core::SchemaReferenceError(
192193
schema_context.schema.at(dynamic_context.keyword).to_string(),
193194
to_pointer(schema_context.relative_pointer),
@@ -214,9 +215,9 @@ auto compiler_draft4_validation_type(const Context &context,
214215
if (context.mode == Mode::FastValidation &&
215216
schema_context.schema.defines("enum") &&
216217
schema_context.schema.at("enum").is_array() &&
217-
std::all_of(schema_context.schema.at("enum").as_array().cbegin(),
218-
schema_context.schema.at("enum").as_array().cend(),
219-
[](const auto &value) { return value.is_null(); })) {
218+
std::ranges::all_of(
219+
schema_context.schema.at("enum").as_array(),
220+
[](const auto &value) { return value.is_null(); })) {
220221
return {};
221222
}
222223

@@ -227,9 +228,9 @@ auto compiler_draft4_validation_type(const Context &context,
227228
if (context.mode == Mode::FastValidation &&
228229
schema_context.schema.defines("enum") &&
229230
schema_context.schema.at("enum").is_array() &&
230-
std::all_of(schema_context.schema.at("enum").as_array().cbegin(),
231-
schema_context.schema.at("enum").as_array().cend(),
232-
[](const auto &value) { return value.is_boolean(); })) {
231+
std::ranges::all_of(
232+
schema_context.schema.at("enum").as_array(),
233+
[](const auto &value) { return value.is_boolean(); })) {
233234
return {};
234235
}
235236

@@ -259,9 +260,9 @@ auto compiler_draft4_validation_type(const Context &context,
259260
if (context.mode == Mode::FastValidation &&
260261
schema_context.schema.defines("enum") &&
261262
schema_context.schema.at("enum").is_array() &&
262-
std::all_of(schema_context.schema.at("enum").as_array().cbegin(),
263-
schema_context.schema.at("enum").as_array().cend(),
264-
[](const auto &value) { return value.is_object(); })) {
263+
std::ranges::all_of(
264+
schema_context.schema.at("enum").as_array(),
265+
[](const auto &value) { return value.is_object(); })) {
265266
return {};
266267
}
267268

@@ -296,9 +297,9 @@ auto compiler_draft4_validation_type(const Context &context,
296297
if (context.mode == Mode::FastValidation &&
297298
schema_context.schema.defines("enum") &&
298299
schema_context.schema.at("enum").is_array() &&
299-
std::all_of(schema_context.schema.at("enum").as_array().cbegin(),
300-
schema_context.schema.at("enum").as_array().cend(),
301-
[](const auto &value) { return value.is_array(); })) {
300+
std::ranges::all_of(
301+
schema_context.schema.at("enum").as_array(),
302+
[](const auto &value) { return value.is_array(); })) {
302303
return {};
303304
}
304305

@@ -309,27 +310,25 @@ auto compiler_draft4_validation_type(const Context &context,
309310
if (context.mode == Mode::FastValidation &&
310311
schema_context.schema.defines("enum") &&
311312
schema_context.schema.at("enum").is_array() &&
312-
std::all_of(schema_context.schema.at("enum").as_array().cbegin(),
313-
schema_context.schema.at("enum").as_array().cend(),
314-
[](const auto &value) { return value.is_number(); })) {
313+
std::ranges::all_of(
314+
schema_context.schema.at("enum").as_array(),
315+
[](const auto &value) { return value.is_number(); })) {
315316
return {};
316317
}
317318

318319
ValueTypes types{};
319-
types.set(static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Real));
320-
types.set(
321-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Integer));
322-
types.set(
323-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Decimal));
320+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));
321+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));
322+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));
324323
return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,
325324
context, schema_context, dynamic_context, types)};
326325
} else if (type == "integer") {
327326
if (context.mode == Mode::FastValidation &&
328327
schema_context.schema.defines("enum") &&
329328
schema_context.schema.at("enum").is_array() &&
330-
std::all_of(schema_context.schema.at("enum").as_array().cbegin(),
331-
schema_context.schema.at("enum").as_array().cend(),
332-
[](const auto &value) { return value.is_integer(); })) {
329+
std::ranges::all_of(
330+
schema_context.schema.at("enum").as_array(),
331+
[](const auto &value) { return value.is_integer(); })) {
333332
return {};
334333
}
335334

@@ -359,9 +358,9 @@ auto compiler_draft4_validation_type(const Context &context,
359358
if (context.mode == Mode::FastValidation &&
360359
schema_context.schema.defines("enum") &&
361360
schema_context.schema.at("enum").is_array() &&
362-
std::all_of(schema_context.schema.at("enum").as_array().cbegin(),
363-
schema_context.schema.at("enum").as_array().cend(),
364-
[](const auto &value) { return value.is_string(); })) {
361+
std::ranges::all_of(
362+
schema_context.schema.at("enum").as_array(),
363+
[](const auto &value) { return value.is_string(); })) {
365364
return {};
366365
}
367366

@@ -396,11 +395,9 @@ auto compiler_draft4_validation_type(const Context &context,
396395
sourcemeta::core::JSON::Type::Array)};
397396
} else if (type == "number") {
398397
ValueTypes types{};
399-
types.set(static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Real));
400-
types.set(
401-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Integer));
402-
types.set(
403-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Decimal));
398+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));
399+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));
400+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));
404401
return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,
405402
context, schema_context, dynamic_context, types)};
406403
} else if (type == "integer") {
@@ -421,30 +418,21 @@ auto compiler_draft4_validation_type(const Context &context,
421418
assert(type.is_string());
422419
const auto &type_string{type.to_string()};
423420
if (type_string == "null") {
424-
types.set(
425-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Null));
421+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Null));
426422
} else if (type_string == "boolean") {
427-
types.set(
428-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Boolean));
423+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Boolean));
429424
} else if (type_string == "object") {
430-
types.set(
431-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Object));
425+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Object));
432426
} else if (type_string == "array") {
433-
types.set(
434-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Array));
427+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Array));
435428
} else if (type_string == "number") {
436-
types.set(
437-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Integer));
438-
types.set(
439-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Real));
440-
types.set(
441-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Decimal));
429+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));
430+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));
431+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));
442432
} else if (type_string == "integer") {
443-
types.set(
444-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::Integer));
433+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));
445434
} else if (type_string == "string") {
446-
types.set(
447-
static_cast<std::uint8_t>(sourcemeta::core::JSON::Type::String));
435+
types.set(std::to_underlying(sourcemeta::core::JSON::Type::String));
448436
}
449437
}
450438

@@ -776,23 +764,23 @@ auto properties_as_loop(const Context &context,
776764
const auto inside_disjunctor{
777765
is_inside_disjunctor(schema_context.relative_pointer) ||
778766
// Check if any reference from `anyOf` or `oneOf` points to us
779-
std::any_of(context.frame.references().cbegin(),
780-
context.frame.references().cend(),
781-
[&context, &current_entry](const auto &reference) {
782-
if (!context.frame.locations().contains(
783-
{sourcemeta::core::SchemaReferenceType::Static,
784-
reference.second.destination})) {
785-
return false;
786-
}
787-
788-
const auto &target{
789-
context.frame.locations()
790-
.at({sourcemeta::core::SchemaReferenceType::Static,
791-
reference.second.destination})
792-
.pointer};
793-
return is_inside_disjunctor(reference.first.second) &&
794-
current_entry.pointer.initial() == target;
795-
})};
767+
std::ranges::any_of(
768+
context.frame.references(),
769+
[&context, &current_entry](const auto &reference) {
770+
if (!context.frame.locations().contains(
771+
{sourcemeta::core::SchemaReferenceType::Static,
772+
reference.second.destination})) {
773+
return false;
774+
}
775+
776+
const auto &target{
777+
context.frame.locations()
778+
.at({sourcemeta::core::SchemaReferenceType::Static,
779+
reference.second.destination})
780+
.pointer};
781+
return is_inside_disjunctor(reference.first.second) &&
782+
current_entry.pointer.initial() == target;
783+
})};
796784

797785
if (!inside_disjunctor &&
798786
schema_context.schema.defines("additionalProperties") &&
@@ -812,13 +800,12 @@ auto properties_as_loop(const Context &context,
812800
// Always unroll inside `oneOf` or `anyOf`, to have a
813801
// better chance at quickly short-circuiting
814802
(!inside_disjunctor ||
815-
std::none_of(properties.as_object().cbegin(),
816-
properties.as_object().cend(), [&](const auto &pair) {
817-
return pair.second.is_object() &&
818-
((imports_validation_vocabulary &&
819-
pair.second.defines("enum")) ||
820-
(imports_const && pair.second.defines("const")));
821-
}));
803+
std::ranges::none_of(properties.as_object(), [&](const auto &pair) {
804+
return pair.second.is_object() &&
805+
((imports_validation_vocabulary &&
806+
pair.second.defines("enum")) ||
807+
(imports_const && pair.second.defines("const")));
808+
}));
822809
}
823810

824811
auto compiler_draft4_applicator_properties_with_options(

0 commit comments

Comments
 (0)