ShadowPtr.h
Go to the documentation of this file.
1 #ifndef _utl_ShadowPtr_h_
2 #define _utl_ShadowPtr_h_
3 
4 #include <utl/ShadowPtr_fwd.h>
5 #include <utility>
6 
7 
8 namespace utl {
9 
19  namespace ShadowPtrMeta {
20 
21  struct True { };
22  struct False { char c[256]; };
23 
24  template<typename T>
25  True MatchCloneTag(typename T::IsClonableTag* const);
26 
27  template<typename T>
28  False MatchCloneTag(...);
29 
30  template<typename T>
31  struct HasClone {
32  static const bool value =
33  sizeof(MatchCloneTag<T>(0)) == sizeof(True);
34  };
35 
36  template<bool v, typename T>
37  struct BoolSwitch {
38  static T* GetCopy(const T& t) { return new T(t); }
39  };
40 
41  template<typename T>
42  struct BoolSwitch<true, T> {
43  static T* GetCopy(const T& t) { return t.Clone(); }
44  };
45 
68  template<typename T>
69  T* Clone(const T& src)
70  { return BoolSwitch<HasClone<T>::value, T>::GetCopy(src); }
71 
72  template<typename T>
73  T* CloneOne(const T& src)
74  { return Clone(src); }
75 
76  }
77 
78 
79  template<typename T>
80  class Meta {
81  private:
82  typedef class { } False;
83  typedef class { False f[256]; } True;
84 
85  template<typename U>
86  static True MatchCloneTag(typename U::IsClonableTag* const);
87 
88  template<typename U>
89  static False MatchCloneTag(...);
90 
91  template<typename U>
92  struct HasClone {
93  static const bool value =
94  sizeof(Meta<T>::template MatchCloneTag<U>(0)) == sizeof(True);
95  };
96 
97  template<bool v, int = 0>
98  struct BoolSwitch {
99  static T* GetCopy(const T& t) { return new T(t); }
100  };
101 
102  template<int i>
103  struct BoolSwitch<true, i> {
104  static T* GetCopy(const T& t) { return t.Clone(); }
105  };
106 
107  public:
108  static T* GetCopy(const T& t)
110  };
111 
112 
162  template<typename T, class DereferenceCheck/* = ThrowOnZeroDereference*/>
163  class ShadowPtr {
164 
165  public:
166  ShadowPtr() { }
167 
168  // shallow ctor
169  explicit ShadowPtr(T* const p) : fPtr(p) { }
170 
171  // deep copy ctor
172  ShadowPtr(const ShadowPtr& sp) { DeepCopy(sp.fPtr); }
173 
174  ShadowPtr(ShadowPtr&& sp) noexcept : fPtr(std::exchange(sp.fPtr, nullptr)) { }
175 
177 
178  // deep copy assignment
179  ShadowPtr&
180  operator=(const ShadowPtr& sp)
181  {
182  if (this != &sp) {
183  Delete();
184  DeepCopy(sp.fPtr);
185  }
186  return *this;
187  }
188 
189  ShadowPtr&
191  {
192  Delete();
193  fPtr = sp.fPtr;
194  sp.fPtr = nullptr;
195  return *this;
196  }
197 
199  ShadowPtr& operator=(T* const p) { Delete(); fPtr = p; return *this; }
200 
201  T* Get() { return fPtr; }
202  const T* Get() const { return fPtr; }
203 
204  T& operator*() { DereferenceCheck::Examine(fPtr); return *fPtr; }
205  const T& operator*() const { DereferenceCheck::Examine(fPtr); return *fPtr; }
206 
207  T* operator->() { DereferenceCheck::Examine(fPtr); return fPtr; }
208  const T* operator->() const { DereferenceCheck::Examine(fPtr); return fPtr; }
209 
210  bool operator==(const ShadowPtr& sp) const { return fPtr == sp.fPtr; }
211  bool operator!=(const ShadowPtr& sp) const { return fPtr != sp.fPtr; }
212  bool operator==(const T* const p) const { return fPtr == p; }
213  bool operator!=(const T* const p) const { return fPtr != p; }
214 
215  explicit operator bool() const { return fPtr; }
216 
217  void Swap(ShadowPtr& sp) { std::swap(fPtr, sp.fPtr); }
218 
219  private:
220  void Delete() noexcept { delete fPtr; }
221 
222  protected:
223  void DeepCopy(const T* const p) { fPtr = p ? Meta<T>::GetCopy(*p) : nullptr; }
224 
225  T* fPtr = nullptr;
226 
227  };
228 
229 
230  template<typename T, class DereferenceCheck/* = ThrowOnZeroDereference*/>
231  class InitializedShadowPtr : public ShadowPtr<T, DereferenceCheck> {
232  public:
233  InitializedShadowPtr() : ShadowPtr<T, DereferenceCheck>(new T) { }
234  };
235 
236 
237  template<typename T, class D>
238  inline bool DeepEqual(const ShadowPtr<T, D>& s1, const ShadowPtr<T, D>& s2)
239  { return (!s1 && !s2) || (s1 && s2 && *s1 == *s2); }
240 
241 
243  template<typename T, class D>
245  { a.Swap(b); }
246 
247 }
248 
249 
250 #endif
pointer with built-in initialization, deletion, deep copying
Definition: ShadowPtr.h:163
void swap(utl::Trace< T > &t1, utl::Trace< T > &t2)
Definition: Trace.h:363
T * Clone(const T &src)
Clone a given object.
Definition: ShadowPtr.h:69
ShadowPtr & operator=(ShadowPtr &&sp)
Definition: ShadowPtr.h:190
static const bool value
Definition: ShadowPtr.h:32
const T * Get() const
Definition: ShadowPtr.h:202
void swap(utl::TabulatedFunction &t1, utl::TabulatedFunction &t2)
const T * operator->() const
Definition: ShadowPtr.h:208
static T * GetCopy(const T &t)
Definition: ShadowPtr.h:99
ShadowPtr(T *const p)
Definition: ShadowPtr.h:169
void Delete() noexcept
Definition: ShadowPtr.h:220
True MatchCloneTag(typename T::IsClonableTag *const)
bool operator!=(const ShadowPtr &sp) const
Definition: ShadowPtr.h:211
T * operator->()
Definition: ShadowPtr.h:207
void Swap(ShadowPtr &sp)
Definition: ShadowPtr.h:217
ShadowPtr & operator=(const ShadowPtr &sp)
Definition: ShadowPtr.h:180
constexpr std::size_t noexcept
static T * GetCopy(const T &t)
Definition: ShadowPtr.h:108
void DeepCopy(const T *const p)
Definition: ShadowPtr.h:223
ShadowPtr(const ShadowPtr &sp)
Definition: ShadowPtr.h:172
T & operator*()
Definition: ShadowPtr.h:204
const T & operator*() const
Definition: ShadowPtr.h:205
bool operator==(const T *const p) const
Definition: ShadowPtr.h:212
static const bool value
Definition: ShadowPtr.h:93
static T * GetCopy(const T &t)
Definition: ShadowPtr.h:38
bool operator==(const ShadowPtr &sp) const
Definition: ShadowPtr.h:210
bool DeepEqual(const LameShadowPtr< T, D > &s1, const LameShadowPtr< T, D > &s2)
Definition: LameShadowPtr.h:91
T * CloneOne(const T &src)
Definition: ShadowPtr.h:73
static True MatchCloneTag(typename U::IsClonableTag *const)
bool operator!=(const T *const p) const
Definition: ShadowPtr.h:213
static T * GetCopy(const T &t)
Definition: ShadowPtr.h:104
ShadowPtr(ShadowPtr &&sp) noexcept
Definition: ShadowPtr.h:174
ShadowPtr & operator=(T *const p)
shallow assignment: transfer ownership
Definition: ShadowPtr.h:199
~ShadowPtr() noexcept
Definition: ShadowPtr.h:176

, generated on Tue Sep 26 2023.