Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
ModuleGetterSetter.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
6
7 /*
8 ********************************************************************************
9 ************************ ModuleGetterSetter<T, IMPL> ***************************
10 ********************************************************************************
11 */
12 template <typename T, typename IMPL>
14 {
15 {
16 // most of the time, the value will have already been initialized, so use a readlock
17 typename RWSynchronized<optional<IMPL>>::ReadableReference l = fIndirect_.cget ();
18 if (l->has_value ()) {
19 return l.cref ()->Get (); // IMPL::Get () must be const method
20 }
21 }
22 typename RWSynchronized<optional<IMPL>>::WritableReference l = fIndirect_.rwget ();
23 if (not l->has_value ()) {
24 DoInitOutOfLine_ (&l);
25 }
26 return l.cref ()->Get (); // IMPL::Get () must be const method
27 }
28 template <typename T, typename IMPL>
29 inline void ModuleGetterSetter<T, IMPL>::Set (const T& v)
30 {
31 typename RWSynchronized<optional<IMPL>>::WritableReference l = fIndirect_.rwget ();
32 if (not l->has_value ()) {
33 DoInitOutOfLine_ (&l);
34 }
35 l.rwref ()->Set (v);
36 }
37 template <typename T, typename IMPL>
38 optional<T> ModuleGetterSetter<T, IMPL>::Update (const function<optional<T> (const T&)>& updaterFunction)
39 {
40 /*
41 * Could consider rewriting this to optimisticly use read/shared lock, and upgrade lock if
42 * its found the update caused a change. In fact, using this->Get () and this->Set () would do that,
43 * except for not making update atomic.
44 */
45 typename RWSynchronized<optional<IMPL>>::WritableReference l = fIndirect_.rwget ();
46 if (not l->has_value ()) {
47 DoInitOutOfLine_ (&l);
48 }
49 if (auto o = updaterFunction (l.cref ()->Get ())) {
50 l.rwref ()->Set (*o);
51 return o;
52 }
53 return {};
54 }
55 template <typename T, typename IMPL>
56 dont_inline void ModuleGetterSetter<T, IMPL>::DoInitOutOfLine_ (typename RWSynchronized<optional<IMPL>>::WritableReference* ref)
57 {
58 RequireNotNull (ref);
59 Require (not ref->load ().has_value ());
60 *ref = IMPL{};
61 Ensure (ref->load ().has_value ());
62 }
63
64}
#define RequireNotNull(p)
Definition Assertions.h:347
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 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))