Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
LazyInitialized.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
6
8
9 /*
10 ********************************************************************************
11 ****************************** LazyInitialized<T> ******************************
12 ********************************************************************************
13 */
14 template <typename T>
15 template <invocable F>
16 constexpr LazyInitialized<T>::LazyInitialized (F&& oneTimeGetter)
17 requires (convertible_to<invoke_result_t<F>, T>)
18 : fOneTimeGetter_{forward<F> (oneTimeGetter)}
19 {
20 }
21 template <typename T>
22 constexpr LazyInitialized<T>::LazyInitialized (const T& v)
23 {
24 // prevent call_once from invoking again
25 call_once (fOnceFlag_, [&] () {
26 // fOneTimeGetter_ never constructed
27 construct_at (&fValue_, v);
28 });
29 }
30 template <typename T>
31 constexpr LazyInitialized<T>::~LazyInitialized ()
32 {
33 bool wasOneTimeGetterCalled = true;
34 call_once (fOnceFlag_, [&] () { wasOneTimeGetterCalled = false; });
35 if (wasOneTimeGetterCalled) {
36 destroy_at (&fValue_);
37 }
38 else {
39 destroy_at (&fOneTimeGetter_);
40 }
41 }
42 template <typename T>
43 inline LazyInitialized<T>& LazyInitialized<T>::operator= (const T& rhs)
44 {
45 bool wasOneTimeGetterCalled = true;
46 call_once (fOnceFlag_, [&] () { wasOneTimeGetterCalled = false; });
47 if (wasOneTimeGetterCalled) {
48 fValue_ = rhs;
49 }
50 else {
51 destroy_at (&fOneTimeGetter_); // then never called, if set before read
52 construct_at (&fValue_, rhs);
53 }
54 return *this;
55 }
56 template <typename T>
57 constexpr LazyInitialized<T>::operator const T () const
58 {
59 return Getter_ ();
60 }
61 template <typename T>
62 inline const T LazyInitialized<T>::operator() () const
63 {
64 return Getter_ ();
65 }
66 template <typename T>
68 {
69 return &(Getter_ ());
70 }
71 template <typename T>
72 inline const T* LazyInitialized<T>::operator->() const
73 {
74 return &(Getter_ ());
75 }
76 template <typename T>
77 inline T& LazyInitialized<T>::Getter_ ()
78 {
79 // same implementation...
80 return const_cast<T&> (const_cast<const LazyInitialized<T>*> (this)->Getter_ ());
81 }
82 template <typename T>
83 inline const T& LazyInitialized<T>::Getter_ () const
84 {
85 call_once (fOnceFlag_, [&] () {
86 // because of union, be careful about overwriting function pointer during function invocation
87 auto tmp = fOneTimeGetter_ ();
88 destroy_at (&fOneTimeGetter_);
89 construct_at (&fValue_, move (tmp));
90 });
91 return fValue_;
92 }
93
94}
value-object, where the value construction is delayed until first needed (can be handy to avoid c++ i...