gatelib  2.1
g_cont_ref_base.h
1 #pragma once
2 
3 #include "g_cont_common.h"
4 #include "g_cont_HeapAbstract.h"
5 #include "g_cont_AllocationPolicyAbstract.h"
6 
7 //
8 //The markator G_REF tells to GJLibSupport to create a .h file in subdirectory [SOURCE_LOCATION]\_g_ref\[ClsName].h
9 //where the list of constructor are included
10 //
11 //class MyCls
12 //{
13 //public:
14 // G_REF
15 // MyCls (int v1) : m1(v1),m2(0) {}
16 // MyCls ( int v1 , int v2 ) : m1(v1),m2(v2) {}
17 //
18 // int get1() const { return m1; }
19 // int get2() const { return m2; }
20 //
21 //private:
22 // int m1,m2;
23 //};
24 //for including ref in your source code use G_REF_HEADER like in:
25 // #include G_REF_HEADER(MyCls)
26 // or directly:
27 //#include "_g_ref/MyCls.h"
28 
29 #define G_REF_HEADER(acls) G_STR(_g_ref/acls.h)
30 
31 namespace g
32 {
33 namespace cont
34 {
35 
36 template < class T > class ref_const;
37 template < class T > class ref_custom;
38 template < class T > class ref_const_custom;
39 template < class T > class ref;
40 
41 template<class T> class ref_base
42 {
43 private:
44  template < class O_T > friend class ref_base;
45  friend class ref_const<T>;
46  friend class ref_custom<T>;
47 
48  ref_base ( ) : mRefMarkerP(NULL),mAllocPolicyP(NULL),mObjOffset(-1){ G_VERBOSE_MSG_L5("ref_base<T>::ref_base()"); }
49  ref_base ( const ref_base& other ) { G_VERBOSE_MSG_L5("ref_base( const ref_base& other )"); }
50 
51 public:
52  virtual ~ref_base() { G_VERBOSE_MSG_L5("ref_base<T>::~ref_base()"); mRefLeave(); }
53 
54  bool operator == ( const ref_base<T>& other ) const { return other.mRefMarkerP == this->mRefMarkerP; }
55 
56  size_t getNumRefs ( ) const { return ( mRefMarkerP!=NULL ) ? mAllocPolicyP->getNumRefs(mRefMarkerP):0; }
57  HeapAbstract* getHeapP ( ) const { return ( mRefMarkerP!=NULL ) ? mAllocPolicyP->getHeapP():NULL; }
58  AllocationPolicyAbstract* getAllocPolicyP ( ) const { return mAllocPolicyP; }
59  bool isEmpty ( ) const { return (mRefMarkerP==NULL); }
60 
61 protected:
62  void* mAllocateMemForObject ( AllocationPolicyAbstract* aDataAllocPolicy )
63  {
64  G_EXC_SET_CONTEXT ( "ref_base<T>::mAllocateMemForObject(HeapAbstract* aHeapP)" );
65 
66  G_VERBOSE_MSG_L5(_g_method_context);
67 
68  if ( aDataAllocPolicy != NULL )
69  {
70  mAllocPolicyP = aDataAllocPolicy;
71  mRefMarkerP = mAllocPolicyP->reserveRef(sizeof(T));
72  mObjOffset = 0x0;
73 
74  G_VERBOSE_MSG_L3("Allocate new ref at mark " << std::hex << (int)mRefMarkerP << std::dec );
75 
76  return mAllocPolicyP->getRefDataLocation(mRefMarkerP);
77  }
78  else
79  {
80  G_EXC_RAISE_CONT ("Not a valid allocation policy!");
81  return NULL;
82  }
83  }
84 
85  void mIncRef ( ) { mAllocPolicyP->incRef(mRefMarkerP); }
86 
87 private:
88  MemMarker* mRefMarkerP;
89  AllocationPolicyAbstract* mAllocPolicyP;
90  //offset from allocation address ( 0, but in the case of multiple inheritance)
91  GInt64_t mObjOffset;
92 
93  void mRefLeave ( )
94  {
95  G_VERBOSE_MSG_L5("ref_base<T>::mRefLeave()");
96 
97  if ( mRefMarkerP != NULL )
98  {
99  G_VERBOSE_MSG_L3 ( "Leaving ref marked at " << std::hex << (int)mRefMarkerP << std::dec << " new ref count " << getNumRefs() );
100 
101  int num_ref = mAllocPolicyP->decRef(mRefMarkerP);
102 
103  if ( num_ref == 0 )
104  {
105  G_VERBOSE_MSG_L3("Num refs == 0 deleting ref marked at " << std::hex << (int)mRefMarkerP << std::dec );
106 
107  mGetObjP ( )->~T();
108 
109  mAllocPolicyP->freeRef ( mRefMarkerP );
110  }
111  else if ( num_ref < 0 )
112  {
113  G_VERBOSE_MSG_L3("Num refs < 0 probably constructor has thrown an exception deleting ref(without deleting object) marked at " << std::hex << (int)mRefMarkerP << std::dec );
114 
115  mAllocPolicyP->freeRef ( mRefMarkerP );
116  }
117 
118  mAllocPolicyP = NULL;
119  mRefMarkerP = NULL;
120  mObjOffset = -1;
121  }
122  else
123  {
124  G_VERBOSE_MSG_L3( "Empty content." );
125  }
126  }
127 
128  //Ref take from ref of same type
129  void mRefTake ( const ref_base& o )
130  {
131  G_VERBOSE_MSG_L5("ref_base<T>::mRefTake ( const ref_base& o )");
132 
133  if ( o.mRefMarkerP != mRefMarkerP )
134  {
135  mRefLeave();
136 
137  if (o.mRefMarkerP)
138  {
139  mRefMarkerP = o.mRefMarkerP;
140  mAllocPolicyP = o.mAllocPolicyP;
141  mAllocPolicyP->incRef(mRefMarkerP);
142  mObjOffset = o.mObjOffset;
143 
144  G_VERBOSE_MSG_L3 ( "Taking ref from other ref marked at " << std::hex << (int)mRefMarkerP << std::dec << " new ref count " << getNumRefs() );
145  }
146  }
147  }
148 
149  template<class O_T> void mRefTake ( const ref_base<O_T>& o )
150  {
151  G_VERBOSE_MSG_L5("ref_base<T>::mRefTake ( const ref_base<O_T>& o )");
152 
153  if ( o.mRefMarkerP != mRefMarkerP )
154  {
155  mRefLeave();
156 
157  if (o.mRefMarkerP)
158  {
159  mRefMarkerP = o.mRefMarkerP;
160  mAllocPolicyP = o.mAllocPolicyP;
161  mAllocPolicyP->incRef(mRefMarkerP);
162 
163  // in order to obtain the offset between source type (O_T*) and destination T*
164  // a fake pointer 1(not NULL would have caused the result to be 0 ) is reinterpret as O_T*,
165  // then is statically casted to a T* value, the algebric value (-1) is the difference between to offsets
166  T* fake = static_cast<T*>(reinterpret_cast<O_T*>(1));
167 
168  mObjOffset = o.mObjOffset + (long long)fake - 1;
169 
170  G_VERBOSE_MSG_L3 ( "Taking ref from other ref of OTHER TYPE marked at " << std::hex << (int)mRefMarkerP << std::dec << " new ref count " << getNumRefs() );
171  }
172  }
173  }
174 
175  template <class O_T> bool mRefTakeTryDynamically ( ref_base<O_T>& o )
176  {
177  G_VERBOSE_MSG_L5( "ref_base<T>::mRefTakeTryDynamically ( const ref_base<O_T>& o )");
178 
179  if ( o.mRefMarkerP != NULL && dynamic_cast<T*>(o.mGetObjP()) )
180  {
181  mRefTake ( o );
182  return true;
183  }
184  else
185  {
186  return false;
187  }
188  }
189 
190  T* mGetObjP ( ) const
191  {
192  G_EXC_SET_CONTEXT ( "T* ref_base<T>mGetObjP ( ) const" );
193 
194  G_VERBOSE_MSG_L5 ("ref_base<T>::mGetObjP()const");
195 
196  if ( mRefMarkerP != NULL )
197  {
198  G_VERBOSE_MSG_L3 ( "Getting pointer to ref marked at " << std::hex << (int)mRefMarkerP << std::dec << " current count " << getNumRefs() );
199  return reinterpret_cast<T*>( reinterpret_cast<char*>(mAllocPolicyP->getRefDataLocation(mRefMarkerP))+mObjOffset);
200  }
201  else
202  {
203  G_EXC_RAISE_CONT ( "Empty object can't be dereferenced!" );
204  return NULL;
205  }
206  }
207 };
208 
209 }//namespace g
210 }//namespace cont
211 
212 
213 
Definition: g_cont_ref_base.h:37
virtual int decRef(MemMarker *)=0
implements decrement ref policy
Definition: g_cont_AllocationPolicyAbstract.h:16
Definition: g.mthread.ThreadSimpleEvent.h:5
Definition: g_cont_it_ref.h:11
Definition: g_cont_ref_base.h:41
Definition: g_cont_HeapAbstract.h:20
Definition: g_cont_it_ref.h:10
Definition: g_cont_AllocationPolicyAbstract.h:13
#define G_EXC_SET_CONTEXT(acontextstr)
Sets the method context.
Definition: g_exception_macros.h:52
Definition: g_cont_ref_base.h:38