更完
This commit is contained in:
@@ -82,21 +82,52 @@ struct No_Defaults {
|
||||
std::tuple<> attributes;
|
||||
};
|
||||
inline constexpr No_Defaults no_defaults{};
|
||||
template <class Object, class Defaults, class... Properties>
|
||||
|
||||
template <class... Attributes>
|
||||
struct Type_Metadata {
|
||||
using type_metadata_tag = void;
|
||||
using attribute_types = Type_List<Attributes...>;
|
||||
static_assert((Property_Attribute<Attributes> && ...));
|
||||
static_assert(unique_single_value_categories<Attributes...>());
|
||||
std::tuple<Attributes...> attributes;
|
||||
};
|
||||
template <class Type>
|
||||
concept Type_Metadata_Type = requires {
|
||||
typename Type::type_metadata_tag;
|
||||
typename Type::attribute_types;
|
||||
};
|
||||
template <class... Attributes>
|
||||
constexpr auto type_metadata(Attributes&&... attributes) {
|
||||
return Type_Metadata<std::decay_t<Attributes>...>{
|
||||
{std::forward<Attributes>(attributes)...}};
|
||||
}
|
||||
using No_Type_Metadata = Type_Metadata<>;
|
||||
inline constexpr No_Type_Metadata no_type_metadata{};
|
||||
|
||||
template <class Object, class Defaults, class Type_Metadata_Value, class... Properties>
|
||||
class Object_Schema {
|
||||
[[no_unique_address]] Defaults object_defaults_;
|
||||
[[no_unique_address]] Type_Metadata_Value type_metadata_;
|
||||
Synchronization_Plan synchronization_plan_;
|
||||
std::tuple<Properties...> properties_;
|
||||
public:
|
||||
using property_schema_tag = void;
|
||||
using object_type = Object;
|
||||
using defaults_type = Defaults;
|
||||
using type_metadata_type = Type_Metadata_Value;
|
||||
using type_attribute_types = typename Type_Metadata_Value::attribute_types;
|
||||
using property_types = Type_List<Properties...>;
|
||||
static constexpr std::size_t property_count = sizeof...(Properties);
|
||||
static_assert((std::same_as<typename Properties::object_type, Object> && ...));
|
||||
static_assert(unique_property_keys<Properties...>());
|
||||
static_assert(unique_property_storage<Properties...>());
|
||||
Object_Schema(Defaults object_defaults, Synchronization_Plan synchronization_plan, std::tuple<Properties...> properties) : object_defaults_(std::move(object_defaults)), synchronization_plan_(std::move(synchronization_plan)), properties_(std::move(properties)) {}
|
||||
Object_Schema(Defaults object_defaults, Type_Metadata_Value type_metadata_value,
|
||||
Synchronization_Plan synchronization_plan,
|
||||
std::tuple<Properties...> properties)
|
||||
: object_defaults_(std::move(object_defaults)),
|
||||
type_metadata_(std::move(type_metadata_value)),
|
||||
synchronization_plan_(std::move(synchronization_plan)),
|
||||
properties_(std::move(properties)) {}
|
||||
Object_Schema(const Object_Schema&) = default;
|
||||
Object_Schema(Object_Schema&&) noexcept = default;
|
||||
Object_Schema& operator=(const Object_Schema&) = delete;
|
||||
@@ -106,6 +137,40 @@ public:
|
||||
const Defaults& object_defaults() const noexcept {
|
||||
return object_defaults_;
|
||||
}
|
||||
const Type_Metadata_Value& metadata() const noexcept {
|
||||
return type_metadata_;
|
||||
}
|
||||
template <class Category>
|
||||
using type_attribute_type = find_attribute_in_list_t<Category, type_attribute_types>;
|
||||
template <class Category>
|
||||
static constexpr std::size_t type_attribute_count =
|
||||
[]<class... Attributes>(Type_List<Attributes...>) {
|
||||
return count_attribute_category<Category, Attributes...>();
|
||||
}(type_attribute_types{});
|
||||
template <class Category>
|
||||
static constexpr bool has_type_attribute = type_attribute_count<Category> != 0;
|
||||
template <class Category>
|
||||
constexpr decltype(auto) type_attribute() const
|
||||
requires (type_attribute_count<Category> == 1) {
|
||||
using target = type_attribute_type<Category>;
|
||||
return std::get<target>(type_metadata_.attributes);
|
||||
}
|
||||
template <class Function>
|
||||
constexpr void for_each_type_attribute(Function&& function) const {
|
||||
std::apply([&](const auto&... attributes) {
|
||||
(function(attributes), ...);
|
||||
}, type_metadata_.attributes);
|
||||
}
|
||||
template <class Category, class Function>
|
||||
constexpr void for_each_type_attribute(Function&& function) const {
|
||||
std::apply([&](const auto&... attributes) {
|
||||
([&] {
|
||||
using type = std::remove_cvref_t<decltype(attributes)>;
|
||||
if constexpr (std::same_as<attribute_category_of_t<type>, Category>)
|
||||
function(attributes);
|
||||
}(), ...);
|
||||
}, type_metadata_.attributes);
|
||||
}
|
||||
template <auto Selector>
|
||||
constexpr const auto& property() const {
|
||||
if constexpr (std::integral<decltype(Selector)>) {
|
||||
@@ -148,6 +213,8 @@ concept Property_Schema = requires {
|
||||
typename Schema::property_schema_tag;
|
||||
typename Schema::object_type;
|
||||
typename Schema::defaults_type;
|
||||
typename Schema::type_metadata_type;
|
||||
typename Schema::type_attribute_types;
|
||||
typename Schema::property_types;
|
||||
{ Schema::property_count } -> std::convertible_to<std::size_t>;
|
||||
};
|
||||
@@ -527,33 +594,82 @@ bool visit_schema_property(const Schema& schema, std::string_view key_value, Fun
|
||||
}
|
||||
return visit_schema_property_at(schema, *index, std::forward<Function>(function));
|
||||
}
|
||||
template <class Object, class Defaults, class Source, class... Properties>
|
||||
auto make_object_schema(Defaults&& object_defaults, Source&& synchronization_source, Properties&&... properties) requires Synchronization_Source_Type<std::remove_cvref_t<Source>> {
|
||||
using schema_type = Object_Schema<Object, std::decay_t<Defaults>, std::decay_t<Properties>...>;
|
||||
template <class Object, class Defaults, class Metadata, class Source, class... Properties>
|
||||
auto make_object_schema(Defaults&& object_defaults, Metadata&& metadata,
|
||||
Source&& synchronization_source, Properties&&... properties)
|
||||
requires Object_Defaults_Type<std::remove_cvref_t<Defaults>> &&
|
||||
Type_Metadata_Type<std::remove_cvref_t<Metadata>> &&
|
||||
Synchronization_Source_Type<std::remove_cvref_t<Source>> {
|
||||
using schema_type = Object_Schema<Object, std::decay_t<Defaults>,
|
||||
std::decay_t<Metadata>, std::decay_t<Properties>...>;
|
||||
constexpr bool valid_schema = Valid_Property_Schema<schema_type>;
|
||||
static_assert(valid_schema, "property dependency graph must be valid and acyclic");
|
||||
auto plan = materialize_synchronization_plan<schema_type>(std::forward<Source>(synchronization_source));
|
||||
schema_type schema{std::forward<Defaults>(object_defaults), std::move(plan), std::tuple<std::decay_t<Properties>...>{std::forward<Properties>(properties)...}};
|
||||
schema_type schema{std::forward<Defaults>(object_defaults),
|
||||
std::forward<Metadata>(metadata), std::move(plan),
|
||||
std::tuple<std::decay_t<Properties>...>{
|
||||
std::forward<Properties>(properties)...}};
|
||||
if constexpr (valid_schema) {
|
||||
static_cast<void>(resolve_synchronization_plan(schema, schema.synchronization_plan()));
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
template <class Object, class Defaults, class Metadata, class Source, class... Properties>
|
||||
auto object_schema(Defaults&& object_defaults, Metadata&& metadata,
|
||||
Source&& synchronization_source, Properties&&... properties)
|
||||
requires Object_Defaults_Type<std::remove_cvref_t<Defaults>> &&
|
||||
Type_Metadata_Type<std::remove_cvref_t<Metadata>> &&
|
||||
Synchronization_Source_Type<std::remove_cvref_t<Source>> &&
|
||||
(Property_Descriptor_Type<std::remove_cvref_t<Properties>> && ...) {
|
||||
return make_object_schema<Object>(std::forward<Defaults>(object_defaults),
|
||||
std::forward<Metadata>(metadata),
|
||||
std::forward<Source>(synchronization_source),
|
||||
std::forward<Properties>(properties)...);
|
||||
}
|
||||
template <class Object, class Metadata, class Source, class... Properties>
|
||||
auto object_schema(Metadata&& metadata, Source&& synchronization_source,
|
||||
Properties&&... properties)
|
||||
requires Type_Metadata_Type<std::remove_cvref_t<Metadata>> &&
|
||||
Synchronization_Source_Type<std::remove_cvref_t<Source>> &&
|
||||
(Property_Descriptor_Type<std::remove_cvref_t<Properties>> && ...) {
|
||||
return make_object_schema<Object>(no_defaults, std::forward<Metadata>(metadata),
|
||||
std::forward<Source>(synchronization_source),
|
||||
std::forward<Properties>(properties)...);
|
||||
}
|
||||
template <class Object, class Defaults, class Source, class... Properties>
|
||||
auto object_schema(Defaults&& object_defaults, Source&& synchronization_source, Properties&&... properties) requires Object_Defaults_Type<std::remove_cvref_t<Defaults>> && Synchronization_Source_Type<std::remove_cvref_t<Source>> && (Property_Descriptor_Type<std::remove_cvref_t<Properties>> && ...) {
|
||||
return make_object_schema<Object>(std::forward<Defaults>(object_defaults), std::forward<Source>(synchronization_source), std::forward<Properties>(properties)...);
|
||||
return make_object_schema<Object>(std::forward<Defaults>(object_defaults), no_type_metadata, std::forward<Source>(synchronization_source), std::forward<Properties>(properties)...);
|
||||
}
|
||||
template <class Object, class Source, class... Properties>
|
||||
auto object_schema(Source&& synchronization_source, Properties&&... properties) requires Synchronization_Source_Type<std::remove_cvref_t<Source>> && (Property_Descriptor_Type<std::remove_cvref_t<Properties>> && ...) {
|
||||
return make_object_schema<Object>(no_defaults, std::forward<Source>(synchronization_source), std::forward<Properties>(properties)...);
|
||||
return make_object_schema<Object>(no_defaults, no_type_metadata, std::forward<Source>(synchronization_source), std::forward<Properties>(properties)...);
|
||||
}
|
||||
template <class Object, class Defaults, class Metadata, class... Properties>
|
||||
auto object_schema(Defaults&& object_defaults, Metadata&& metadata,
|
||||
Properties&&... properties)
|
||||
requires Object_Defaults_Type<std::remove_cvref_t<Defaults>> &&
|
||||
Type_Metadata_Type<std::remove_cvref_t<Metadata>> &&
|
||||
(Property_Descriptor_Type<std::remove_cvref_t<Properties>> && ...) {
|
||||
return make_object_schema<Object>(std::forward<Defaults>(object_defaults),
|
||||
std::forward<Metadata>(metadata),
|
||||
Synchronization_Plan{},
|
||||
std::forward<Properties>(properties)...);
|
||||
}
|
||||
template <class Object, class Metadata, class... Properties>
|
||||
auto object_schema(Metadata&& metadata, Properties&&... properties)
|
||||
requires Type_Metadata_Type<std::remove_cvref_t<Metadata>> &&
|
||||
(Property_Descriptor_Type<std::remove_cvref_t<Properties>> && ...) {
|
||||
return make_object_schema<Object>(no_defaults, std::forward<Metadata>(metadata),
|
||||
Synchronization_Plan{},
|
||||
std::forward<Properties>(properties)...);
|
||||
}
|
||||
template <class Object, class Defaults, class... Properties>
|
||||
auto object_schema(Defaults&& object_defaults, Properties&&... properties) requires Object_Defaults_Type<std::remove_cvref_t<Defaults>> && (Property_Descriptor_Type<std::remove_cvref_t<Properties>> && ...) {
|
||||
return make_object_schema<Object>(std::forward<Defaults>(object_defaults), Synchronization_Plan{}, std::forward<Properties>(properties)...);
|
||||
return make_object_schema<Object>(std::forward<Defaults>(object_defaults), no_type_metadata, Synchronization_Plan{}, std::forward<Properties>(properties)...);
|
||||
}
|
||||
template <class Object, class... Properties>
|
||||
auto object_schema(Properties&&... properties) requires (Property_Descriptor_Type<std::remove_cvref_t<Properties>> && ...) {
|
||||
return make_object_schema<Object>(no_defaults, Synchronization_Plan{}, std::forward<Properties>(properties)...);
|
||||
return make_object_schema<Object>(no_defaults, no_type_metadata, Synchronization_Plan{}, std::forward<Properties>(properties)...);
|
||||
}
|
||||
template <class Object, class... Arguments>
|
||||
requires requires(Arguments&&... arguments) {
|
||||
|
||||
Reference in New Issue
Block a user