diff --git a/core/include/structive/property/property_object.hpp b/core/include/structive/property/property_object.hpp index 2f33e0a..63d98f0 100644 --- a/core/include/structive/property/property_object.hpp +++ b/core/include/structive/property/property_object.hpp @@ -632,6 +632,13 @@ private: }); } template + decltype(auto) with_all_readable_locked_impl(Function&& function) const { + using Schema = type_descriptor_schema_t; + auto targets = collect_all_static_lock_targets(); + Static_Read_Guard guard{*this, std::move(targets)}; + return std::invoke(std::forward(function), guard); + } + template void with_all_writable_locked_impl(Function&& function) { using Schema = type_descriptor_schema_t; auto targets = collect_all_static_lock_targets(); @@ -777,6 +784,20 @@ public: constexpr auto index = schema_member_property_index_v; return read_one(); } + template + decltype(auto) with_read_index(Function&& function) const { + using Schema = type_descriptor_schema_t; + static_assert(Index < Schema::property_count); + static_assert(Schema::template property_type::readable); + const auto lock_slot = slot(Index); + Single_Read_View view{*this, lock_slot}; + if constexpr(!uses_real_mutexes) + return std::invoke(std::forward(function), read_unlocked(view)); + if (lock_slot == Resolved_Synchronization_View::unsynchronized_slot) + return std::invoke(std::forward(function), read_unlocked(view)); + std::shared_lock lock{mutex(lock_slot)}; + return std::invoke(std::forward(function), read_unlocked(view)); + } template auto read() const requires Schema_Readable_Property_Key, Key> { using Schema = type_descriptor_schema_t; @@ -864,6 +885,10 @@ public: for_each_readable_locked_impl(std::forward(function)); } template + decltype(auto) with_all_readable_locked(Function&& function) const { + return with_all_readable_locked_impl(std::forward(function)); + } + template void with_all_writable_locked(Function&& function) { with_all_writable_locked_impl(std::forward(function)); }