Stroika Library 3.0d23
 
Loading...
Searching...
No Matches
ModuleGetterSetter.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4
6
8
9 /*
10 ********************************************************************************
11 ************************ ModuleGetterSetter<T, IMPL> ***************************
12 ********************************************************************************
13 */
14 template <typename T, IModuleGetterSetterImpl<T> IMPL>
16 {
17 typename RWSynchronized<optional<IMPL>>::WritableReference l = fIndirect_.rwget ();
18 if (not l->has_value ()) {
19 DoInitOutOfLine_ (&l);
20 }
21 }
22 template <typename T, IModuleGetterSetterImpl<T> IMPL>
24 {
25 {
26 // most of the time, the value will have already been initialized, so use a readlock
27 typename RWSynchronized<optional<IMPL>>::ReadableReference l = fIndirect_.cget ();
28 if (l->has_value ()) {
29 return l.cref ()->Get (); // IMPL::Get () must be const method
30 }
31 }
32 AssureLoaded ();
33 return fIndirect_.load ()->Get ();
34 }
35 template <typename T, IModuleGetterSetterImpl<T> IMPL>
36 inline void ModuleGetterSetter<T, IMPL>::Set (const T& v)
37 {
38 typename RWSynchronized<optional<IMPL>>::WritableReference l = fIndirect_.rwget ();
39 if (not l->has_value ()) {
40 DoInitOutOfLine_ (&l);
41 }
42 l.rwref ()->Set (v);
43 }
44 template <typename T, IModuleGetterSetterImpl<T> IMPL>
45 inline shared_ptr<const T> ModuleGetterSetter<T, IMPL>::operator->() const
46 {
47 return Memory::MakeSharedPtr<const T> (Get ());
48 }
49 template <typename T, IModuleGetterSetterImpl<T> IMPL>
50 optional<T> ModuleGetterSetter<T, IMPL>::Update (const function<optional<T> (const T&)>& updaterFunction)
51 {
52 /*
53 * Could consider rewriting this to optimisticly use read/shared lock, and upgrade lock if
54 * its found the update caused a change. In fact, using this->Get () and this->Set () would do that,
55 * except for not making update atomic.
56 */
57 typename RWSynchronized<optional<IMPL>>::WritableReference l = fIndirect_.rwget ();
58 if (not l->has_value ()) {
59 DoInitOutOfLine_ (&l);
60 }
61 if (auto o = updaterFunction (l.cref ()->Get ())) {
62 l.rwref ()->Set (*o);
63 return o;
64 }
65 return {};
66 }
67 template <typename T, IModuleGetterSetterImpl<T> IMPL>
68 dont_inline void ModuleGetterSetter<T, IMPL>::DoInitOutOfLine_ (typename RWSynchronized<optional<IMPL>>::WritableReference* ref)
69 {
70 RequireNotNull (ref);
71 Require (not ref->cref ().has_value ());
72 *ref = IMPL{}; // @todo redo with emplace()
73 Ensure (ref->cref ().has_value ());
74 }
75
76}
#define RequireNotNull(p)
Definition Assertions.h:348
Wrap any object with Synchronized<> and it can be used similarly to the base type,...
nonvirtual WritableReference rwget()
get a read-write smart pointer to the underlying Synchronized<> object, holding the full lock the who...
nonvirtual ReadableReference cget() const
get a read-only smart pointer to the underlying Synchronized<> object, holding the readlock the whole...
Helper to define synchronized, lazy constructed, module initialization (intended to work with DataExc...
nonvirtual shared_ptr< const T > operator->() const
nonvirtual optional< T > Update(const function< optional< T >(const T &)> &updaterFunction)
Call this with a lambda that will update the associated value (INSIDE a lock (synchronized))