You.i Engine
YiCowPtr.h
Go to the documentation of this file.
1 // © You i Labs Inc. 2000-2017. All rights reserved.
2 #ifndef _YI_COWPTR_H_
3 #define _YI_COWPTR_H_
4 
7 #include "utility/YiRtti.h"
8 
77 template<typename YI_PTR_TYPE, typename YI_DELETE_FUNCTOR = CYICheckedDeleteFunctor<YI_PTR_TYPE> >
78 class CYICowPtr
79 {
80  template<typename YI_OTHER_PTR_TYPE, typename YI_OTHER_DELETE_FUNCTOR> friend class CYICowPtr;
81 protected:
82 
83  YI_DELETE_FUNCTOR DeleteFunc;
85  YI_PTR_TYPE *m_pData;
86 
87  inline void Ref()
88  {
89  if(m_pData)
90  {
91  if(!m_pRefCounter)
92  {
93  m_pRefCounter = new CYIReferenceCounter();
94  }
95  else
96  {
97  m_pRefCounter->StrongRef();
98  m_pRefCounter->WeakRef();
99  }
100  }
101  }
102 
103  inline void Deref()
104  {
105  if(m_pRefCounter)
106  {
107  if(m_pRefCounter->StrongDeref() == 0)
108  {
109  if(m_pData)
110  {
111  DeleteFunc(m_pData);
112  m_pData = nullptr;
113  }
114 
115  }
116 
117  if (m_pRefCounter->WeakRef() == 0)
118  {
119  delete m_pRefCounter;
120  m_pRefCounter = nullptr;
121  }
122  }
123  }
124 
125 public:
126  typedef YI_PTR_TYPE * CYICowPtr<YI_PTR_TYPE, YI_DELETE_FUNCTOR>::* YI_UNSPECIFIED_BOOL_TYPE;
127 
131  inline CYICowPtr() :
132  m_pRefCounter(nullptr),
133  m_pData(nullptr)
134  {
135  }
136 
141  inline explicit CYICowPtr(YI_PTR_TYPE *pData) :
142  m_pRefCounter(nullptr),
143  m_pData(pData)
144  {
145  Ref();
146  }
147 
153  m_pRefCounter(rOther.m_pRefCounter), m_pData(rOther.m_pData)
154  {
155  Ref();
156  }
157 
163  template<typename YI_OTHER_PTR_TYPE, typename YI_OTHER_DELETE_FUNCTOR>
165  m_pRefCounter(rOther.m_pRefCounter), m_pData((YI_PTR_TYPE*) rOther.m_pData)
166  {
167  Ref();
168  }
169 
173  inline ~CYICowPtr()
174  {
175  Deref();
176  }
177 
182  inline void Detach()
183  {
184  if (m_pData && GetRefCount() > 1)
185  {
186  YI_PTR_TYPE *pCloneData = new YI_PTR_TYPE(*m_pData);
187  Deref();
188  m_pRefCounter = nullptr;
189  m_pData = pCloneData;
190  Ref();
191  }
192  }
193 
199  inline void Reset()
200  {
202  }
203 
221  inline const YI_PTR_TYPE &operator*() const
222  {
223  YI_ASSERT(m_pData, "CYICowPtr", "Attempted to dereference a null copy-on-write pointer.");
224  return *m_pData;
225  }
226 
244  inline YI_PTR_TYPE &operator*()
245  {
246  YI_ASSERT(m_pData, "CYICowPtr", "Attempted to dereference a null copy-on-write pointer.");
247  Detach();
248  return *m_pData;
249  }
250 
251 
268  inline const YI_PTR_TYPE *operator->() const
269  {
270  YI_ASSERT(m_pData, "CYICowPtr", "Attempted to dereference a null copy-on-write pointer.");
271  return m_pData;
272  }
273 
290  inline YI_PTR_TYPE *operator->()
291  {
292  YI_ASSERT(m_pData, "CYICowPtr", "Attempted to dereference a null copy-on-write pointer.");
293  Detach();
294  return m_pData;
295  }
296 
319  inline bool operator!() const
320  {
321  return m_pData == nullptr;
322  }
323 
345  inline operator YI_UNSPECIFIED_BOOL_TYPE() const
346  {
347  return m_pData == nullptr ? nullptr : &CYICowPtr<YI_PTR_TYPE, YI_DELETE_FUNCTOR>::m_pData;
348  }
349 
359  {
360  if (m_pData != rOther.m_pData)
361  {
362  Deref();
363  m_pRefCounter = rOther.m_pRefCounter;
364  m_pData = rOther.m_pData;
365  Ref();
366  }
367  return *this;
368  }
369 
378  template<typename YI_OTHER_PTR_TYPE, typename YI_OTHER_DELETE_FUNCTOR>
380  {
381  if (m_pData != rOther.m_pData)
382  {
383  Deref();
384  m_pRefCounter = rOther.m_pRefCounter;
385  m_pData = (YI_PTR_TYPE*) rOther.m_pData;
386  Ref();
387  }
388  return *this;
389  }
390 
409  inline const YI_PTR_TYPE *Get() const
410  {
411  return m_pData;
412  }
413 
436  inline bool IsNull() const
437  {
438  return m_pData == nullptr;
439  }
440 
444  inline int32_t GetRefCount() const
445  {
446  if(m_pRefCounter)
447  {
448  return m_pRefCounter->GetStrongRefCount();
449  }
450  return 0;
451  }
452 
477  {
478  std::swap(m_pRefCounter, rPtr.m_pRefCounter);
479  std::swap(m_pData, rPtr.m_pData);
480  }
481 
482 
483 };
484 
486 
487 template<typename YI_L_PTR_TYPE, typename YI_L_DELETE_FUNCTOR, typename YI_R_PTR_TYPE, typename YI_R_DELETE_FUNCTOR>
489 {
490  return rLhs.Get() == rRhs.Get();
491 }
492 
493 template<typename YI_L_PTR_TYPE, typename YI_L_DELETE_FUNCTOR, typename YI_R_PTR_TYPE, typename YI_R_DELETE_FUNCTOR>
495 {
496  return rLhs.Get() != rRhs.Get();
497 }
498 
499 template<typename YI_L_PTR_TYPE, typename YI_L_DELETE_FUNCTOR, typename YI_R_PTR_TYPE>
500 inline bool operator==(const CYICowPtr<YI_L_PTR_TYPE, YI_L_DELETE_FUNCTOR> &rLhs, const YI_R_PTR_TYPE *pRhs)
501 {
502  return rLhs.Get() == pRhs;
503 }
504 
505 template<typename YI_L_PTR_TYPE, typename YI_L_DELETE_FUNCTOR, typename YI_R_PTR_TYPE>
506 inline bool operator!=(const CYICowPtr<YI_L_PTR_TYPE, YI_L_DELETE_FUNCTOR> &rLhs, const YI_R_PTR_TYPE *pRhs)
507 {
508  return rLhs.Get() != pRhs;
509 }
510 
511 template<typename YI_L_PTR_TYPE, typename YI_R_PTR_TYPE, typename YI_R_DELETE_FUNCTOR>
512 inline bool operator==(const YI_L_PTR_TYPE *pLhs, const CYICowPtr<YI_R_PTR_TYPE, YI_R_DELETE_FUNCTOR> &rRhs)
513 {
514  return pLhs == rRhs.Get();
515 }
516 
517 template<typename YI_L_PTR_TYPE, typename YI_R_PTR_TYPE, typename YI_R_DELETE_FUNCTOR>
518 inline bool operator!=(const YI_L_PTR_TYPE *pLhs, const CYICowPtr<YI_R_PTR_TYPE, YI_R_DELETE_FUNCTOR> &rRhs)
519 {
520  return pLhs != rRhs.Get();
521 }
522 
525 #endif /* _YI_COWPTR_H_ */
void Detach()
Definition: YiCowPtr.h:182
const YI_PTR_TYPE & operator*() const
Definition: YiCowPtr.h:221
CYICowPtr< YI_PTR_TYPE, YI_DELETE_FUNCTOR > & operator=(const CYICowPtr< YI_OTHER_PTR_TYPE, YI_OTHER_DELETE_FUNCTOR > &rOther)
Definition: YiCowPtr.h:379
YI_DELETE_FUNCTOR DeleteFunc
Definition: YiCowPtr.h:83
CYICowPtr< YI_PTR_TYPE, YI_DELETE_FUNCTOR > & operator=(const CYICowPtr< YI_PTR_TYPE, YI_DELETE_FUNCTOR > &rOther)
Definition: YiCowPtr.h:358
CYICowPtr(const CYICowPtr< YI_PTR_TYPE, YI_DELETE_FUNCTOR > &rOther)
Definition: YiCowPtr.h:152
const YI_PTR_TYPE * operator->() const
Definition: YiCowPtr.h:268
void Reset()
Definition: YiCowPtr.h:199
bool IsNull() const
Definition: YiCowPtr.h:436
bool operator!() const
Definition: YiCowPtr.h:319
bool operator!=(const CYICowPtr< YI_L_PTR_TYPE, YI_L_DELETE_FUNCTOR > &rLhs, const CYICowPtr< YI_R_PTR_TYPE, YI_R_DELETE_FUNCTOR > &rRhs)
Definition: YiCowPtr.h:494
int32_t GetRefCount() const
Definition: YiCowPtr.h:444
bool operator==(const CYICowPtr< YI_L_PTR_TYPE, YI_L_DELETE_FUNCTOR > &rLhs, const CYICowPtr< YI_R_PTR_TYPE, YI_R_DELETE_FUNCTOR > &rRhs)
Definition: YiCowPtr.h:488
YI_PTR_TYPE * operator->()
Definition: YiCowPtr.h:290
Definition: YiReferenceCounter.h:23
CYICowPtr(const CYICowPtr< YI_OTHER_PTR_TYPE, YI_OTHER_DELETE_FUNCTOR > &rOther)
Definition: YiCowPtr.h:164
CYICowPtr(YI_PTR_TYPE *pData)
Definition: YiCowPtr.h:141
YI_PTR_TYPE & operator*()
Definition: YiCowPtr.h:244
void Swap(CYICowPtr< YI_PTR_TYPE, YI_DELETE_FUNCTOR > &rPtr)
Definition: YiCowPtr.h:476
const YI_PTR_TYPE * Get() const
Definition: YiCowPtr.h:409
~CYICowPtr()
Definition: YiCowPtr.h:173
uint32_t StrongRef()
YI_PTR_TYPE * m_pData
Definition: YiCowPtr.h:85
uint32_t StrongDeref()
void Deref()
Definition: YiCowPtr.h:103
#define YI_ASSERT(condition, tag, msg,...)
Platform-independent assertion macro.
Definition: YiError.h:37
The CYICowPtr is a smart pointer that performs a shallow-copy when duplicated, and a deep-copy only w...
Definition: YiCowPtr.h:78
CYICowPtr()
Definition: YiCowPtr.h:131
This file contains the classes and macros used to implement RTTI in You.i Engine. ...
CYIReferenceCounter * m_pRefCounter
Definition: YiCowPtr.h:84
uint32_t GetStrongRefCount() const
void Ref()
Definition: YiCowPtr.h:87