@@ -59,6 +59,9 @@ export namespace stormkit { inline namespace core {
5959 using MutexType = Mutex;
6060
6161 private:
62+ template <LockAccessMode Mode>
63+ using AccessClosureInvokeParameter = meta::If<Mode == LockAccessMode::READ_ONLY, ConstReferenceType, ReferenceType>;
64+
6265 template <template <class > class Lock , LockAccessMode Mode>
6366 class Access ;
6467
@@ -85,12 +88,30 @@ export namespace stormkit { inline namespace core {
8588 template <LockAccessMode Mode, template <class > class Lock , typename ... LockArgs, class Self >
8689 auto access (this Self& self, LockArgs&&... lock_args) noexcept -> Access<Lock, Mode>;
8790
91+ template <LockAccessMode Mode,
92+ std::invocable<AccessClosureInvokeParameter<Mode>> Closure,
93+ template <class > class Lock ,
94+ typename ... LockArgs,
95+ class Self >
96+ auto access (this Self& self, Closure&& closure, LockArgs&&... lock_args) noexcept
97+ -> std::invoke_result_t<Closure, AccessClosureInvokeParameter<Mode>>;
98+
8899 template <template <class > class Lock = details::DefaultReadOnlyLock, typename ... LockArgs>
89100 auto read (LockArgs&&... lock_args) const noexcept -> ReadAccess<Lock>;
90101
102+ template <std::invocable<ConstReferenceType> Closure,
103+ template <class > class Lock = details::DefaultReadOnlyLock,
104+ typename ... LockArgs>
105+ auto read (Closure&& closure, LockArgs&&... lock_args) const noexcept -> std::invoke_result_t<Closure, ConstReferenceType>;
106+
91107 template <template <class > class Lock = details::DefaultReadWriteLock, typename ... LockArgs>
92108 auto write (LockArgs&&... lock_args) noexcept -> WriteAccess<Lock>;
93109
110+ template <std::invocable<ReferenceType> Closure,
111+ template <class > class Lock = details::DefaultReadWriteLock,
112+ typename ... LockArgs>
113+ auto write (Closure&& closure, LockArgs&&... lock_args) noexcept -> std::invoke_result_t<Closure, ReferenceType>;
114+
94115 template <template <class > class Lock = details::DefaultReadOnlyLock, typename ... LockArgs>
95116 auto copy (LockArgs&&... lock_args) const noexcept -> ValueType;
96117
@@ -210,6 +231,24 @@ namespace stormkit { inline namespace core {
210231 return AccessType { std::forward<Self&>(self), std::forward<LockArgs>(lock_args)... };
211232 }
212233
234+ // //////////////////////////////////////
235+ // //////////////////////////////////////
236+ template <meta::IsNotRawIndirection T, class Mutex >
237+ template <LockAccessMode Mode,
238+ std::invocable<typename Locked<T, Mutex>::template AccessClosureInvokeParameter<Mode>> Closure,
239+ template <class > class Lock ,
240+ typename ... LockArgs,
241+ class Self >
242+ STORMKIT_FORCE_INLINE
243+ auto Locked<T, Mutex>::access(this Self& self, Closure&& closure, LockArgs&&... lock_args) noexcept
244+ -> std::invoke_result_t <Closure, AccessClosureInvokeParameter<Mode>> {
245+ static_assert (not (Mode == LockAccessMode::READ_ONLY and not std::is_const_v<meta::RemoveIndirectionsType<Self>>),
246+ " can't get read access on const Locked<T>" );
247+ using AccessType = Access<Lock, Mode>;
248+ auto access_ = AccessType { std::forward<Self&>(self), std::forward<LockArgs>(lock_args)... };
249+ return std::invoke (std::forward<Closure>(closure), *access_);
250+ }
251+
213252 // //////////////////////////////////////
214253 // //////////////////////////////////////
215254 template <meta::IsNotRawIndirection T, class Mutex >
@@ -219,6 +258,19 @@ namespace stormkit { inline namespace core {
219258 return access<LockAccessMode::READ_ONLY, Lock>(std::forward<LockArgs>(lock_args)...);
220259 }
221260
261+ // //////////////////////////////////////
262+ // //////////////////////////////////////
263+ template <meta::IsNotRawIndirection T, class Mutex >
264+ template <std::invocable<typename Locked<T, Mutex>::ConstReferenceType> Closure,
265+ template <class > class Lock ,
266+ typename ... LockArgs>
267+ STORMKIT_FORCE_INLINE
268+ auto Locked<T, Mutex>::read(Closure&& closure, LockArgs&&... lock_args) const noexcept
269+ -> std::invoke_result_t <Closure, ConstReferenceType> {
270+ return access<LockAccessMode::READ_ONLY, Closure, Lock>(std::forward<Closure>(closure),
271+ std::forward<LockArgs>(lock_args)...);
272+ }
273+
222274 // //////////////////////////////////////
223275 // //////////////////////////////////////
224276 template <meta::IsNotRawIndirection T, class Mutex >
@@ -228,6 +280,17 @@ namespace stormkit { inline namespace core {
228280 return access<LockAccessMode::READ_WRITE, Lock>(std::forward<LockArgs>(lock_args)...);
229281 }
230282
283+ // //////////////////////////////////////
284+ // //////////////////////////////////////
285+ template <meta::IsNotRawIndirection T, class Mutex >
286+ template <std::invocable<typename Locked<T, Mutex>::ReferenceType> Closure, template <class > class Lock , typename ... LockArgs>
287+ STORMKIT_FORCE_INLINE
288+ auto Locked<T, Mutex>::write(Closure&& closure, LockArgs&&... lock_args) noexcept
289+ -> std::invoke_result_t <Closure, ReferenceType> {
290+ return access<LockAccessMode::READ_WRITE, Closure, Lock>(std::forward<Closure>(closure),
291+ std::forward<LockArgs>(lock_args)...);
292+ }
293+
231294 // //////////////////////////////////////
232295 // //////////////////////////////////////
233296 template <meta::IsNotRawIndirection T, class Mutex >
0 commit comments