Sub.inl
Go to the documentation of this file.
1 namespace iv
2 {
3 
4 //-----------------------------------------------------------
7 template< class T >
9 {
10 public:
11  static void * T_copy_new( void * src )
12  {
13  T * t_src = reinterpret_cast< T * >( src );
14  T * t_self = new T( *t_src );
15  return reinterpret_cast< T * >( t_self );
16  }
17 
18  static void * T_copy_inplace( void * place, void * src )
19  {
20  T * t_src = reinterpret_cast< T * >( src );
21  T * t_self = new (place) T( *t_src );
22  return reinterpret_cast< T * >( t_self );
23  }
24 
25  static void T_destroy_inplace( void * self )
26  {
27  T * t_self = reinterpret_cast< T * >( self );
28  t_self->~T();
29  }
30 
31  static void T_destroy_delete( void * self )
32  {
33  T * t_self = reinterpret_cast< T * >( self );
34  delete t_self;
35  }
36 
37  static void T_assign_copy( void * self, void * src )
38  {
39  T * t_self = reinterpret_cast< T * >( self );
40  T * t_src = reinterpret_cast< T * >( src );
41  (*t_self) = (*t_src);
42  }
43 
44  static void T_assign_default( void * self )
45  {
46  T * t_self = reinterpret_cast< T * >( self );
47  (*t_self) = T();
48  }
49 
50  //static void * T_move_new( void * src )
51  //{
52  // T * t_src = reinterpret_cast< T * >( src );
53  // T * t_self = new T( std::move( *t_src ) );
54  // return reinterpret_cast< T * >( t_self );
55  //}
56  //
57  //static void * T_move_inplace( void * place, void * src )
58  //{
59  // T * t_src = reinterpret_cast< T * >( src );
60  // T * t_self = new (place) T( std::move( *t_src ) );
61  // return reinterpret_cast< T * >( t_self );
62  //}
63  //
64  //static void T_assign_move( void * self, void * src )
65  //{
66  // (*t_self) = std::move( (*t_src) );
67  //}
68 
70  {
71  this->sizeof_v = sizeof( T );
72  this->alignof_v = alignof( T );
73  this->copy_new = &T_copy_new;
77  this->assign_copy = &T_assign_copy;
79  }
80 
82 };
83 
84 template< class T >
86 
87 //---------------- SubId -------------------------------------------
88 template< class Type, class SubType >
90  _idx( Type::SubDirectoryInst.next++ )
91 {
92 }
93 
94 template< class Type, class SubType >
96 {
97  return this->_idx;
98 }
99 
100 template< class Type, class SubType >
102 {
103  return Type::SubDirectoryInst.next;
104 }
105 
106 //-------------- Sub -----------------------------------------------
107 template< class T >
108 static void l_dynamic_deleter( void * ptr )
109 {
110  delete reinterpret_cast< T * >( ptr );
111 }
112 
113 template< class T >
114 static void l_static_deleter( void * ptr )
115 {
116  T * t = reinterpret_cast< T * >( ptr );
117  t->~T();
118 }
119 
120 template< class SubType, size_t LocalItems, size_t LocalStorage >
122  dir_local(),
123  mem_local(),
124  dir_dynamic(),
125  static_mem_used( 0 )
126 {
127 }
128 
129 template< class SubType, size_t LocalItems, size_t LocalStorage >
131 {
132  // deinitialize everything
133  for( S & s : iv::reversed( this->dir_dynamic ) )
134  if( s.inst )
135  {
136  if( !s.dynamic )
137  s.functions->destroy_inplace( s.inst );
138  else
139  s.functions->destroy_delete( s.inst );
140  }
141  for( S & s : iv::reversed( this->dir_local ) )
142  if( s.inst )
143  {
144  if( !s.dynamic )
145  s.functions->destroy_inplace( s.inst );
146  else
147  s.functions->destroy_delete( s.inst );
148  }
149 }
150 
151 template< class SubType, size_t LocalItems, size_t LocalStorage >
153 {
154  // deinitialize and clear everything
155  for( S & s : iv::reversed( this->dir_dynamic ) )
156  if( s.inst )
157  {
158  if( !s.dynamic )
159  s.functions->destroy_inplace( s.inst );
160  else
161  s.functions->destroy_delete( s.inst );
162  s.inst = nullptr;
163  s.functions = nullptr;
164  s.dynamic = false;
165  }
166 
167  for( S & s : iv::reversed( this->dir_local ) )
168  if( s.inst )
169  {
170  if( !s.dynamic )
171  s.functions->destroy_inplace( s.inst );
172  else
173  s.functions->destroy_delete( s.inst );
174  s.inst = nullptr;
175  s.functions = nullptr;
176  s.dynamic = false;
177  }
178 
179  // reset static memory
180  this->static_mem_used = 0;
181 }
182 
183 template< class Type, size_t LocalItems, size_t LocalStorage >
185 {
186  bool dir_dynamic = idx > LocalItems;
187  if( !dir_dynamic )
188  {
189  return &this->dir_local[ idx ];
190  }
191  else
192  {
193  size_t dyn_idx = Type::SubDirectoryInst.next - LocalItems;
194  this->dir_dynamic.resize( dyn_idx );
195  return &this->dir_dynamic[ dyn_idx ];
196  }
197 }
198 
199 template< class Type, size_t LocalItems, size_t LocalStorage >
200 template< class SubType >
202 {
203  // locate pointer
204  S * s = this->getS( id.idx() );
205 
206  // initialize value
207  if( !s->inst )
208  {
209  // try to align it into static storage
210  void * ptr = mem_local.data() + this->static_mem_used;
211  size_t space = LocalStorage - this->static_mem_used;
212  void * aligned = std::align( alignof( SubType ), sizeof( SubType ), ptr, space );
213 
214  // allocate it
215  if( aligned )
216  {// static
217  this->static_mem_used = LocalStorage - space;
218  s->inst = reinterpret_cast< void * >( new ( aligned ) SubType );
220  s->dynamic = false;
221  }
222  else
223  {// dynamic
224  s->inst = reinterpret_cast< void * >( new SubType );
226  s->dynamic = true;
227  }
228  }
229 
230  // return value
231  return *reinterpret_cast< SubType * >( s->inst );
232 }
233 
234 template< class Type, size_t LocalItems, size_t LocalStorage >
235 void Sub< Type, LocalItems, LocalStorage >::copy( size_t idx, S const & s_src )
236 {
237  // locate pointer
238  S * s = this->getS( idx );
239 
240  // initialize value
241  if( s_src.inst )
242  {
243  if( !s->inst )
244  {
245  // try to align it into static storage
246  void * ptr = mem_local.data() + this->static_mem_used;
247  size_t space = LocalStorage - this->static_mem_used;
248  void * aligned = std::align( s_src.functions->alignof_v, s_src.functions->sizeof_v, ptr, space );
249 
250  // allocate it
251  if( aligned )
252  {// static
253  this->static_mem_used = LocalStorage - space;
254  s->inst = s_src.functions->copy_inplace( aligned, s_src.inst );
255  s->functions = s_src.functions;
256  s->dynamic = false;
257  }
258  else
259  {// dynamic
260  s->inst = s_src.functions->copy_new( s_src.inst );
261  s->functions = s_src.functions;
262  s->dynamic = true;
263  }
264  }
265  else
266  {
267  s_src.functions->assign_copy( s->inst, s_src.inst );
268  }
269  }
270  else
271  {
272  if( s->inst )
273  {
274  // If it exists here but not in source, it will not be deinitialized, but only put to default state - so that we don't mess up the static allocator.
275  s->functions->assign_default( s->inst );
276  }
277  }
278 }
279 
280 template< class Type, size_t LocalItems, size_t LocalStorage >
282 {
283  size_t idx = 0;
284 
285  for( S const & s : src.dir_local )
286  if( s.inst )
287  {
288  this->copy( idx, s );
289  idx += 1;
290  }
291 
292  for( S const & s : src.dir_dynamic )
293  if( s.inst )
294  {
295  this->copy( idx, s );
296  idx += 1;
297  }
298 }
299 
300 template< class Type, size_t LocalItems, size_t LocalStorage >
302 {
303  size_t idx = 0;
304 
305  for( S const & s : src.dir_local )
306  if( s.inst )
307  {
308  this->assign_copy( idx, s );
309  idx += 1;
310  }
311 
312  for( S const & s : src.dir_dynamic )
313  if( s.inst )
314  {
315  this->assign_copy( idx, s );
316  idx += 1;
317  }
318 }
319 
320 }