Mobile API Reference  MicroStrategy 2019
SmartPtrI.h
Go to the documentation of this file.
1 //==============================================================================================
2 // FILENAME : SmartPtrI.h
3 // AUTHOR : Juan Pablo Muraira
4 // CREATION : 9/26/01
5 // Copyright (C) MicroStrategy Incorporated 2001
6 // All Rights Reserved
7 //==============================================================================================
8 #ifndef MBase_SmartPtrI_h
9 #define MBase_SmartPtrI_h
10 
11 #include "Asserte.h"
12 #include "ReturnPtrI.h"
13 #include "Null.h"
14 
15 namespace MBase
16 {
34  template<class ReferenceCountedT>
35  class SmartPtrI
36  {
37  public:
38  SmartPtrI(ReferenceCountedT* ipData=NULL) throw() :
39  mpData(ipData)
40  {
41  if(mpData)
42  {
43  mpData->AddRef();
44  }
45  }
46 
47  // copy constructor allowed on SmartPtr
48  // upcast should be implicit
49  template<class ReferenceCountedU>
50  SmartPtrI(const SmartPtrI<ReferenceCountedU>& irSmartPtrI) throw()
51  {
52  if (!irSmartPtrI.IsNull())
53  {
54  mpData = irSmartPtrI.Get();
55  mpData->AddRef();
56  }
57  else
58  {
59  mpData = NULL;
60  }
61  }
62 
63  SmartPtrI(const SmartPtrI<ReferenceCountedT>& irSmartPtrI) throw()
64  {
65  if (!irSmartPtrI.IsNull())
66  {
67  mpData = irSmartPtrI.Get();
68  mpData->AddRef();
69  }
70  else
71  {
72  mpData = NULL;
73  }
74  }
75 
76  // constructor from a return ptr, upcast should be implicit
77 
78 #if defined(__IBMCPP__) || defined(WIN64) || defined(__GNUG__) || defined(__hpux)
79  // VisualAge compiler doesn't resolve copy-constructors with non-const
80  // arguments. So we have to make the argument const and make a const
81  // cast inside.
82  template<class ReferenceCountedU>
83  SmartPtrI(const ReturnPtrI<ReferenceCountedU>& irReturnPtrI) throw()
84  {
85  // do not add ref again, "steal" the reference from the return ptr
86  mpData = const_cast<ReturnPtrI<ReferenceCountedU>&>(irReturnPtrI).GiveUp();
87  }
88 #else
89  template<class ReferenceCountedU>
91  {
92  // do not add ref again, "steal" the reference from the return ptr
93  mpData = irReturnPtrI.GiveUp();
94  }
95 #endif
96 
97  ~SmartPtrI() throw()
98  {
99  Dispose();
100  }
101 
102  void Reset(ReferenceCountedT* ipData=NULL) throw()
103  {
104  if(mpData!=ipData)
105  {
106  Dispose();
107  mpData=ipData;
108  if(mpData)
109  {
110  mpData->AddRef();
111  }
112  }
113  }
114 
115  // Attach to a raw pointer without AddRef
116  void Attach(ReferenceCountedT* ipData=NULL) throw()
117  {
118  Dispose();
119  mpData=ipData;
120  }
121 
122  // Assignment operator of raw pointer
123  // upcast should be implicit
124  SmartPtrI& operator=(ReferenceCountedT* ipData) throw()
125  {
126  Reset(ipData);
127  return *this;
128  }
129 
130  // Assignment operator
131  // upcast should be implicit
132  template<class ReferenceCountedU>
133  SmartPtrI& operator=(const SmartPtrI<ReferenceCountedU>& irSmartPtrI) throw()
134  {
135  if (!irSmartPtrI.IsNull())
136  {
137  Reset(irSmartPtrI.Get());
138  }
139  else
140  {
141  Reset(NULL);
142  }
143  return *this;
144  }
145 
146  SmartPtrI& operator=(const SmartPtrI<ReferenceCountedT>& irSmartPtrI) throw()
147  {
148  if (!irSmartPtrI.IsNull())
149  {
150  Reset(irSmartPtrI.Get());
151  }
152  else
153  {
154  Reset(NULL);
155  }
156  return *this;
157  }
158 
159  // Assignment operator from a return ptr
160  // upcast should be implicit
161  template<class ReferenceCountedU>
163  {
164  // do not add ref again, "steal" the reference from the return ptr
165  Reset(NULL);
166  mpData=irReturnPtrI.GiveUp();
167  return *this;
168  }
169 
170 #if defined(__IBMCPP__) || defined(WIN64) || defined(__GNUG__) || defined(__hpux)
171  SmartPtrI& operator=(const ReturnPtrI<ReferenceCountedT>& irReturnPtrI) throw()
172 #else
174 #endif
175  {
176  // do not add ref again, "steal" the reference from the return ptr
177  Reset(NULL);
178 
179 #if defined(__IBMCPP__) || defined(WIN64) || defined(__GNUG__) || defined(__hpux)
180  mpData = const_cast<ReturnPtrI<ReferenceCountedT>&>(irReturnPtrI).GiveUp();
181 #else
182  mpData=irReturnPtrI.GiveUp();
183 #endif
184 
185  return *this;
186  }
187  ReferenceCountedT* operator->() const throw()
188  {
189  _ASSERTE(mpData!=NULL);
190  return mpData;
191  }
192 
193  ReferenceCountedT& operator*() const throw()
194  {
195  _ASSERTE(mpData!=NULL);
196  return *mpData;
197  }
198 
199  ReferenceCountedT* Get() const throw()
200  {
201  return mpData;
202  }
203 
204  bool IsNull() const throw()
205  {
206  return !mpData;
207  }
208 
209  template<class ReferenceCountedU>
210  void DownCastFrom(SmartPtrI<ReferenceCountedU>& irSmartPtrI) throw()
211  {
212  // Only modify if iData is different from the current member
213  if(static_cast<ReferenceCountedU*>(mpData) != irSmartPtrI.Get())
214  {
215  Reset(reinterpret_cast<ReferenceCountedT*>(irSmartPtrI.Get()));
216  }
217  }
218 
219  bool operator==(const SmartPtrI& iSmartBase) const
220  {
221  return mpData==iSmartBase.mpData;
222  }
223 
224  bool operator<(const SmartPtrI& iSmartBase) const
225  {
226  return mpData<iSmartBase.mpData;
227  }
228 
229  // GiveUp will relinquish this reference to the object
230  // (we will not call release when it goes out of scope)
231  ReferenceCountedT* GiveUp() throw()
232  {
233  ReferenceCountedT* lpTemp=mpData;
234  mpData=NULL;
235  return lpTemp;
236  }
237 
238  // implicit cast to return ptr (to allow user to just call "return SmartPtrI")
240  {
241  return Return();
242  }
243 
244  // create a ReturnPtrI from this smart ptr
245  // this will increment the reference count by 1 (upon creating the return ptr)
247  {
248  return ReturnPtrI<ReferenceCountedT>(mpData);
249  }
250  private:
251  void Dispose() throw()
252  {
253  //To avoid problems with circular references make a temporary
254  //copy first and set the member to the new one before deleting it
255  ReferenceCountedT* lpDataTemp = mpData;
256  if(lpDataTemp)
257  {
258  mpData=NULL;
259  lpDataTemp->Release();
260  }
261  }
262  ReferenceCountedT* mpData;
263  };
264 }
265 
266 #endif // MBase_SmartPtrI_h
SmartPtrI & operator=(const SmartPtrI< ReferenceCountedT > &irSmartPtrI)
Definition: SmartPtrI.h:146
ReferenceCountedT * GiveUp()
Definition: SmartPtrI.h:231
void DownCastFrom(SmartPtrI< ReferenceCountedU > &irSmartPtrI)
Definition: SmartPtrI.h:210
SmartPtrI(const SmartPtrI< ReferenceCountedT > &irSmartPtrI)
Definition: SmartPtrI.h:63
bool IsNull() const
Definition: SmartPtrI.h:204
#define _ASSERTE(x)
Definition: Asserte.h:40
void Attach(ReferenceCountedT *ipData=NULL)
Definition: SmartPtrI.h:116
void Reset(ReferenceCountedT *ipData=NULL)
Definition: SmartPtrI.h:102
bool operator==(const SmartPtrI &iSmartBase) const
Definition: SmartPtrI.h:219
ReferenceCountedT * Get() const
Definition: SmartPtrI.h:199
SmartPtrI & operator=(const SmartPtrI< ReferenceCountedU > &irSmartPtrI)
Definition: SmartPtrI.h:133
ReturnPtrI< ReferenceCountedT > Return() const
Definition: SmartPtrI.h:246
Definition: Allocator.h:47
SmartPtrI(const SmartPtrI< ReferenceCountedU > &irSmartPtrI)
Definition: SmartPtrI.h:50
Definition: ReturnPtrI.h:47
SmartPtrI(ReferenceCountedT *ipData=NULL)
Definition: SmartPtrI.h:38
ReferenceCountedT & operator*() const
Definition: SmartPtrI.h:193
bool operator<(const SmartPtrI &iSmartBase) const
Definition: SmartPtrI.h:224
SmartPtrI & operator=(ReferenceCountedT *ipData)
Definition: SmartPtrI.h:124
SmartPtrI & operator=(ReturnPtrI< ReferenceCountedT > &irReturnPtrI)
Definition: SmartPtrI.h:173
#define NULL
Definition: Null.h:10
SmartPtrI(ReturnPtrI< ReferenceCountedU > &irReturnPtrI)
Definition: SmartPtrI.h:90
~SmartPtrI()
Definition: SmartPtrI.h:97
ReferenceCountedT * operator->() const
Definition: SmartPtrI.h:187
SmartPtrI & operator=(ReturnPtrI< ReferenceCountedU > &irReturnPtrI)
Definition: SmartPtrI.h:162
Definition: ReturnPtrI.h:22