Mobile API Reference  MicroStrategy 2019
SmartBase.h
Go to the documentation of this file.
1 //==============================================================================================
2 // FILENAME : SmartBase.h
3 // AUTHOR : Juan Pablo Muraira
4 // CREATION : 10/19/2001
5 // Copyright (C) MicroStrategy Incorporated 2001
6 //==============================================================================================
7 #ifndef MSynch_SmartBase_h
8 #define MSynch_SmartBase_h
9 
10 #include "Base/Defines/Null.h"
11 #include "Base/Defines/Asserte.h"
13 #if defined(_NO_EXCEPTION)
14 #include <stdio.h>
15 #endif
16 
17 namespace MSynch
18 {
19  template<class T,class DeleteOperator>
20  class SmartBase
21  {
22  public:
23  ~SmartBase() throw();
24 
25  T Get() const throw()
26  {
27  return mData;
28  }
29 
30  // if reset throws, it will free the resource it's being set to guard
31  // IMPORTANT: reset assumes that the assignment of T does not throw
32  void Reset(T iData=NULL)
33  {
34  _ASSERTE(*mpnRefCount<10000); // Reference count is corrupted
35  _ASSERTE(*mpnRefCount>0); // Reference count is corrupted
36 
37  // Only modify if iData is different from the current member
38  if(mData!=iData)
39  {
40  //create a new reference count and start using that one
41 
42  // first try to allocate the new ref count
43  Int32* lpnTempRefCount=NULL;
44 #if !defined(_NO_EXCEPTION)
45  try
46  {
47  lpnTempRefCount=new Int32(1);
48  }
49  catch(...)
50  {
51  // if memory allocation fails,
52  // delete resource we were assigned to guard and rethrow
53  // this SmartPtr remains unchanged
54  DeleteOperator()(iData);
55  throw;
56  }
57 #else
58  lpnTempRefCount=new Int32(1);
59 #endif
60 
61  // if we were able to allocate the new refcount, then we
62  // are safe, decrement the original refcount and copy over
63  // the new guarded object
64  Dispose();
65 
66  mpnRefCount=lpnTempRefCount;
67  lpnTempRefCount=NULL;
68 
69  mData = iData;
70  }
71  }
72 
73  bool operator==(const SmartBase& iSmartBase) const
74  {
75  return mData==iSmartBase.mData;
76  }
77 
78  bool operator<(const SmartBase& iSmartBase) const
79  {
80  return mData<iSmartBase.mData;
81  }
82 
83  bool IsNull() const throw()
84  {
85  return mData==NULL;
86  }
87  protected:
88  explicit SmartBase(T iData = NULL);
89 
90  explicit SmartBase(const SmartBase& iSmartPtr) throw() :
91  mpnRefCount(iSmartPtr.mpnRefCount),
92  mData(iSmartPtr.mData)
93  {
94  _ASSERTE(*mpnRefCount<10000); // Reference count is corrupted
95  _ASSERTE(*mpnRefCount>0); // Reference count is corrupted
96 
97  ++(*mpnRefCount);
98  }
99 
100  SmartBase(T iData, Int32* ipRefCount) throw() :
101  mpnRefCount(ipRefCount),
102  mData(iData)
103  {
104  _ASSERTE(*mpnRefCount<10000); // Reference count is corrupted
105  _ASSERTE(*mpnRefCount>0); // Reference count is corrupted
106 
107  ++(*mpnRefCount);
108  }
109 
111  {
112  //To avoid problems with circular references make a temporary
113  //copy first and set the member to NULL.
114  T lData = mData;
115  if (lData)
116  {
117  mData = NULL;
118  DeleteOperator()(lData);
119  lData = NULL;
120  }
121  }
122 
123  void Dispose() throw()
124  {
125  if(mpnRefCount)
126  {
127  _ASSERTE(*mpnRefCount<10000); // Reference count is corrupted
128  _ASSERTE(*mpnRefCount>=0); // Reference count is corrupted
129 
130  if ((--(*mpnRefCount)) == 0)
131  {
132  //To avoid problems with circular references make a temporary
133  //copy first and set the member to NULL.
134  Int32* lpnRefCount = mpnRefCount;
135 
136  if (lpnRefCount)
137  {
138  mpnRefCount = NULL;
139  delete lpnRefCount;
140  lpnRefCount=NULL;
141  }
143  }
144  }
145  }
146 
147  void ReplaceWith(T iData,Int32* ipRefCount) throw()
148  {
149  Dispose();
150 
151  _ASSERTE(*ipRefCount<10000); // Reference count is corrupted
152  _ASSERTE(*ipRefCount>0); // Reference count is corrupted
153 
154  mpnRefCount = ipRefCount;
155  ++(*mpnRefCount);
156  mData = iData;
157  }
158 
159  private:
160  SmartBase& operator=(const SmartBase&);
161 
162  public:
164  // For all purposes, these data members should be considered protected.
165  // They are only public here to allow SmartPtrs to have polymorphism.
166  // No other class other than SmartBase derived classes should access these members.
167  T mData;
168 
170  };
171 
172  template<class T,class DeleteOperator>
174  {
175  Dispose();
176  }
177 
178  template<class T,class DeleteOperator>
180  mData(iData),
181  mpnRefCount(NULL)
182  {
183  // When the first smart pointer is created, we must allocate the
184  // space for the reference count. If it fails to allocate that space,
185  // cleanup mData (which we already own) and rethrow.
186 #if !defined(_NO_EXCEPTION)
187  try
188  {
189  mpnRefCount = new Int32(1);
190  }
191  catch(...)
192  {
193  CallDeleteOperator();
194  throw;
195  }
196 #else
197  mpnRefCount = new Int32(1);
198 #endif
199 
200  }
201 
202 }
203 
204 #endif // MSynch_SmartBase_h
Int32 * mpnRefCount
Definition: SmartBase.h:169
bool IsNull() const
Definition: SmartBase.h:83
void ReplaceWith(T iData, Int32 *ipRefCount)
Definition: SmartBase.h:147
~SmartBase()
Definition: SmartBase.h:173
void CallDeleteOperator()
Definition: SmartBase.h:110
T mData
Definition: SmartBase.h:167
SmartBase(const SmartBase &iSmartPtr)
Definition: SmartBase.h:90
#define _ASSERTE(x)
Definition: Asserte.h:40
bool operator==(const SmartBase &iSmartBase) const
Definition: SmartBase.h:73
Definition: ReferenceCountedImpl.h:18
void Reset(T iData=NULL)
Definition: SmartBase.h:32
#define Int32
Definition: BasicTypes.h:20
void Dispose()
Definition: SmartBase.h:123
SmartBase(T iData=NULL)
Definition: SmartBase.h:179
T Get() const
Definition: SmartBase.h:25
bool operator<(const SmartBase &iSmartBase) const
Definition: SmartBase.h:78
SmartBase(T iData, Int32 *ipRefCount)
Definition: SmartBase.h:100
#define NULL
Definition: Null.h:10
Definition: SmartBase.h:20