mist_alloc.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 
33 
34 #ifndef __INCLUDE_MIST_ALLOC_H__
35 #define __INCLUDE_MIST_ALLOC_H__
36 
37 #include <cstring>
38 #include <memory>
39 
40 #ifndef __INCLUDE_MIST_CONF_H__
41 #include "mist_conf.h"
42 #endif
43 
44 #ifndef __INCLUDE_MIST_TYPE_TRAIT_H__
45 #include "type_trait.h"
46 #endif
47 
48 
49 // mist名前空間の始まり
51 
52 
53 
55 template < bool b >
57 {
67  template < class Allocator >
68  static typename Allocator::pointer allocate_objects1( Allocator &allocator, typename Allocator::size_type num )
69  {
70 #if _MIST_ALLOCATE_TEST_ != 0
71  ::std::cerr << "Normal Allocator" << ::std::endl;
72 #endif
73  typename Allocator::pointer ptr = allocator.allocate( num, 0 );
74  typename Allocator::value_type obj;
75  for( typename Allocator::size_type i = 0 ; i < num ; i++ ) allocator.construct( &( ptr[i] ), obj );
76  return( ptr );
77  }
78 
79 
90  template < class Allocator >
91  static typename Allocator::pointer allocate_objects2( Allocator &allocator, typename Allocator::size_type num, typename Allocator::const_reference obj )
92  {
93 #if _MIST_ALLOCATE_TEST_ != 0
94  ::std::cerr << "Normal Allocator" << ::std::endl;
95 #endif
96  typename Allocator::pointer ptr = allocator.allocate( num, 0 );
97  for( typename Allocator::size_type i = 0 ; i < num ; i++ ) allocator.construct( &( ptr[i] ), obj );
98  return( ptr );
99  }
100 
101 
112  template < class Allocator >
113  static typename Allocator::pointer allocate_objects3( Allocator &allocator, typename Allocator::const_pointer s, typename Allocator::const_pointer e )
114  {
115 #if _MIST_ALLOCATE_TEST_ != 0
116  ::std::cerr << "Normal Allocator" << ::std::endl;
117 #endif
118  typename Allocator::pointer ptr = allocator.allocate( e - s, 0 );
119  for( typename Allocator::pointer p = ptr ; s != e ; p++, s++ ) allocator.construct( p, *s );
120  return( ptr );
121  }
122 
123 
132  template < class Allocator >
133  static void deallocate_objects( Allocator &allocator, typename Allocator::pointer ptr, typename Allocator::size_type num )
134  {
135 #if _MIST_ALLOCATE_TEST_ != 0
136  ::std::cerr << "Normal Deallocator" << ::std::endl;
137 #endif
138  for( typename Allocator::size_type i = 0 ; i < num ; i++ ) allocator.destroy( &( ptr[i] ) );
139  allocator.deallocate( ptr, num );
140  }
141 
142 
154  template < class Allocator >
155  static typename Allocator::pointer copy_objects1( Allocator & /* allocator */, typename Allocator::const_pointer s, typename Allocator::const_pointer e, typename Allocator::pointer x )
156  {
157 #if _MIST_ALLOCATE_TEST_ != 0
158  ::std::cerr << "Normal Copy Function" << ::std::endl;
159 #endif
160  while( s != e )
161  {
162  *x = *s;
163  ++x;
164  ++s;
165  }
166  return( x );
167  }
168 
169 
181  template < class Allocator >
182  static typename Allocator::pointer copy_objects2( Allocator & /* allocator */, typename Allocator::const_pointer ptr, typename Allocator::size_type num, typename Allocator::pointer to )
183  {
184 #if _MIST_ALLOCATE_TEST_ != 0
185  ::std::cerr << "Normal Copy Function" << ::std::endl;
186 #endif
187  for( typename Allocator::size_type i = 0 ; i < num ; i++ ) to[i] = ptr[i];
188  return( to + num );
189  }
190 
191 
201  template < class Allocator >
202  static void fill_objects1( Allocator & /* allocator */, typename Allocator::pointer ptr, typename Allocator::size_type num, typename Allocator::const_reference obj )
203  {
204 #if _MIST_ALLOCATE_TEST_ != 0
205  ::std::cerr << "Normal Clean Function" << ::std::endl;
206 #endif
207  for( typename Allocator::size_type i = 0 ; i < num ; i++ ) ptr[i] = obj;
208  }
209 
210 
219  template < class Allocator >
220  static void fill_objects2( Allocator & /* allocator */, typename Allocator::pointer ptr, typename Allocator::size_type num )
221  {
222 #if _MIST_ALLOCATE_TEST_ != 0
223  ::std::cerr << "Normal Clean Function" << ::std::endl;
224 #endif
225  typename Allocator::value_type obj;
226  for( typename Allocator::size_type i = 0 ; i < num ; i++ ) ptr[i] = obj;
227  }
228 };
229 
230 
231 
232 
234 template <>
235 struct mist_memory_operator< true >
236 {
246  template < class Allocator >
247  static typename Allocator::pointer allocate_objects1( Allocator &allocator, typename Allocator::size_type num )
248  {
249 #if _MIST_ALLOCATE_TEST_ != 0
250  ::std::cerr << "Memset Allocator" << ::std::endl;
251 #endif
252  typename Allocator::pointer ptr = allocator.allocate( num, 0 );
253  ::memset( ptr, 0, num * sizeof( typename Allocator::value_type ) );
254  return( ptr );
255  }
256 
257 
268  template < class Allocator >
269  static typename Allocator::pointer allocate_objects2( Allocator &allocator, typename Allocator::size_type num, typename Allocator::const_reference obj )
270  {
271 #if _MIST_ALLOCATE_TEST_ != 0
272  ::std::cerr << "Specialized Allocator" << ::std::endl;
273 #endif
274  typename Allocator::pointer ptr = allocator.allocate( num, 0 );
275  for( typename Allocator::size_type i = 0 ; i < num ; i++ ) ptr[i] = obj;
276  return( ptr );
277  }
278 
279 
290  template < class Allocator >
291  static typename Allocator::pointer allocate_objects3( Allocator &allocator, typename Allocator::const_pointer s, typename Allocator::const_pointer e )
292  {
293 #if _MIST_ALLOCATE_TEST_ != 0
294  ::std::cerr << "Memcpy Allocator" << ::std::endl;
295 #endif
296  typename Allocator::pointer ptr = allocator.allocate( e - s, 0 );
297  memcpy( ptr, s, ( e - s ) * sizeof( typename Allocator::value_type ) );
298  return( ptr );
299  }
300 
301 
310  template < class Allocator >
311  static void deallocate_objects( Allocator &allocator, typename Allocator::pointer ptr, typename Allocator::size_type num )
312  {
313 #if _MIST_ALLOCATE_TEST_ != 0
314  ::std::cerr << "Specialized Deallocator" << ::std::endl;
315 #endif
316  allocator.deallocate( ptr, num );
317  }
318 
319 
331  template < class Allocator >
332  static typename Allocator::pointer copy_objects1( Allocator & /* allocator */, typename Allocator::const_pointer s, typename Allocator::const_pointer e, typename Allocator::pointer x )
333  {
334 #if _MIST_ALLOCATE_TEST_ != 0
335  ::std::cerr << "Memcpy Copy Function" << ::std::endl;
336 #endif
337  memcpy( x, s, ( e - s ) * sizeof( typename Allocator::value_type ) );
338  return( x + ( e - s ) );
339  }
340 
341 
353  template < class Allocator >
354  static typename Allocator::pointer copy_objects2( Allocator & /* allocator */, typename Allocator::const_pointer ptr, typename Allocator::size_type num, typename Allocator::pointer to )
355  {
356 #if _MIST_ALLOCATE_TEST_ != 0
357  ::std::cerr << "Memcpy Copy Function" << ::std::endl;
358 #endif
359  memcpy( to, ptr, num * sizeof( typename Allocator::value_type ) );
360  return( to + num );
361  }
362 
363 
373  template < class Allocator >
374  static void fill_objects1( Allocator & /* allocator */, typename Allocator::pointer ptr, typename Allocator::size_type num, typename Allocator::const_reference obj )
375  {
376 #if _MIST_ALLOCATE_TEST_ != 0
377  ::std::cerr << "Memcpy Clean Function" << ::std::endl;
378 #endif
379  memset( ptr, obj, num * sizeof( typename Allocator::value_type ) );
380  }
381 
382 
391  template < class Allocator >
392  static void fill_objects2( Allocator & /* allocator */, typename Allocator::pointer ptr, typename Allocator::size_type num )
393  {
394 #if _MIST_ALLOCATE_TEST_ != 0
395  ::std::cerr << "Memcpy Clean Function" << ::std::endl;
396 #endif
397  memset( ptr, 0, num * sizeof( typename Allocator::value_type ) );
398  }
399 };
400 
401 
402 
410 template < class T, class Allocator >
411 class mist_allocator : public Allocator
412 {
413 public:
414  typedef Allocator base;
415  typedef typename Allocator::reference reference;
416  typedef typename Allocator::const_reference const_reference;
417  typedef typename Allocator::value_type value_type;
418  typedef typename Allocator::size_type size_type;
419  typedef typename Allocator::difference_type difference_type;
420  typedef typename Allocator::pointer pointer;
421  typedef typename Allocator::const_pointer const_pointer;
422 
423 protected:
424  pointer shared_pointer; // 利用可能なメモリへのポインタ(外部とメモリを共有する場合のみ利用)
425  size_type shared_memory; // 利用可能なメモリ量(外部とメモリを共有する場合のみ利用)
426 
427 
428 public:
430  pointer allocate_objects( size_type num )
431  {
432  if( num == 0 || num > max_size( ) )
433  {
434  return( NULL );
435  }
436  else if( !is_memory_shared( ) )
437  {
438  // 自動でメモリを割り当てる場合
439  return( mist_memory_operator< is_builtin< T >::value >::allocate_objects1( *this, num ) );
440  }
441  else
442  {
443  // 外部割り当てのメモリを利用する場合
444  return( shared_pointer );
445  }
446  }
447 
449  pointer allocate_objects( size_type num, const_reference obj )
450  {
451  if( num == 0 || num > max_size( ) )
452  {
453  return( NULL );
454  }
455  else if( !is_memory_shared( ) )
456  {
457  // 自動でメモリを割り当てる場合
458  return( mist_memory_operator< is_builtin< T >::value >::allocate_objects2( *this, num, obj ) );
459  }
460  else
461  {
462  // 外部割り当てのメモリを利用する場合
463  mist_memory_operator< type_and< is_char< T >::value, is_builtin< T >::value >::value >::fill_objects1( *this, shared_pointer, num, obj );
464  return( shared_pointer );
465  }
466  }
467 
469  pointer allocate_objects( const_pointer s, const_pointer e )
470  {
471  if( s >= e || e - s > max_size( ) )
472  {
473  return( NULL );
474  }
475  else if( !is_memory_shared( ) )
476  {
477  // 自動でメモリを割り当てる場合
478  return( mist_memory_operator< is_builtin< T >::value >::allocate_objects3( *this, s, e ) );
479  }
480  else
481  {
482  // 外部割り当てのメモリを利用する場合
483  mist_memory_operator< type_and< is_char< T >::value, is_builtin< T >::value >::value >::copy_objects2( *this, s, e - s, shared_pointer );
484  return( shared_pointer );
485  }
486  }
487 
489  void deallocate_objects( pointer ptr, size_type num )
490  {
491  if( !is_memory_shared( ) )
492  {
493  // 自動でメモリを割り当てる場合
494  if( num <= 0 ) return;
495  mist_memory_operator< is_builtin< T >::value >::deallocate_objects( *this, ptr, num );
496  }
497  }
498 
500  pointer copy_objects( const_pointer s, const_pointer e, pointer x ) const
501  {
502  if( s >= e ) return( x );
503  return( mist_memory_operator< is_builtin< T >::value >::copy_objects1( *this, s, e, x ) );
504  }
505 
507  pointer copy_objects( const_pointer ptr, size_type num, pointer to ) const
508  {
509  if( num <= 0 ) return( to );
510  return( mist_memory_operator< is_builtin< T >::value >::copy_objects2( *this, ptr, num, to ) );
511  }
512 
514  void fill_objects( pointer ptr, size_type num, const_reference obj ) const
515  {
516  if( num <= 0 ) return;
517  mist_memory_operator< type_and< is_char< T >::value, is_builtin< T >::value >::value >::fill_objects1( *this, ptr, num, obj );
518  }
519 
521  void fill_objects( pointer ptr, size_type num ) const
522  {
523  if( num <= 0 ) return;
524  mist_memory_operator< is_builtin< T >::value >::fill_objects2( *this, ptr, num );
525  }
526 
531  pointer trim_objects( pointer ptr, size_type num, size_type dest_num )
532  {
533  if( num < dest_num ) return( ptr ); // 開放しようとしている配列の要素数は,トリム後の配列サイズよりサイズよりも小さい例外
534  //if( num < 0 ) return( NULL ); // トリム先の配列サイズが0より小さい例外
535  if( num == dest_num ) return( ptr ); // トリムによる変更の必要なし
536  if( num == 0 ) return( NULL );
537 
538  if( !is_memory_shared( ) )
539  {
540  // 自動でメモリを割り当てる場合
541 #if _MIST_ALLOCATOR_MEMORY_TRIM_ != 0
542  deallocate_objects( ptr + dest_num, num - dest_num );
543  fill_objects( ptr, dest_num );
544 #else
545  deallocate_objects( ptr, num );
546  ptr = allocate_objects( dest_num );
547 #endif
548  }
549  return( dest_num == 0 ? NULL : ptr );
550  }
551 
556  pointer trim_objects( pointer ptr, size_type num, size_type dest_num, const_reference obj )
557  {
558  if( num < dest_num ) return( ptr ); // 開放しようとしている配列の要素数は,トリム後の配列サイズよりサイズよりも小さい例外
559  if( num < 0 ) return( NULL ); // トリム先の配列サイズが0より小さい例外
560  if( num == dest_num ) return( ptr ); // トリムによる変更の必要なし
561  if( num == 0 ) return( NULL );
562 
563  if( !is_memory_shared( ) )
564  {
565  // 自動でメモリを割り当てる場合
566 #if _MIST_ALLOCATOR_MEMORY_TRIM_ != 0
567  deallocate_objects( ptr + dest_num, num - dest_num );
568  fill_objects( ptr, dest_num, obj );
569 #else
570  deallocate_objects( ptr, num );
571  ptr = allocate_objects( dest_num, obj );
572 #endif
573  }
574  return( dest_num == 0 ? NULL : ptr );
575  }
576 
578  size_type max_size( ) const
579  {
580  return( shared_memory == 0 ? base::max_size( ) : shared_memory );
581  }
582 
584  bool is_memory_shared( ) const
585  {
586  return( shared_memory != 0 );
587  }
588 
590  const Allocator &operator=( const Allocator &alloc )
591  {
592  if( &alloc != this )
593  {
594  // 外部メモリを利用しているかどうかは受け継がない
595  base::operator=( alloc );
596  }
597  return( *this );
598  }
599 
601  const mist_allocator &operator=( const mist_allocator &alloc )
602  {
603  if( &alloc != this )
604  {
605  // 外部メモリを利用しているかどうかは受け継がない
606  base::operator=( alloc );
607  }
608  return( *this );
609  }
610 
611 
613  mist_allocator( ) : base( ), shared_pointer( NULL ), shared_memory( 0 ){}
614 
615 
623  mist_allocator( pointer ptr, size_type mem_shared ) : base( ), shared_pointer( mem_shared == 0 ? NULL : ptr ), shared_memory( ptr == NULL ? 0 : mem_shared ){}
624 
625 
627  mist_allocator( const Allocator &alloc ) : base( alloc ), shared_pointer( NULL ), shared_memory( 0 ){}
628 
629 
631  mist_allocator( const mist_allocator &alloc ) : base( alloc ), shared_pointer( NULL ), shared_memory( 0 ){}
632 };
633 
634 
635 
636 // mist名前空間の終わり
637 _MIST_END
638 
639 #endif // __INCLUDE_MIST_ALLOC_H__
640 

Generated on Wed Nov 12 2014 19:44:20 for MIST by doxygen 1.8.1.2