This commit is contained in:
2026-08-12 01:44:13 +08:00
parent 8d4714f691
commit a672f37fae
5 changed files with 58 additions and 0 deletions
@@ -140,6 +140,46 @@ struct Trusted_Getter_Setter_Accessor {
std::invoke(Setter, object, std::forward<Value>(value));
}
};
template <class Object, class Reader, class Writer>
requires std::invocable<const Reader&, const Object&> &&
(!std::is_void_v<std::invoke_result_t<const Reader&, const Object&>>) &&
(!std::is_rvalue_reference_v<std::invoke_result_t<const Reader&, const Object&>>) &&
std::invocable<const Writer&, Object&,
std::remove_cvref_t<std::invoke_result_t<const Reader&, const Object&>>> &&
std::same_as<std::invoke_result_t<
const Writer&, Object&,
std::remove_cvref_t<std::invoke_result_t<const Reader&, const Object&>>>,
void>
struct Trusted_Callable_Accessor {
using object_type = Object;
using value_type =
std::remove_cvref_t<std::invoke_result_t<const Reader&, const Object&>>;
using storage_identity = void;
static constexpr bool readable = true;
static constexpr bool writable = true;
static constexpr bool synchronized_view_read = false;
static constexpr bool trusted_object_access = true;
using dependency_spec = No_Property_Dependencies;
[[no_unique_address]] Reader reader;
[[no_unique_address]] Writer writer;
constexpr decltype(auto) read(const object_type& object) const
noexcept(std::is_nothrow_invocable_v<const Reader&, const object_type&>) {
return std::invoke(reader, object);
}
template <class Value>
constexpr void write(object_type& object, Value&& value) const
requires std::invocable<const Writer&, object_type&, Value> &&
std::same_as<std::invoke_result_t<const Writer&, object_type&, Value>, void> {
std::invoke(writer, object, std::forward<Value>(value));
}
};
template <class Object, class Reader, class Writer>
auto trusted_callable_accessor(Reader reader, Writer writer) {
return Trusted_Callable_Accessor<Object, Reader, Writer>{
std::move(reader), std::move(writer)};
}
template <class Accessor>
concept Property_Accessor = requires {
typename Accessor::object_type;
@@ -556,6 +556,9 @@ auto object_schema(Properties&&... properties) requires (Property_Descriptor_Typ
return make_object_schema<Object>(no_defaults, Synchronization_Plan{}, std::forward<Properties>(properties)...);
}
template <class Object, class... Arguments>
requires requires(Arguments&&... arguments) {
object_schema<Object>(std::forward<Arguments>(arguments)...);
}
auto object(Arguments&&... arguments) {
return object_schema<Object>(std::forward<Arguments>(arguments)...);
}
+11
View File
@@ -131,6 +131,9 @@ struct Pure_Read_Only_Device : Property_Object<Pure_Read_Only_Device> {
int id{21};
int version{4};
};
struct Callable_Device {
int value{4};
};
template <>
struct structive::Type_Descriptor<Pure_Read_Only_Device> {
static auto get() {
@@ -184,6 +187,14 @@ static void runtime_read_int(void* context, std::size_t, std::string_view, const
*static_cast<int*>(context) = *static_cast<const int*>(value);
}
int main() {
auto callable_accessor = trusted_callable_accessor<Callable_Device>(
[](const Callable_Device& value) { return value.value; },
[](Callable_Device& target, int value) { target.value = value; });
static_assert(Property_Accessor<decltype(callable_accessor)>);
Callable_Device callable_device;
REQUIRE(callable_accessor.read(callable_device) == 4);
callable_accessor.write(callable_device, 9);
REQUIRE(callable_device.value == 9);
static_assert(Property_Described_Object<Device>);
static_assert(!Can_Write_Immutable<Device>);
static_assert(!Can_Write_Immutable_By_Key<Device>);