This commit is contained in:
2026-08-12 06:16:00 +08:00
parent a672f37fae
commit 42392bbb7e
10 changed files with 246 additions and 10 deletions
+126 -10
View File
@@ -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) {