|
|
@@ -36,6 +36,7 @@
|
|
|
|
|
|
#define DECLARE_TYPE_ENUM(X) X,
|
|
|
#define SIZEOF_STRUCT(X) sizeof(X),
|
|
|
+#define ALIGNOF_STRUCT(X) alignof(X),
|
|
|
#define SWITCH_DELETE(X) \
|
|
|
case Type::X: \
|
|
|
reinterpret_cast<X const *>(data_.data())->~X(); \
|
|
|
@@ -51,6 +52,10 @@
|
|
|
namespace jvalidate::constraint {
|
|
|
|
|
|
class Constraint {
|
|
|
+public:
|
|
|
+ static constexpr size_t UNION_WIDTH = std::max({CONSTRAINT_IMPLEMENTATION_LIST(SIZEOF_STRUCT)});
|
|
|
+ static constexpr size_t UNION_ALIGN = std::max({CONSTRAINT_IMPLEMENTATION_LIST(ALIGNOF_STRUCT)});
|
|
|
+
|
|
|
public:
|
|
|
CONSTRAINT_IMPLEMENTATION_LIST(IMPLICIT_CONSTRUCTOR)
|
|
|
Constraint(Constraint const &) = delete;
|
|
|
@@ -88,7 +93,7 @@ private:
|
|
|
enum class Type : uint8_t { None, CONSTRAINT_IMPLEMENTATION_LIST(DECLARE_TYPE_ENUM) };
|
|
|
|
|
|
Type type_ = Type::None;
|
|
|
- std::array<std::byte, std::max({CONSTRAINT_IMPLEMENTATION_LIST(SIZEOF_STRUCT)})> data_;
|
|
|
+ alignas(UNION_ALIGN) std::array<std::byte, UNION_WIDTH> data_;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
@@ -1154,12 +1159,12 @@ public:
|
|
|
static auto properties(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Object);
|
|
|
|
|
|
- std::map<std::string, schema::Node const *> rval;
|
|
|
+ constraint::PropertiesConstraint rval;
|
|
|
for (auto [prop, subschema] : context.schema.as_object()) {
|
|
|
- rval.emplace(prop, context.child(subschema, prop).node());
|
|
|
+ rval.properties.emplace(prop, context.child(subschema, prop).node());
|
|
|
}
|
|
|
|
|
|
- return ptr(constraint::PropertiesConstraint{rval});
|
|
|
+ return ptr(std::move(rval));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1310,26 +1315,25 @@ public:
|
|
|
static auto dependencies(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Object);
|
|
|
|
|
|
- std::map<std::string, schema::Node const *> schemas;
|
|
|
- std::map<std::string, std::unordered_set<std::string>> required;
|
|
|
+ constraint::DependenciesConstraint rval;
|
|
|
for (auto [prop, subschema] : context.schema.as_object()) {
|
|
|
if (subschema.type() == adapter::Type::Array) {
|
|
|
// Option 1) dependentRequired
|
|
|
for (auto key : subschema.as_array()) {
|
|
|
EXPECT(key.type() == adapter::Type::String);
|
|
|
- required[prop].insert(key.as_string());
|
|
|
+ rval.required[prop].insert(key.as_string());
|
|
|
}
|
|
|
} else if (context.vocab->version() <= schema::Version::Draft03 &&
|
|
|
subschema.type() == adapter::Type::String) {
|
|
|
// Option 2) Special single-element dependentRequired in Draft03
|
|
|
- required[prop].insert(subschema.as_string());
|
|
|
+ rval.required[prop].insert(subschema.as_string());
|
|
|
} else {
|
|
|
// Option 3) dependentSchemas
|
|
|
- schemas.emplace(prop, context.child(subschema, prop).node());
|
|
|
+ rval.subschemas.emplace(prop, context.child(subschema, prop).node());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return ptr(constraint::DependenciesConstraint{.subschemas = schemas, .required = required});
|
|
|
+ return ptr(std::move(rval));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1355,12 +1359,12 @@ public:
|
|
|
static auto dependentSchemas(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Object);
|
|
|
|
|
|
- std::map<std::string, schema::Node const *> rval;
|
|
|
+ constraint::DependenciesConstraint rval;
|
|
|
for (auto [prop, subschema] : context.schema.as_object()) {
|
|
|
- rval.emplace(prop, context.child(subschema, prop).node());
|
|
|
+ rval.subschemas.emplace(prop, context.child(subschema, prop).node());
|
|
|
}
|
|
|
|
|
|
- return ptr(constraint::DependenciesConstraint{.subschemas = rval});
|
|
|
+ return ptr(std::move(rval));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1385,17 +1389,24 @@ public:
|
|
|
static auto dependentRequired(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Object);
|
|
|
|
|
|
- std::map<std::string, std::unordered_set<std::string>> rval;
|
|
|
+ constraint::DependenciesConstraint rval;
|
|
|
for (auto [prop, subschema] : context.schema.as_object()) {
|
|
|
EXPECT(subschema.type() == adapter::Type::Array);
|
|
|
for (auto key : subschema.as_array()) {
|
|
|
EXPECT(key.type() == adapter::Type::String);
|
|
|
- rval[prop].insert(key.as_string());
|
|
|
+ rval.required[prop].insert(key.as_string());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return ptr(constraint::DependenciesConstraint{.subschemas = {}, .required = rval});
|
|
|
+ return ptr(std::move(rval));
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
+
|
|
|
+#undef DECLARE_TYPE_ENUM
|
|
|
+#undef SIZEOF_STRUCT
|
|
|
+#undef ALIGNOF_STRUCT
|
|
|
+#undef SWITCH_DELETE
|
|
|
+#undef SWITCH_VISIT
|
|
|
+#undef IMPLICIT_CONSTRUCTOR
|
|
|
// NOLINTEND(readability-identifier-naming)
|