7namespace Stroika::Foundation::Memory {
14 template <
typename T,
typename SHARED_IMLP>
15 inline SHARED_IMLP SharedByValue_CopyByDefault<T, SHARED_IMLP>::operator() (
const T& t)
const
17 if constexpr (same_as<SHARED_IMLP, shared_ptr<T>>) {
18 return Memory::MakeSharedPtr<T> (t);
20 return SHARED_IMLP{
new T{t}};
28 template <
typename T,
typename TRAITS>
30 : fCopier_{element_copier_type{}}
34 template <
typename T,
typename TRAITS>
40 template <
typename T,
typename TRAITS>
43 , fSharedImpl_{copier (from)}
46 template <
typename T,
typename TRAITS>
48 : fCopier_{move (copier)}
49 , fSharedImpl_{move (from)}
52 template <
typename T,
typename TRAITS>
58 template <
typename T,
typename TRAITS>
59 inline SharedByValue<T, TRAITS>& SharedByValue<T, TRAITS>::operator= (
const shared_ptr_type& from)
noexcept
63 if (fSharedImpl_ != from) [[likely]] {
68 template <
typename T,
typename TRAITS>
69 inline SharedByValue<T, TRAITS>::operator bool () const noexcept
71 return fSharedImpl_.get () !=
nullptr;
73 template <
typename T,
typename TRAITS>
74 inline SharedByValue<T, TRAITS>& SharedByValue<T, TRAITS>::operator= (shared_ptr_type&& from)
noexcept
78 if (fSharedImpl_ != from) [[likely]] {
79 fSharedImpl_ = move (from);
83 template <
typename T,
typename TRAITS>
86 return fSharedImpl_.get ();
88 template <
typename T,
typename TRAITS>
93 template <
typename T,
typename TRAITS>
96 return rwget_ptr (fCopier_);
98 template <
typename T,
typename TRAITS>
99 template <
typename COPIER>
102 if (fSharedImpl_ !=
nullptr) [[likely]] {
103 auto result = forward<COPIER> (copier) (fSharedImpl_);
104 Assert (result.use_count () == 1);
109 template <
typename T,
typename TRAITS>
112 return rwget (fCopier_);
114 template <
typename T,
typename TRAITS>
115 template <
typename COPIER>
124 if (fSharedImpl_ !=
nullptr) [[likely]] {
125 AssureNOrFewerReferences (forward<COPIER> (copier));
126 Ensure (fSharedImpl_.use_count () == 1);
127 return fSharedImpl_.get ();
131 template <
typename T,
typename TRAITS>
134 return fSharedImpl_.get ();
136 template <
typename T,
typename TRAITS>
141 template <
typename T,
typename TRAITS>
144 const element_type* ptr = cget ();
148 template <
typename T,
typename TRAITS>
151 return fSharedImpl_ ==
nullptr;
153 template <
typename T,
typename TRAITS>
154 inline typename SharedByValue<T, TRAITS>::element_copier_type SharedByValue<T, TRAITS>::GetDefaultCopier ()
const
158 template <
typename T,
typename TRAITS>
161 switch (fSharedImpl_.use_count ()) {
163 Assert (fSharedImpl_.get () ==
nullptr);
164 return SharedByValue_State::eNull;
166 Assert (fSharedImpl_.get () !=
nullptr);
167 return SharedByValue_State::eSolo;
169 Assert (fSharedImpl_.get () !=
nullptr);
175 return SharedByValue_State::eShared;
178 template <
typename T,
typename TRAITS>
183 template <
typename T,
typename TRAITS>
188 template <
typename T,
typename TRAITS>
189 template <
typename COPIER>
193 if (
static_cast<unsigned int> (fSharedImpl_.use_count ()) > n) [[unlikely]] {
194 BreakReferences_ (forward<COPIER> (copier));
195 Assert (this->use_count () == 1);
198 template <
typename T,
typename TRAITS>
201 AssureNOrFewerReferences (fCopier_, n);
203 template <
typename T,
typename TRAITS>
204 template <
typename COPIER>
205 void SharedByValue<T, TRAITS>::BreakReferences_ (COPIER&& copier)
229 fSharedImpl_ = forward<COPIER> (copier) (*fSharedImpl_);
#define RequireNotNull(p)
SharedByValue is a utility class to implement Copy-On-Write (aka COW) - sort of halfway between uniqu...
nonvirtual unsigned int use_count() const
SharedByValue() noexcept=default