gatelib  2.1
g_cont_vect_priv.h
1 #pragma once
2 
3 #include "g_common.h"
4 
5 #if G_AUTOPTION_ON_WINDOWS
6 #include "new"
7 #endif
8 
9 #include "g_cont_private_data_pointer.h"
10 #include "g_cont_AllocationPolicyAbstract.h"
11 
12 #define VECTOR_ALLOC_DELTA 16 //MUST be power of 2
13 
14 namespace g
15 {
16 namespace cont
17 {
18 
19 template < class T , class IT , class IT_C > class vect;
20 
21 namespace priv
22 {
23 
24 template < class T> struct vect_content
25 {
26  vect_content ( AllocationPolicyAbstract* aAllocPolicyP , int aAllocRightBits ):
27  data ( aAllocPolicyP ) ,
28  capacity ( 0 ) ,
29  lbound ( 0 ) ,
30  ubound ( -1 )
31  {
32  aAllocRightBits = ( aAllocRightBits < 1 )?1:aAllocRightBits;
33  allocDelta = 1 << aAllocRightBits;
34  }
35 
36  ~vect_content(){ erase(); }
37 
38  data_pointer<T> data;
39  size_t capacity;
40  int lbound;
41  int ubound;
42  int allocDelta;
43 
44 
45  int first ( )
46  {
47  if (ubound>=lbound)
48  {
49  return 0;
50  }
51  else
52  {
53  return G_CONT_INDEX_NOT_VALID;
54  }
55  }
56 
57  int last ( )
58  {
59  if (ubound>=lbound)
60  {
61  return (int)size()-1;
62  }
63  else
64  {
65  return G_CONT_INDEX_NOT_VALID;
66  }
67  }
68 
69  size_t size ( ) { return ubound-lbound+1; }
70 
71  //-1 means outside
72  int abs_index ( const T* aItem )
73  {
74  if ( data != NULL )
75  {
76  int delta = ( int ) ( aItem - data );
77 
78  return ( delta >= 0 && delta < (int)size() )?delta:-1;
79  }
80  else
81  {
82  return -1;
83  }
84  }
85 
86  //call destructors then set object to empty (without unreserving memory )
87  void empty ( )
88  {
89  for ( int i = 0 ; i < (int)size() ; i++ )
90  {
91  ( data + i )->~T();
92  }
93 
94  lbound = 0;
95  ubound = -1;
96  }
97 
98  void erase ( )
99  {
100  empty();
101 
102  if ( data )
103  {
104  data.free ();
105  }
106  }
107 
108  void changeCapacity ( size_t aNewCapacity )
109  {
110  data.allocate ( aNewCapacity , capacity );
111  capacity = aNewCapacity;
112  }
113 
114  void reserveBytes ( int aLbound , int aUbound )
115  {
116  long long required_capacity = get_rounded_by_power_of_2( (long long)(aUbound - aLbound + 1) , (long long)allocDelta );
117 
118  changeCapacity ( (size_t)required_capacity );
119  }
120 
121  void pushAfter ( int aIndex , const T& aItem )
122  {
123  reserveBytes ( lbound , ubound + 1 );
124 
125  move_data ( data + aIndex + 1 , data + aIndex + 2 , size() - aIndex - 1 );
126 
127  new ( data + aIndex + 1 ) T ( aItem );
128 
129  ubound++;
130  }
131 
132  void setSize ( int aLbound , int aUbound )
133  {
134  G_EXC_SET_CONTEXT ( "void g::cont::vect_content<T>::setSize ( int aLbound , int aUbound )" );
135 
136  empty ( );
137 
138  if ( aUbound >= aLbound )
139  {
140  int new_size = aUbound - aLbound + 1;
141 
142  reserveBytes ( aLbound , aUbound );
143 
144  for ( int i = 0 ; i < new_size ; i++ )
145  {
146  new ( data + i ) T(); //emtpy objects
147  }
148 
149  lbound = aLbound;
150  ubound = aUbound;
151  }
152  else if ( aUbound != -1 || aLbound != 0 )
153  {
154  G_EXC_RAISE_CONT ( "Lbound > ubound!" );
155  }
156  }
157 
158  void replaceContent ( int aLbound , int aUbound , const T* aOtherDataP )
159  {
160  empty ( );
161 
162  reserveBytes ( aLbound , aUbound );
163 
164  for ( int i = aLbound ; i <= aUbound ; i++ )
165  {
166  new ( data + i - aLbound ) T (aOtherDataP[i]);
167  }
168 
169  lbound = aLbound;
170  ubound = aUbound;
171  }
172 
173  void resize ( int aLbound , int aUbound )
174  {
175  if ( !size ( ) )
176  {
177  setSize ( aLbound , aUbound );
178  }
179  else if ( aUbound >= aLbound )
180  {
181  //first index not be delete
182  int start = ( aLbound >= lbound ) ? aLbound : lbound;
183  int stop = ( aUbound <= ubound ) ? aUbound : ubound;
184  int size_to_move = stop - start + 1;
185 
186  //change if required the capacity
187  reserveBytes ( aLbound , aUbound );
188 
189  //delete unused (left)
190  for ( int i = 0 ; i < start - lbound ; i++ )
191  {
192  ( data + i - lbound )->~T();
193  }
194  //delete unused (right)
195  for ( int i = stop + 1 ; i <= ubound ; i++ )
196  {
197  ( data + i - lbound )->~T();
198  }
199 
200  move_data ( data + start - lbound , data + start - aLbound , size_to_move );
201 
202  //initialize empty objetcs (left)
203  for ( int i = aLbound ; i < start ; i++ )
204  {
205  new ( data - aLbound + i ) T(); //emtpy objects
206  }
207 
208  //initialize empty objetcs (left)
209  for ( int i = stop + 1 ; i <= aUbound ; i++ )
210  {
211  new ( data - aLbound + i )T();
212  }
213 
214  lbound = aLbound;
215  ubound = aUbound;
216  }
217  else // = 0
218  {
219  empty ( );
220  }
221  }
222 
223  T remove ( int aIndex )
224  {
225  T result = *( data + aIndex );
226 
227  ( data + aIndex )->~T();
228 
229  move_data ( data + aIndex + 1 , data + aIndex , size() - aIndex - 1 );
230 
231  ubound--;
232 
233  return result;
234  }
235 };
236 
237 template < class T > class vect_positioner : public positioner_abstract<T>
238 {
239 public:
240  vect_positioner ( vect_content<T>* aVectorContentP ) : vectorContentP (aVectorContentP) {}
241  virtual ~vect_positioner () {}
242 
243  virtual int first ( ) const { return vectorContentP->first(); }
244  virtual int last ( ) const { return vectorContentP->last(); }
245 
246  virtual bool isIn ( int aIndex ) const
247  {
248  return ( aIndex >= vectorContentP->lbound && aIndex <= vectorContentP->ubound );
249  }
250 
251  virtual void forward ( int& aItem , GUint32_t aInc ) const
252  {
253  aItem += aInc;
254  }
255 
256  virtual void backward ( int& aItem , GUint32_t aDec ) const
257  {
258  aItem -= aDec;
259  }
260 
261  virtual T* getPtr ( int aIndex ) const
262  {
263  if ( !vectorContentP->data )
264  {
265  return NULL;
266  }
267  else
268  {
269  return vectorContentP->data - vectorContentP->lbound + aIndex;
270  }
271  }
272 
273  vect_content<T>* vectorContentP;
274 };
275 
276 }//namespace priv
277 }//namespace cont
278 }//namespace g
279 
Definition: g_cont_AllocationPolicyAbstract.h:16
Definition: g.mthread.ThreadSimpleEvent.h:5
Definition: g_cont_common.h:52
T get_rounded_by_power_of_2(T value, T delta)
f(v,d) is the next multiple of d(MUST be a power of 2), which is k*d>=v && (k-1)*d
Definition: g_common_functions.h:104
Definition: g_cont_private_data_pointer.h:14
#define G_EXC_SET_CONTEXT(acontextstr)
Sets the method context.
Definition: g_exception_macros.h:52
Definition: g_cont_vect_priv.h:24
Definition: g_cont_vect_priv.h:237