SLikeNet  0.1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
smartptr.h
Go to the documentation of this file.
1 /*
2  * Original work: Copyright (c) 2014, Oculus VR, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7  * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8  *
9  *
10  * Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
11  *
12  * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13  * license found in the license.txt file in the root directory of this source tree.
14  */
15 
16 #ifndef __RAKNET_SMART_PTR_H
17 #define __RAKNET_SMART_PTR_H
18 
19 // From http://www.codeproject.com/KB/cpp/SmartPointers.aspx
20 // with bugs fixed
21 
22 #include "memoryoverride.h"
23 #include "Export.h"
24 
25 //static int allocCount=0;
26 //static int deallocCount=0;
27 
28 namespace SLNet
29 {
30 
32 {
33 private:
34  int refCount;
35 
36 public:
37  ReferenceCounter() {refCount=0;}
39  void AddRef() {refCount++;}
40  int Release() {return --refCount;}
41  int GetRefCount(void) const {return refCount;}
42 };
43 
44 template < typename T > class RAK_DLL_EXPORT RakNetSmartPtr
45 {
46 private:
47  T* ptr; // pointer
48  ReferenceCounter* reference; // Reference refCount
49 
50 public:
51  RakNetSmartPtr() : ptr(0), reference(0)
52  {
53  // Do not allocate by default, wasteful if we just have a list of preallocated and unassigend smart pointers
54  }
55 
56  RakNetSmartPtr(T* pValue) : ptr(pValue)
57  {
58  reference = SLNet::OP_NEW<ReferenceCounter>(_FILE_AND_LINE_);
59  reference->AddRef();
60 
61 // allocCount+=2;
62 // printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
63  }
64 
65  RakNetSmartPtr(const RakNetSmartPtr<T>& sp) : ptr(sp.ptr), reference(sp.reference)
66  {
67  if (reference)
68  reference->AddRef();
69  }
70 
72  {
73  if(reference && reference->Release() == 0)
74  {
77 
78 // deallocCount+=2;
79 // printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
80  }
81  }
82 
83  bool IsNull(void) const
84  {
85  return ptr==0;
86  }
87 
88  void SetNull(void)
89  {
90  if(reference && reference->Release() == 0)
91  {
94 
95 // deallocCount+=2;
96 // printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
97  }
98  ptr=0;
99  reference=0;
100  }
101 
102  bool IsUnique(void) const
103  {
104  return reference->GetRefCount()==1;
105  }
106 
107  // Allow you to change the values of the internal contents of the pointer, without changing what is pointed to by other instances of the smart pointer
108  void Clone(bool copyContents)
109  {
110  if (IsUnique()==false)
111  {
112  reference->Release();
113 
114  reference = SLNet::OP_NEW<ReferenceCounter>(_FILE_AND_LINE_);
115  reference->AddRef();
116  T* oldPtr=ptr;
117  ptr= SLNet::OP_NEW<T>(_FILE_AND_LINE_);
118  if (copyContents)
119  *ptr=*oldPtr;
120  }
121  }
122 
123  int GetRefCount(void) const
124  {
125  return reference->GetRefCount();
126  }
127 
128  T& operator* ()
129  {
130  return *ptr;
131  }
132 
133  const T& operator* () const
134  {
135  return *ptr;
136  }
137 
138  T* operator-> ()
139  {
140  return ptr;
141  }
142 
143  const T* operator-> () const
144  {
145  return ptr;
146  }
147 
148  bool operator == (const RakNetSmartPtr<T>& sp)
149  {
150  return ptr == sp.ptr;
151  }
152  bool operator<( const RakNetSmartPtr<T> &right ) {return ptr < right.ptr;}
153  bool operator>( const RakNetSmartPtr<T> &right ) {return ptr > right.ptr;}
154 
155  bool operator != (const RakNetSmartPtr<T>& sp)
156  {
157  return ptr != sp.ptr;
158  }
159 
160  RakNetSmartPtr<T>& operator = (const RakNetSmartPtr<T>& sp)
161  {
162  // Assignment operator
163 
164  if (this != &sp) // Avoid self assignment
165  {
166  if(reference && reference->Release() == 0)
167  {
169  SLNet::OP_DELETE(reference, _FILE_AND_LINE_);
170 
171 // deallocCount+=2;
172 // printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
173  }
174 
175  ptr = sp.ptr;
176  reference = sp.reference;
177  if (reference)
178  reference->AddRef();
179  }
180  return *this;
181  }
182 
183 
184 };
185 
186 } // namespace SLNet
187 
188 #endif