This commit is contained in:
2026-08-12 01:44:13 +08:00
parent 3b4d509d43
commit 4f2ec40922
6 changed files with 180 additions and 54 deletions
+59 -44
View File
@@ -2,6 +2,7 @@
#include "adminive/adapter.hpp"
#include "adminive/concepts.hpp"
#include "adminive/presentation.hpp"
#include <structive/property/accessor.hpp>
#include <cctype>
#include <concepts>
#include <map>
@@ -23,43 +24,33 @@ template <class T>
concept Reflected_Type = requires {
{ Reflection_Adapter<std::remove_cvref_t<T>>::field_count } -> std::convertible_to<std::size_t>;
};
template <auto Member>
struct Member_Pointer_Traits;
template <class Owner, class Member_Type, Member_Type Owner::*Member>
struct Member_Pointer_Traits<Member> {
using owner_type = Owner;
using member_type = Member_Type;
static constexpr auto value = Member;
};
template <auto Member>
struct Member_Field_Accessor {
using owner_type = typename Member_Pointer_Traits<Member>::owner_type;
using member_type = typename Member_Pointer_Traits<Member>::member_type;
static constexpr auto member = Member;
template <class Object>
static decltype(auto) get(Object& object) noexcept {
return object.*Member;
}
template <class Object>
static decltype(auto) get(const Object& object) noexcept {
return object.*Member;
}
};
template <class T, std::size_t Index>
struct Reflected_Field_Accessor {
using owner_type = T;
using object_type = T;
using reference_type = decltype(Reflection_Adapter<T>::template get<Index>(std::declval<T&>()));
using const_reference_type = decltype(Reflection_Adapter<T>::template get<Index>(std::declval<const T&>()));
using member_type = std::remove_cvref_t<reference_type>;
using value_type = std::remove_cvref_t<reference_type>;
struct storage_identity {};
using dependency_spec = structive::No_Property_Dependencies;
static constexpr bool readable = true;
static constexpr bool writable =
!std::is_const_v<std::remove_reference_t<reference_type>>;
static constexpr bool synchronized_view_read = false;
static constexpr bool trusted_object_access = true;
static constexpr std::size_t index = Index;
static_assert(std::is_lvalue_reference_v<reference_type>);
static_assert(std::is_lvalue_reference_v<const_reference_type>);
static decltype(auto) get(T& object) noexcept(noexcept(Reflection_Adapter<T>::template get<Index>(object))) {
decltype(auto) read(T& object) const noexcept(noexcept(Reflection_Adapter<T>::template get<Index>(object))) {
return Reflection_Adapter<T>::template get<Index>(object);
}
static decltype(auto) get(const T& object) noexcept(noexcept(Reflection_Adapter<T>::template get<Index>(object))) {
decltype(auto) read(const T& object) const noexcept(noexcept(Reflection_Adapter<T>::template get<Index>(object))) {
return Reflection_Adapter<T>::template get<Index>(object);
}
template <class Value>
void write(T& object, Value&& value) const
requires std::assignable_from<value_type&, Value> {
Reflection_Adapter<T>::template get<Index>(object) = std::forward<Value>(value);
}
};
inline bool valid_data_name(std::string_view name) noexcept {
if(name.empty()) {
@@ -102,35 +93,39 @@ struct Field_Metadata {
bool include_default{true};
bool required{};
};
template <class Accessor, bool Managed_Writable = false, bool Synchronized = true>
template <structive::Property_Accessor Accessor, bool Managed_Writable = false,
bool Synchronized = true>
class Field_Descriptor {
public:
using field_descriptor_tag = void;
using accessor_type = Accessor;
using owner_type = typename Accessor::owner_type;
using member_type = typename Accessor::member_type;
using owner_type = typename Accessor::object_type;
using member_type = typename Accessor::value_type;
static constexpr bool managed_writable = Managed_Writable;
static constexpr bool synchronized = Synchronized;
explicit Field_Descriptor(std::string name) {
Field_Descriptor(std::string name, Accessor accessor = {})
: accessor_(std::move(accessor)) {
metadata_.name = std::move(name);
metadata_.presentation.label = make_label(metadata_.name);
}
Field_Descriptor(std::string name, std::string label) {
Field_Descriptor(std::string name, std::string label, Accessor accessor = {})
: accessor_(std::move(accessor)) {
metadata_.name = std::move(name);
metadata_.presentation.label = std::move(label);
}
explicit Field_Descriptor(Field_Metadata metadata) : metadata_(std::move(metadata)) {}
auto editable() const {
Field_Descriptor(Field_Metadata metadata, Accessor accessor)
: accessor_(std::move(accessor)), metadata_(std::move(metadata)) {}
auto editable() const requires Accessor::writable {
auto result = rebind<true, Synchronized>();
result.metadata_.editable = true;
return result;
}
auto creatable() const {
auto creatable() const requires Accessor::writable {
auto result = rebind<true, Synchronized>();
result.metadata_.creatable = true;
return result;
}
auto read_write() const {
auto read_write() const requires Accessor::writable {
return rebind<true, Synchronized>();
}
auto unsynchronized() const {
@@ -219,13 +214,24 @@ public:
}
template <class Object>
requires std::convertible_to<std::remove_reference_t<Object>*, owner_type*>
decltype(auto) get(Object& object) const noexcept(noexcept(Accessor::get(object))) {
return Accessor::get(object);
decltype(auto) get(Object& object) const
noexcept(noexcept(accessor_.read(object))) {
return accessor_.read(object);
}
template <class Object>
requires std::convertible_to<const std::remove_reference_t<Object>*, const owner_type*>
decltype(auto) get(const Object& object) const noexcept(noexcept(Accessor::get(object))) {
return Accessor::get(object);
decltype(auto) get(const Object& object) const
noexcept(noexcept(accessor_.read(object))) {
return accessor_.read(object);
}
template <class Object, class Value>
requires std::convertible_to<std::remove_reference_t<Object>*, owner_type*> &&
requires(const Accessor& accessor, Object& object, Value&& value) {
accessor.write(object, std::forward<Value>(value));
}
void set(Object& object, Value&& value) const
noexcept(noexcept(accessor_.write(object, std::forward<Value>(value)))) {
accessor_.write(object, std::forward<Value>(value));
}
const std::string& name() const noexcept {
return metadata_.name;
@@ -269,10 +275,11 @@ public:
private:
template <bool New_Writable, bool New_Synchronized>
auto rebind() const {
return Field_Descriptor<Accessor, New_Writable, New_Synchronized>(metadata_);
return Field_Descriptor<Accessor, New_Writable, New_Synchronized>(metadata_, accessor_);
}
template <class, bool, bool>
template <structive::Property_Accessor, bool, bool>
friend class Field_Descriptor;
[[no_unique_address]] Accessor accessor_;
Field_Metadata metadata_;
};
template <class T>
@@ -286,11 +293,19 @@ concept Field_Descriptor_Type = requires {
};
template <auto Member>
auto field(std::string name) {
return Field_Descriptor<Member_Field_Accessor<Member>>(std::move(name));
return Field_Descriptor<structive::Member_Accessor<Member>>(std::move(name));
}
template <auto Member>
auto field(std::string name, std::string label) {
return Field_Descriptor<Member_Field_Accessor<Member>>(std::move(name), std::move(label));
return Field_Descriptor<structive::Member_Accessor<Member>>(std::move(name), std::move(label));
}
template <structive::Property_Accessor Accessor>
auto field(std::string name, Accessor accessor) {
return Field_Descriptor<Accessor>(std::move(name), std::move(accessor));
}
template <structive::Property_Accessor Accessor>
auto field(std::string name, std::string label, Accessor accessor) {
return Field_Descriptor<Accessor>(std::move(name), std::move(label), std::move(accessor));
}
template <Reflected_Type T, std::size_t Index>
auto reflected_field() {
@@ -384,7 +399,7 @@ struct Identity_Field_Customizer {
};
template <Reflected_Type T, class Customizer, std::size_t... Indexes>
auto reflected_object_with_impl(std::string name, std::string label, Customizer customizer, std::index_sequence<Indexes...>) {
return object<T>(std::move(name), std::move(label), customizer.template operator()<Indexes>(reflected_field<T, Indexes>())...);
return adminive::object<T>(std::move(name), std::move(label), customizer.template operator()<Indexes>(reflected_field<T, Indexes>())...);
}
template <Reflected_Type T, class Customizer>
auto reflected_object_with(std::string name, Customizer customizer) {