- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

mist.h
説明を見る。
1 /****************************************************************************************************************************
2 ** MIST ( Media Integration Standard Toolkit )
3 **
4 ** We defined following template classes.
5 **
6 ** array : template class of one dimensionl array with STL support.
7 ** array1 : template class of one dimensionl array containing resolution.
8 ** array2 : template class of two dimensionl array containing pixel resolution.
9 ** array3 : template class of three dimensionl array containing voxel resolution.
10 ** matrix : template class of matrix with its operations, and impremented using expression template technique.
11 ** vector : template class of vector with its operations, and impremented using expression template technique.
12 **
13 **
14 ** We developed these programs since 2003/09/05.
15 **
16 ** $LastChangedDate:: 2011-04-26 13:10:24 #$
17 ** $LastChangedRevision: 1365 $
18 ** $LastChangedBy: ddeguchi $
19 ** $HeadURL: http://localhost/svn/mist/trunk/mist/mist.h $
20 **
21 **
22 ** Copyright MIST Project Team.
23 ** All Rights Reserved.
24 **
25 ****************************************************************************************************************************/
26
27 //
28 // Copyright (c) 2003-2011, MIST Project, Nagoya University
29 // All rights reserved.
30 //
31 // Redistribution and use in source and binary forms, with or without modification,
32 // are permitted provided that the following conditions are met:
33 //
34 // 1. Redistributions of source code must retain the above copyright notice,
35 // this list of conditions and the following disclaimer.
36 //
37 // 2. Redistributions in binary form must reproduce the above copyright notice,
38 // this list of conditions and the following disclaimer in the documentation
39 // and/or other materials provided with the distribution.
40 //
41 // 3. Neither the name of the Nagoya University nor the names of its contributors
42 // may be used to endorse or promote products derived from this software
43 // without specific prior written permission.
44 //
45 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
46 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
47 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
48 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
51 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
52 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 //
54
55
77
78 #ifndef __INCLUDE_MIST_H__
79 #define __INCLUDE_MIST_H__
80
81
82 #ifndef __INCLUDE_MIST_CONF_H__
83 #include "config/mist_conf.h"
84 #endif
85
86
87 #ifndef __INCLUDE_MIST_ALLOC_H__
88 #include "config/mist_alloc.h"
89 #endif
90
91 #ifndef __INCLUDE_MIST_ITERATOR_H__
92 #include "config/iterator.h"
93 #endif
94
95
96
97 // mist名前空間の始まり
98 _MIST_BEGIN
99
100
101
110 template < class T, class Allocator = std::allocator< T > >
111 class array
112 {
113 public:
114 typedef Allocator allocator_type;
115 typedef typename Allocator::reference reference;
116 typedef typename Allocator::const_reference const_reference;
117 typedef typename Allocator::value_type value_type;
118 typedef typename Allocator::size_type size_type;
119 typedef typename Allocator::difference_type difference_type;
120 typedef typename Allocator::pointer pointer;
121 typedef typename Allocator::const_pointer const_pointer;
122
124 typedef mist_iterator1< T, ptrdiff_t, pointer, reference > iterator;
125
127 typedef mist_iterator1< T, ptrdiff_t, const_pointer, const_reference > const_iterator;
128
130 typedef mist_reverse_iterator< mist_iterator1< T, ptrdiff_t, pointer, reference > > reverse_iterator;
131
133 typedef mist_reverse_iterator< mist_iterator1< T, ptrdiff_t, const_pointer, const_reference > > const_reverse_iterator;
134
136 template < class TT, class AAllocator = std::allocator< TT > >
137 struct rebind
138 {
139 typedef array< TT, AAllocator > other;
140 };
141
142
143 protected:
144 mist_allocator< T, Allocator > allocator_;
145
146 private:
147 size_type size_;
148
149 protected:
150 T* data_;
151
152 public:
169 bool resize( size_type num, size_type /* dmy1 */ = 0, size_type /* dmy2 */ = 0 )
170 {
171 if( size_ < num )
172 {
173 allocator_.deallocate_objects( data_, size_ );
174 data_ = allocator_.allocate_objects( num );
175 size_ = data_ == NULL ? 0 : num;
176 }
177 else if( size_ > num )
178 {
179 data_ = allocator_.trim_objects( data_, size_, num );
180 size_ = data_ == NULL ? 0 : num;
181 }
182
183 return( data_ != NULL );
184 }
185
197 bool trim( array &out, size_type index, difference_type num = -1 ) const
198 {
199 difference_type num_ = size( );
200 if( num_ <= static_cast< difference_type >( index ) || num_ < static_cast< difference_type >( index + num ) )
201 {
202 return( false );
203 }
204 else if( num_ == num )
205 {
206 out = *this;
207 return( true );
208 }
209
210 if( num < 0 )
211 {
212 num = size( ) - index;
213 }
214
215 if( out.resize( num ) )
216 {
217 allocator_.copy_objects( paccess( index ), num, out.paccess( 0 ) );
218 return( true );
219 }
220 else
221 {
222 return( false );
223 }
224 }
225
236 bool trim( size_type index, difference_type num = -1 )
237 {
238 if( is_memory_shared( ) )
239 {
240 // 外部メモリを利用している場合
241 array o( *this );
242 return( o.trim( *this, index, num ) );
243 }
244 else
245 {
246 difference_type num_ = size( );
247 if( num_ <= static_cast< difference_type >( index ) || num_ < static_cast< difference_type >( index + num ) )
248 {
249 return( false );
250 }
251 else if( num_ == num )
252 {
253 return( true );
254 }
255 else
256 {
257 array o( num );
258
259 if( this->trim( o, index, num ) )
260 {
261 swap( o );
262
263 return( true );
264 }
265 else
266 {
267 return( false );
268 }
269 }
270 }
271 }
272
273
285 bool swap( array &a )
286 {
287 if( is_memory_shared( ) || a.is_memory_shared( ) )
288 {
289 return( false );
290 }
291 else
292 {
293 size_type _dmy_size = size_;
294 size_ = a.size_;
295 a.size_ = _dmy_size;
296
297 value_type *dmy_data_ = data_;
298 data_ = a.data_;
299 a.data_ = dmy_data_;
300
301 return( true );
302 }
303 }
304
305
310 void clear( )
311 {
312 allocator_.deallocate_objects( data_, size_ );
313 size_ = 0;
314 data_ = NULL;
315 }
316
317
323 void fill( )
324 {
325 allocator_.fill_objects( data_, size_ );
326 }
327
328
335 void fill( const value_type &val )
336 {
337 allocator_.fill_objects( data_, size_, val );
338 }
339
340
346 bool empty( ) const { return( size_ == 0 ); }
347
348
349 size_type size( ) const { return( size_ ); }
350 size_type size1( ) const { return( size_ ); }
351 size_type size2( ) const { return( 1 ); }
352 size_type size3( ) const { return( 1 ); }
353 size_type width( ) const { return( size_ ); }
354 size_type height( ) const { return( 1 ); }
355 size_type depth( ) const { return( 1 ); }
356
357 double reso1( double /* r1 */ ){ return( 1.0 ); }
358 double reso1( ) const { return( 1.0 ); }
359 double reso2( double /* r2 */ ){ return( 1.0 ); }
360 double reso2( ) const { return( 1.0 ); }
361 double reso3( double /* r3 */ ){ return( 1.0 ); }
362 double reso3( ) const { return( 1.0 ); }
363
364
366 size_type byte( ) const { return( size_ * sizeof( value_type ) ); }
367
369 bool is_memory_shared( ) const { return( allocator_.is_memory_shared( ) ); }
370
371
384 iterator begin( ){ return( iterator( paccess( 0 ), 1 ) ); }
385
387 const_iterator begin( ) const { return( const_iterator( paccess( 0 ), 1 ) ); }
388
389
391 iterator end( ){ return( iterator( paccess( size( ) ), 1 ) ); }
392
394 const_iterator end( ) const { return( const_iterator( paccess( size( ) ), 1 ) ); }
395
396
397
410 reverse_iterator rbegin( ){ return( reverse_iterator( end( ) ) ); }
411
413 const_reverse_iterator rbegin( ) const { return( const_reverse_iterator( end( ) ) ); }
414
415
417 reverse_iterator rend( ){ return( reverse_iterator( begin( ) ) ); }
418
420 const_reverse_iterator rend( ) const { return( const_reverse_iterator( begin( ) ) ); }
421
422
424 size_type max_size( ) const { return( allocator_.max_size( ) ); }
425
426
427
428 private: // サポートしないＳＴＬの関数（実装・使用しちゃだめ）
429 iterator erase( iterator i );
430 iterator erase( iterator s, iterator e );
431 iterator insert( iterator i, const value_type &val );
432 void insert( iterator i, size_type num, const value_type &val );
433
434 public:
446 template < class TT, class AAlocator >
447 const array& operator =( const array< TT, AAlocator > &o )
448 {
449 if( size_ > o.size( ) )
450 {
451 data_ = allocator_.trim_objects( data_, size_, o.size( ) );
452 size_ = data_ == NULL ? 0 : o.size( );
453 }
454 else if( size_ < o.size( ) )
455 {
456 allocator_.deallocate_objects( data_, size_ );
457 data_ = allocator_.allocate_objects( o.size( ) );
458 size_ = data_ == NULL ? 0 : o.size( );
459 }
460
461 if( data_ != NULL )
462 {
463 for( size_type i = 0 ; i < size_ ; i++ )
464 {
465 data_[ i ] = static_cast< value_type >( o[ i ] );
466 }
467 }
468
469 return( *this );
470 }
471
482 const array& operator =( const array &o )
483 {
484 if( this == &o ) return( *this );
485
486 // まず，アロケータをコピーする
487 allocator_ = o.allocator_;
488
489 if( size_ > o.size_ )
490 {
491 data_ = allocator_.trim_objects( data_, size_, o.size_ );
492 size_ = data_ == NULL ? 0 : o.size( );
493 }
494 else if( size_ < o.size_ )
495 {
496 allocator_.deallocate_objects( data_, size_ );
497 data_ = allocator_.allocate_objects( o.size( ) );
498 size_ = data_ == NULL ? 0 : o.size( );
499 }
500
501 if( data_ != NULL )
502 {
503 allocator_.copy_objects( o.data_, size_, data_ );
504 }
505
506 return( *this );
507 }
508
509 // コンテナ内の要素へのアクセス演算子
510 protected:
517 pointer paccess( size_type index )
518 {
519 return( data_ + index );
520 }
521
528 const_pointer paccess( size_type index ) const
529 {
530 return( data_ + index );
531 }
532
533 public:
544 reference at( size_type index, size_type dmy1 = 0, size_type dmy2 = 0 )
545 {
546 _CHECK_ACCESS_VIOLATION1U_( index )
547 return( data_[ index ] );
548 }
549
550
561 const_reference at( size_type index, size_type dmy1 = 0, size_type dmy2 = 0 ) const
562 {
563 _CHECK_ACCESS_VIOLATION1U_( index )
564 return( data_[ index ] );
565 }
566
567
578 reference operator ()( size_type index, size_type dmy1 = 0, size_type dmy2 = 0 )
579 {
580 _CHECK_ACCESS_VIOLATION1U_( index )
581 return( data_[ index ] );
582 }
583
584
595 const_reference operator ()( size_type index, size_type dmy1 = 0, size_type dmy2 = 0 ) const
596 {
597 _CHECK_ACCESS_VIOLATION1U_( index )
598 return( data_[ index ] );
599 }
600
601
610 reference operator []( size_type index )
611 {
612 _CHECK_ACCESS_VIOLATION1U_( index )
613 return( data_[ index ] );
614 }
615
616
625 const_reference operator []( size_type index ) const
626 {
627 _CHECK_ACCESS_VIOLATION1U_( index )
628 return( data_[ index ] );
629 }
630
631 public:
633 array( ) : allocator_( ), size_( 0 ), data_( NULL ){}
634
636 explicit array( const Allocator &a ) : allocator_( a ), size_( 0 ), data_( NULL ){}
637
638
640 explicit array( size_type num ) : allocator_( ), size_( num ), data_( NULL )
641 {
642 data_ = allocator_.allocate_objects( size_ );
643 if( data_ == NULL ) size_ = 0;
644 }
646 array( size_type num, const Allocator &a ) : allocator_( a ), size_( num ), data_( NULL )
647 {
648 data_ = allocator_.allocate_objects( size_ );
649 if( data_ == NULL ) size_ = 0;
650 }
651
652
654 array( size_type num, const value_type &val ) : allocator_( ), size_( num ), data_( NULL )
655 {
656 data_ = allocator_.allocate_objects( size_, val );
657 if( data_ == NULL ) size_ = 0;
658 }
660 array( size_type num, const value_type &val, const Allocator &a ) : allocator_( a ), size_( num ), data_( NULL )
661 {
662 data_ = allocator_.allocate_objects( size_, val );
663 if( data_ == NULL ) size_ = 0;
664 }
665
666
668 array( const_iterator s, const_iterator e ) : allocator_( ), size_( e - s ), data_( NULL )
669 {
670 data_ = allocator_.allocate_objects( s, e );
671 if( data_ == NULL ) size_ = 0;
672 }
674 array( const_iterator s, const_iterator e, const Allocator &a ) : allocator_( a ), size_( e - s ), data_( NULL )
675 {
676 data_ = allocator_.allocate_objects( s, e );
677 if( data_ == NULL ) size_ = 0;
678 }
679
680
682 array( size_type num, pointer ptr, size_type mem_available ) : allocator_( ptr, mem_available ), size_( num ), data_( NULL )
683 {
684 data_ = allocator_.allocate_objects( size_ );
685 if( data_ == NULL ) size_ = 0;
686 }
688 array( size_type num, const value_type &val, pointer ptr, size_type mem_available ) : allocator_( ptr, mem_available ), size_( num ), data_( NULL )
689 {
690 data_ = allocator_.allocate_objects( size_, val );
691 if( data_ == NULL ) size_ = 0;
692 }
693
694
699 template < class TT, class AAlocator >
700 array( const array< TT, AAlocator > &o ) : allocator_( ), size_( o.size( ) ), data_( NULL )
701 {
702 data_ = allocator_.allocate_objects( size_ );
703 if( data_ == NULL )
704 {
705 size_ = 0;
706 }
707 else
708 {
709 for( size_type i = 0 ; i < size_ ; i++ ) data_[i] = static_cast< value_type >( o[i] );
710 }
711 }
712
714 array( const array< T, Allocator > &o ) : allocator_( o.allocator_ ), size_( o.size_ ), data_( NULL )
715 {
716 data_ = allocator_.allocate_objects( size_ );
717 if( data_ == NULL )
718 {
719 size_ = 0;
720 }
721 else
722 {
723 allocator_.copy_objects( o.data_, size_, data_ );
724 }
725 }
726
728 ~array( )
729 {
730 clear( );
731 }
732 };
733
734
735
744 template < class T, class Allocator = std::allocator< T > >
745 class array1 : public array< T, Allocator >
746 {
747 public:
748 typedef Allocator allocator_type;
749 typedef typename Allocator::reference reference;
750 typedef typename Allocator::const_reference const_reference;
751 typedef typename Allocator::value_type value_type;
752 typedef typename Allocator::size_type size_type;
753 typedef typename Allocator::difference_type difference_type;
754 typedef typename Allocator::pointer pointer;
755 typedef typename Allocator::const_pointer const_pointer;
756
758 typedef mist_iterator1< T, ptrdiff_t, pointer, reference > iterator;
759
761 typedef mist_iterator1< T, ptrdiff_t, const_pointer, const_reference > const_iterator;
762
764 typedef mist_reverse_iterator< mist_iterator1< T, ptrdiff_t, pointer, reference > > reverse_iterator;
765
767 typedef mist_reverse_iterator< mist_iterator1< T, ptrdiff_t, const_pointer, const_reference > > const_reverse_iterator;
768
770 template < class TT, class AAllocator = std::allocator< TT > >
771 struct rebind
772 {
773 typedef array1< TT, AAllocator > other;
774 };
775
776 private:
777 typedef array< T, Allocator > base;
778
779 protected:
780 double reso1_;
781
782 public:
783 double reso1( double r1 ){ return( reso1_ = r1 ); } //< @brief X軸方向の解像度を r1 に設定し，設定後の値を返す
784 double reso1( ) const { return( reso1_ ); } //< @brief X軸方向の解像度を返す
785 void reso( double r1, double /* dmy1 */ = 1.0, double /* dmy2 */ = 1.0 ){ reso1_ = r1; } //< @brief X軸方向の解像度を r1 に設定し，設定後の値を返す
786
787
788 /************************************************************************************************************
789 **
790 ** X方向に対する順方向・逆方向の反復子
791 **
792 ************************************************************************************************************/
793
806 iterator x_begin( ){ return( base::begin( ) ); }
807
809 const_iterator x_begin( ) const { return( base::begin( ) ); }
810
811
813 iterator x_end( ){ return( base::end( ) ); }
814
816 const_iterator x_end( ) const { return( base::end( ) ); }
817
818
819
832 reverse_iterator x_rbegin( ){ return( base::rbegin( ) ); }
833
835 const_reverse_iterator x_rbegin( ) const { return( base::rbegin( ) ); }
836
837
839 reverse_iterator x_rend( ){ return( base::rend( ) ); }
840
842 const_reverse_iterator x_rend( ) const { return( base::rend( ) ); }
843
844
845 public: // 配列に対する操作
846
856 bool trim( array1 &out, size_type index, difference_type num = -1 ) const
857 {
858 if( base::trim( out, index, num ) )
859 {
860 out.reso( reso1( ) );
861 return( true );
862 }
863 else
864 {
865 return( false );
866 }
867 }
868
877 bool trim( size_type index, difference_type num = -1 )
878 {
879 double r = reso1( );
880 if( base::trim( index, num ) )
881 {
882 reso( r );
883 return( true );
884 }
885 else
886 {
887 return( false );
888 }
889 }
890
891
903 bool swap( array1 &a )
904 {
905 if( base::swap( a ) )
906 {
907 double dmy_reso1_ = reso1_;
908 reso1_ = a.reso1_;
909 a.reso1_ = dmy_reso1_;
910 return( true );
911 }
912 else
913 {
914 return( false );
915 }
916 }
917
918 public:
929 template < class TT, class AAlocator >
930 const array1& operator =( const array1< TT, AAlocator > &o )
931 {
932 base::operator =( o );
933 reso1_ = o.reso1( );
934
935 return( *this );
936 }
937
938
948 const array1& operator =( const array1 &o )
949 {
950 if( this == &o ) return( *this );
951
952 base::operator =( o );
953 reso1_ = o.reso1_;
954
955 return( *this );
956 }
957
958 public:
960 array1( ) : base( ), reso1_( 1.0 ) {}
961
963 explicit array1( const Allocator &a ) : base( a ), reso1_( 1.0 ) {}
964
966 explicit array1( size_type num ) : base( num ), reso1_( 1.0 ) {}
967
968
970 array1( size_type num, double r1 ) : base( num ), reso1_( r1 ) {}
971
973 array1( size_type num, const Allocator &a ) : base( num, a ), reso1_( 1.0 ) {}
974
976 array1( size_type num, double r1, const Allocator &a ) : base( num, a ), reso1_( r1 ) {}
977
978
980 array1( size_type num, double r1, const value_type &val ) : base( num, val ), reso1_( r1 ) {}
981
983 array1( size_type num, const value_type &val, const Allocator &a ) : base( num, val, a ), reso1_( 1.0 ) {}
984
986 array1( size_type num, double r1, const value_type &val, const Allocator &a ) : base( num, val, a ), reso1_( r1 ) {}
987
988
990 array1( size_type num, pointer ptr, size_type mem_available ) : base( num, ptr, mem_available ), reso1_( 1.0 ) {}
991
993 array1( size_type num, double r1, pointer ptr, size_type mem_available ) : base( num, ptr, mem_available ), reso1_( r1 ) {}
994
996 array1( size_type num, double r1, const value_type &val, pointer ptr, size_type mem_available ) : base( num, val, ptr, mem_available ), reso1_( r1 ) {}
997
1002 template < class TT, class AAlocator >
1003 explicit array1( const array1< TT, AAlocator > &o ) : base( o ), reso1_( o.reso1( ) ) {}
1004
1006 array1( const array1< T, Allocator > &o ) : base( o ), reso1_( o.reso1_ ) {}
1007 };
1008
1009
1010
1019 template < class T, class Allocator = std::allocator< T > >
1020 class array2 : public array1< T, Allocator >
1021 {
1022 public:
1023 typedef Allocator allocator_type;
1024 typedef typename Allocator::reference reference;
1025 typedef typename Allocator::const_reference const_reference;
1026 typedef typename Allocator::value_type value_type;
1027 typedef typename Allocator::size_type size_type;
1028 typedef typename Allocator::difference_type difference_type;
1029 typedef typename Allocator::pointer pointer;
1030 typedef typename Allocator::const_pointer const_pointer;
1031
1033 typedef mist_iterator1< T, ptrdiff_t, pointer, reference > iterator;
1034
1036 typedef mist_iterator1< T, ptrdiff_t, const_pointer, const_reference > const_iterator;
1037
1039 typedef mist_reverse_iterator< mist_iterator1< T, ptrdiff_t, pointer, reference > > reverse_iterator;
1040
1042 typedef mist_reverse_iterator< mist_iterator1< T, ptrdiff_t, const_pointer, const_reference > > const_reverse_iterator;
1043
1045 template < class TT, class AAllocator = std::allocator< TT > >
1046 struct rebind
1047 {
1048 typedef array2< TT, AAllocator > other;
1049 };
1050
1051
1052 private:
1053 typedef array1< T, Allocator > base;
1054 size_type size2_;
1055 size_type size1_;
1056
1057 protected:
1058 double reso2_;
1059
1060 public:
1074 bool resize( size_type num1, size_type num2, size_type /* dmy1 */ = 0 )
1075 {
1076 if( base::resize( num1 * num2 ) )
1077 {
1078 size1_ = num1;
1079 size2_ = num2;
1080 return( true );
1081 }
1082 else
1083 {
1084 size1_ = size2_ = 0;
1085 return( false );
1086 }
1087 }
1088
1100 bool trim( array2 &out, size_type x, size_type y, difference_type w = -1, difference_type h = -1 ) const
1101 {
1102 difference_type w_ = width( );
1103 difference_type h_ = height( );
1104 if( w_ <= static_cast< difference_type >( x ) || w_ < static_cast< difference_type >( x + w ) )
1105 {
1106 return( false );
1107 }
1108 else if( h_ <= static_cast< difference_type >( y ) || h_ < static_cast< difference_type >( y + h ) )
1109 {
1110 return( false );
1111 }
1112 else if( w_ == w && h_ == h )
1113 {
1114 out = *this;
1115 return( true );
1116 }
1117
1118 if( w < 0 )
1119 {
1120 w = w_ - x;
1121 }
1122 if( h < 0 )
1123 {
1124 h = h_ - y;
1125 }
1126
1127 if( out.resize( w, h ) )
1128 {
1129 out.reso( base::reso1( ), base::reso2( ) );
1130
1131 const_pointer pi = paccess( x, y );
1132 pointer po = out.paccess( 0, 0 );
1133 for( difference_type j = 0 ; j < h ; j++ )
1134 {
1135 po = base::allocator_.copy_objects( pi, w, po );
1136 pi += this->width( );
1137 }
1138
1139 return( true );
1140 }
1141 else
1142 {
1143 return( false );
1144 }
1145 }
1146
1157 bool trim( size_type x, size_type y, difference_type w = -1, difference_type h = -1 )
1158 {
1159 if( base::is_memory_shared( ) )
1160 {
1161 // 外部メモリを利用している場合
1162 array2 o( *this );
1163 return( o.trim( *this, x, y, w, h ) );
1164 }
1165 else
1166 {
1167 difference_type w_ = this->width( );
1168 difference_type h_ = this->height( );
1169
1170 if( w_ <= static_cast< difference_type >( x ) || w_ < static_cast< difference_type >( x + w ) )
1171 {
1172 return( false );
1173 }
1174 else if( h_ <= static_cast< difference_type >( y ) || h_ < static_cast< difference_type >( y + h ) )
1175 {
1176 return( false );
1177 }
1178 else if( w_ == w && h_ == h )
1179 {
1180 return( true );
1181 }
1182 else
1183 {
1184 array2 o;
1185
1186 if( this->trim( o, x, y, w, h ) )
1187 {
1188 swap( o );
1189
1190 return( true );
1191 }
1192 else
1193 {
1194 return( false );
1195 }
1196 }
1197 }
1198 }
1199
1211 bool swap( array2 &a )
1212 {
1213 if( base::swap( a ) )
1214 {
1215 double dmy_reso2_ = reso2_;
1216 reso2_ = a.reso2_;
1217 a.reso2_ = dmy_reso2_;
1218
1219 size_type _dmy_size1 = size1_;
1220 size_type _dmy_size2 = size2_;
1221 size1_ = a.size1_;
1222 size2_ = a.size2_;
1223 a.size1_ = _dmy_size1;
1224 a.size2_ = _dmy_size2;
1225 return( true );
1226 }
1227 else
1228 {
1229 return( false );
1230 }
1231 }
1232
1233
1238 void clear( )
1239 {
1240 base::clear( );
1241 size1_ = size2_ = 0;
1242 }
1243
1244
1245 size_type size1( ) const { return( size1_ ); }
1246 size_type size2( ) const { return( size2_ ); }
1247 size_type width( ) const { return( size1_ ); }
1248 size_type height( ) const { return( size2_ ); }
1249
1250 double reso2( double r2 ){ return( reso2_ = r2 ); }
1251 double reso2( ) const { return( reso2_ ); }
1252
1259 void reso( double r1, double r2, double /* dmy */ = 1.0 ){ base::reso1_ = r1; reso2_ = r2; }
1260
1261
1262
1263 /************************************************************************************************************
1264 **
1265 ** X軸を固定した場合の順方向・逆方向の反復子
1266 **
1267 ************************************************************************************************************/
1268
1281 iterator x_begin( size_type i ){ return( iterator( paccess( i, 0 ), width( ) ) ); }
1282
1284 const_iterator x_begin( size_type i ) const { return( const_iterator( paccess( i, 0 ), width( ) ) ); }
1285
1287 iterator x_end( size_type i ){ return( iterator( paccess( i, height( ) ), width( ) ) ); }
1288
1290 const_iterator x_end( size_type i ) const { return( const_iterator( paccess( i, height( ) ), width( ) ) ); }
1291
1292
1305 reverse_iterator x_rbegin( size_type i ){ return( reverse_iterator( x_end( i ) ) ); }
1306
1308 const_reverse_iterator x_rbegin( size_type i ) const { return( const_reverse_iterator( x_end( i ) ) ); }
1309
1310
1312 reverse_iterator x_rend( size_type i ){ return( reverse_iterator( x_begin( i ) ) ); }
1313
1315 const_reverse_iterator x_rend( size_type i ) const { return( const_reverse_iterator( x_begin( i ) ) ); }
1316
1317 /************************************************************************************************************
1318 **
1319 ** Y軸を固定した場合の順方向・逆方向の反復子
1320 **
1321 ************************************************************************************************************/
1322
1335 iterator y_begin( size_type j ){ return( iterator( paccess( 0, j ), 1 ) ); }
1336
1338 const_iterator y_begin( size_type j ) const { return( const_iterator( paccess( 0, j ), 1 ) ); }
1339
1341 iterator y_end( size_type j ){ return( iterator( paccess( width( ), j ), 1 ) ); }
1342
1344 const_iterator y_end( size_type j ) const { return( const_iterator( paccess( width( ), j ), 1 ) ); }
1345
1346
1359 reverse_iterator y_rbegin( size_type j ){ return( reverse_iterator( y_end( j ) ) ); }
1360
1362 const_reverse_iterator y_rbegin( size_type j ) const { return( const_reverse_iterator( y_end( j ) ) ); }
1363
1365 reverse_iterator y_rend( size_type j ){ return( reverse_iterator( y_begin( j ) ) ); }
1366
1368 const_reverse_iterator y_rend( size_type j ) const { return( const_reverse_iterator( y_begin( j ) ) ); }
1369
1370
1371 public:
1382 template < class TT, class AAlocator >
1383 const array2& operator =( const array2< TT, AAlocator > &o )
1384 {
1385 base::operator =( o );
1386
1387 if( base::empty( ) )
1388 {
1389 size1_ = size2_ = 0;
1390 }
1391 else
1392 {
1393 size1_ = o.size1( );
1394 size2_ = o.size2( );
1395 }
1396
1397 reso2_ = o.reso2( );
1398
1399 return( *this );
1400 }
1401
1402
1412 const array2& operator =( const array2 &o )
1413 {
1414 if( this == &o ) return( *this );
1415
1416 base::operator =( o );
1417
1418 if( base::empty( ) )
1419 {
1420 size1_ = size2_ = 0;
1421 }
1422 else
1423 {
1424 size1_ = o.size1( );
1425 size2_ = o.size2( );
1426 }
1427
1428 reso2_ = o.reso2( );
1429
1430 return( *this );
1431 }
1432
1433 // 要素へのアクセス
1434 protected:
1442 pointer paccess( size_type i, size_type j )
1443 {
1444 return( base::data_ + i + j * size1_ );
1445 }
1446
1454 const_pointer paccess( size_type i, size_type j ) const
1455 {
1456 return( base::data_ + i + j * size1_ );
1457 }
1458
1459 public:
1470 reference at( size_type i, size_type j, size_type dmy = 0 )
1471 {
1472 _CHECK_ACCESS_VIOLATION2U_( i, j )
1473 return( base::data_[ i + j * size1_ ] );
1474 }
1475
1476
1487 const_reference at( size_type i, size_type j, size_type dmy = 0 ) const
1488 {
1489 _CHECK_ACCESS_VIOLATION2U_( i, j )
1490 return( base::data_[ i + j * size1_ ] );
1491 }
1492
1493
1504 reference operator ()( size_type i, size_type j, size_type /* dmy */ = 0 )
1505 {
1506 _CHECK_ACCESS_VIOLATION2U_( i, j )
1507 return( base::data_[ i + j * size1_ ] );
1508 }
1509
1510
1521 const_reference operator ()( size_type i, size_type j, size_type /* dmy */ = 0 ) const
1522 {
1523 _CHECK_ACCESS_VIOLATION2U_( i, j )
1524 return( base::data_[ i + j * size1_ ] );
1525 }
1526
1527
1528 public:
1530 array2( ) : base( ), size2_( 0 ), size1_( 0 ), reso2_( 1.0 ) {}
1531
1533 explicit array2( const Allocator &a ) : base( a ), size2_( 0 ), size1_( 0 ), reso2_( 1.0 ) {}
1534
1536 array2( size_type num1, size_type num2 ) : base( num1 * num2 ), size2_( num2 ), size1_( num1 ), reso2_( 1.0 )
1537 {
1538 if( base::empty( ) ) size1_ = size2_ = 0;
1539 }
1540
1541
1543 array2( size_type num1, size_type num2, double r1, double r2 ) : base( num1 * num2, r1 ), size2_( num2 ), size1_( num1 ), reso2_( r2 )
1544 {
1545 if( base::empty( ) ) size1_ = size2_ = 0;
1546 }
1547
1549 array2( size_type num1, size_type num2, const Allocator &a ) : base( num1 * num2, a ), size2_( num2 ), size1_( num1 ), reso2_( 1.0 )
1550 {
1551 if( base::empty( ) ) size1_ = size2_ = 0;
1552 }
1553
1555 array2( size_type num1, size_type num2, double r1, double r2, const Allocator &a ) : base( num1 * num2, r1, a ), size2_( num2 ), size1_( num1 ), reso2_( r2 )
1556 {
1557 if( base::empty( ) ) size1_ = size2_ = 0;
1558 }
1559
1560
1562 array2( size_type num1, size_type num2, const value_type &val ) : base( num1 * num2, 1.0, val ), size2_( num2 ), size1_( num1 ), reso2_( 1.0 )
1563 {
1564 if( base::empty( ) ) size1_ = size2_ = 0;
1565 }
1566
1568 array2( size_type num1, size_type num2, double r1, double r2, const value_type &val ) : base( num1 * num2, r1, val ), size2_( num2 ), size1_( num1 ), reso2_( r2 )
1569 {
1570 if( base::empty( ) ) size1_ = size2_ = 0;
1571 }
1572
1574 array2( size_type num1, size_type num2, const value_type &val, const Allocator &a ) : base( num1 * num2, val, a ), size2_( num2 ), size1_( num1 ), reso2_( 1.0 )
1575 {
1576 if( base::empty( ) ) size1_ = size2_ = 0;
1577 }
1578
1580 array2( size_type num1, size_type num2, double r1, double r2, const value_type &val, const Allocator &a ) : base( num1 * num2, r1, val, a ), size2_( num2 ), size1_( num1 ), reso2_( r2 )
1581 {
1582 if( base::empty( ) ) size1_ = size2_ = 0;
1583 }
1584
1585
1587 array2( size_type num1, size_type num2, pointer ptr, size_type mem_available ) : base( num1 * num2, ptr, mem_available ), size2_( num2 ), size1_( num1 ), reso2_( 1.0 )
1588 {
1589 if( base::empty( ) ) size1_ = size2_ = 0;
1590 }
1591
1593 array2( size_type num1, size_type num2, double r1, double r2, pointer ptr, size_type mem_available ) : base( num1 * num2, r1, ptr, mem_available ), size2_( num2 ), size1_( num1 ), reso2_( r2 )
1594 {
1595 if( base::empty( ) ) size1_ = size2_ = 0;
1596 }
1597
1599 array2( size_type num1, size_type num2, double r1, double r2, const value_type &val, pointer ptr, size_type mem_available ) : base( num1 * num2, r1, val, ptr, mem_available ), size2_( num2 ), size1_( num1 ), reso2_( r2 )
1600 {
1601 if( base::empty( ) ) size1_ = size2_ = 0;
1602 }
1603
1604
1605
1610 template < class TT, class AAlocator >
1611 array2( const array2< TT, AAlocator > &o ) : base( o ), size2_( o.size2( ) ), size1_( o.size1( ) ), reso2_( o.reso2( ) )
1612 {
1613 if( base::empty( ) ) size1_ = size2_ = 0;
1614 }
1615
1617 array2( const array2< T, Allocator > &o ) : base( o ), size2_( o.size2_ ), size1_( o.size1_ ), reso2_( o.reso2_ )
1618 {
1619 if( base::empty( ) ) size1_ = size2_ = 0;
1620 }
1621 };
1622
1623
1624
1625
1626
1635 template < class T, class Allocator = std::allocator< T > >
1636 class array3 : public array2< T, Allocator >
1637 {
1638 public:
1639 typedef Allocator allocator_type;
1640 typedef typename Allocator::reference reference;
1641 typedef typename Allocator::const_reference const_reference;
1642 typedef typename Allocator::value_type value_type;
1643 typedef typename Allocator::size_type size_type;
1644 typedef typename Allocator::difference_type difference_type;
1645 typedef typename Allocator::pointer pointer;
1646 typedef typename Allocator::const_pointer const_pointer;
1647
1649 typedef mist_iterator2< T, ptrdiff_t, pointer, reference > iterator;
1650
1652 typedef mist_iterator2< T, ptrdiff_t, const_pointer, const_reference > const_iterator;
1653
1655 typedef mist_reverse_iterator< mist_iterator2< T, ptrdiff_t, pointer, reference > > reverse_iterator;
1656
1658 typedef mist_reverse_iterator< mist_iterator2< T, ptrdiff_t, const_pointer, const_reference > > const_reverse_iterator;
1659
1661 template < class TT, class AAllocator = std::allocator< TT > >
1662 struct rebind
1663 {
1664 typedef array3< TT, AAllocator > other;
1665 };
1666
1667
1668 private:
1669 typedef array2< T, Allocator > base;
1670 size_type size3_;
1671 size_type size2_;
1672 size_type size1_;
1673
1674 protected:
1675 double reso3_;
1676
1677 public:
1692 bool resize( size_type num1, size_type num2, size_type num3 )
1693 {
1694 if( base::resize( num1 * num2, num3 ) )
1695 {
1696 size1_ = num1;
1697 size2_ = num2;
1698 size3_ = num3;
1699 return( true );
1700 }
1701 else
1702 {
1703 size1_ = size2_ = size3_ = 0;
1704 return( false );
1705 }
1706 }
1707
1721 bool trim( array3 &out, size_type x, size_type y, size_type z, difference_type w = -1, difference_type h = -1, difference_type d = -1 ) const
1722 {
1723 difference_type w_ = width( );
1724 difference_type h_ = height( );
1725 difference_type d_ = depth( );
1726 if( w_ <= static_cast< difference_type >( x ) || w_ < static_cast< difference_type >( x + w ) )
1727 {
1728 return( false );
1729 }
1730 else if( h_ <= static_cast< difference_type >( y ) || h_ < static_cast< difference_type >( y + h ) )
1731 {
1732 return( false );
1733 }
1734 else if( d_ <= static_cast< difference_type >( z ) || d_ < static_cast< difference_type >( z + d ) )
1735 {
1736 return( false );
1737 }
1738 else if( w_ == w && h_ == h && d_ == d )
1739 {
1740 out = *this;
1741 return( true );
1742 }
1743
1744 if( w < 0 )
1745 {
1746 w = w_ - x;
1747 }
1748 if( h < 0 )
1749 {
1750 h = h_ - y;
1751 }
1752 if( d < 0 )
1753 {
1754 d = d_ - z;
1755 }
1756
1757 if( out.resize( w, h, d ) )
1758 {
1759 out.reso( base::reso1( ), base::reso2( ), reso3( ) );
1760
1761 const_pointer pi = paccess( x, y, z );
1762 pointer po = out.paccess( 0, 0, 0 );
1763 size_type s1 = paccess( x, y + 1, z ) - pi;
1764 size_type s2 = paccess( x, y, z + 1 ) - paccess( x, y + h, z );
1765
1766 for( difference_type k = 0 ; k < d ; k++ )
1767 {
1768 for( difference_type j = 0 ; j < h ; j++ )
1769 {
1770 po = base::allocator_.copy_objects( pi, w, po );
1771 pi += s1;
1772 }
1773
1774 pi += s2;
1775 }
1776
1777 return( true );
1778 }
1779 else
1780 {
1781 return( false );
1782 }
1783 }
1784
1797 bool trim( size_type x, size_type y, size_type z, difference_type w = -1, difference_type h = -1, difference_type d = -1 )
1798 {
1799 if( base::is_memory_shared( ) )
1800 {
1801 // 外部メモリを利用している場合
1802 array3 o( *this );
1803 return( o.trim( *this, x, y, z, w, h, d ) );
1804 }
1805 else
1806 {
1807 difference_type w_ = this->width( );
1808 difference_type h_ = this->height( );
1809 difference_type d_ = this->depth( );
1810 if( w_ <= static_cast< difference_type >( x ) || w_ < static_cast< difference_type >( x + w ) )
1811 {
1812 return( false );
1813 }
1814 else if( h_ <= static_cast< difference_type >( y ) || h_ < static_cast< difference_type >( y + h ) )
1815 {
1816 return( false );
1817 }
1818 else if( d_ <= static_cast< difference_type >( z ) || d_ < static_cast< difference_type >( z + d ) )
1819 {
1820 return( false );
1821 }
1822 else if( w_ == w && h_ == h && d_ == d )
1823 {
1824 return( true );
1825 }
1826 else
1827 {
1828 array3 o;
1829
1830 if( this->trim( o, x, y, z, w, h, d ) )
1831 {
1832 swap( o );
1833
1834 return( true );
1835 }
1836 else
1837 {
1838 return( false );
1839 }
1840 }
1841 }
1842 }
1843
1855 bool swap( array3 &a )
1856 {
1857 if( base::swap( a ) )
1858 {
1859 double dmy_reso3_ = reso3_;
1860 reso3_ = a.reso3_;
1861 a.reso3_ = dmy_reso3_;
1862
1863 size_type _dmy_size1 = size1_;
1864 size_type _dmy_size2 = size2_;
1865 size_type _dmy_size3 = size3_;
1866 size1_ = a.size1_;
1867 size2_ = a.size2_;
1868 size3_ = a.size3_;
1869 a.size1_ = _dmy_size1;
1870 a.size2_ = _dmy_size2;
1871 a.size3_ = _dmy_size3;
1872
1873 return( true );
1874 }
1875 else
1876 {
1877 return( true );
1878 }
1879 }
1880
1881
1886 void clear( )
1887 {
1888 base::clear( );
1889 size1_ = size2_ = size3_ = 0;
1890 }
1891
1892
1893 size_type size1( ) const { return( size1_ ); }
1894 size_type size2( ) const { return( size2_ ); }
1895 size_type size3( ) const { return( size3_ ); }
1896 size_type width( ) const { return( size1_ ); }
1897 size_type height( ) const { return( size2_ ); }
1898 size_type depth( ) const { return( size3_ ); }
1899
1900 double reso3( double r3 ){ return( reso3_ = r3 ); }
1901 double reso3( ) const { return( reso3_ ); }
1902
1909 void reso( double r1, double r2, double r3 ){ base::reso1_ = r1; base::reso2_ = r2; reso3_ = r3; }
1910
1911
1912
1925 iterator begin( ){ return( iterator( paccess( 0, 0, 0 ), 0, base::size( ), 0 ) ); }
1926
1928 const_iterator begin( ) const { return( const_iterator( paccess( 0, 0, 0 ), 0, base::size( ), 0 ) ); }
1929
1931 iterator end( ){ return( iterator( paccess( 0, 0, 0 ), base::size( ), base::size( ), 0 ) ); }
1932
1934 const_iterator end( ) const { return( const_iterator( paccess( 0, 0, 0 ), base::size( ), base::size( ), 0 ) ); }
1935
1936
1949 reverse_iterator rbegin( ){ return( reverse_iterator( end( ) ) ); }
1950
1952 const_reverse_iterator rbegin( ) const { return( const_reverse_iterator( end( ) ) ); }
1953
1955 reverse_iterator rend( ){ return( reverse_iterator( begin( ) ) ); }
1956
1958 const_reverse_iterator rend( ) const { return( const_reverse_iterator( begin( ) ) ); }
1959
1960 /************************************************************************************************************
1961 **
1962 ** X軸を固定した場合の順方向・逆方向の反復子
1963 **
1964 ************************************************************************************************************/
1965
1978 iterator x_begin( size_type i ){ return( iterator( paccess( i, 0, 0 ), 0, 1, width( ) ) ); }
1979
1981 const_iterator x_begin( size_type i ) const { return( const_iterator( paccess( i, 0, 0 ), 0, 1, width( ) ) ); }
1982
1984 iterator x_end( size_type i ){ return( iterator( paccess( i, 0, 0 ), height( ) * depth( ), 1, width( ) ) ); }
1985
1987 const_iterator x_end( size_type i ) const { return( const_iterator( paccess( i, 0, 0 ), height( ) * depth( ), 1, width( ) ) ); }
1988
1989
1990
2003 reverse_iterator x_rbegin( size_type i ){ return( reverse_iterator( x_end( i ) ) ); }
2004
2006 const_reverse_iterator x_rbegin( size_type i ) const { return( const_reverse_iterator( x_end( i ) ) ); }
2007
2009 reverse_iterator x_rend( size_type i ){ return( reverse_iterator( x_begin( i ) ) ); }
2010
2012 const_reverse_iterator x_rend( size_type i ) const { return( const_reverse_iterator( x_begin( i ) ) ); }
2013
2014
2015 /************************************************************************************************************
2016 **
2017 ** Y軸を固定した場合の順方向・逆方向の反復子
2018 **
2019 ************************************************************************************************************/
2020
2033 iterator y_begin( size_type j ){ return( iterator( paccess( 0, j, 0 ), 0, height( ), width( ) * height( ) ) ); }
2034
2036 const_iterator y_begin( size_type j ) const { return( const_iterator( paccess( 0, j, 0 ), 0, height( ), width( ) * height( ) ) ); }
2037
2039 iterator y_end( size_type j ){ return( iterator( paccess( 0, j, 0 ), width( ) * depth( ), height( ), width( ) * height( ) ) ); }
2040
2042 const_iterator y_end( size_type j ) const { return( const_iterator( paccess( 0, j, 0 ), width( ) * depth( ), height( ), width( ) * height( ) ) ); }
2043
2044
2057 reverse_iterator y_rbegin( size_type j ){ return( reverse_iterator( y_end( j ) ) ); }
2058
2060 const_reverse_iterator y_rbegin( size_type j ) const { return( const_reverse_iterator( y_end( j ) ) ); }
2061
2063 reverse_iterator y_rend( size_type j ){ return( reverse_iterator( y_begin( j ) ) ); }
2064
2066 const_reverse_iterator y_rend( size_type j ) const { return( const_reverse_iterator( y_begin( j ) ) ); }
2067
2068
2069 /************************************************************************************************************
2070 **
2071 ** Z軸を固定した場合の順方向・逆方向の反復子
2072 **
2073 ************************************************************************************************************/
2074
2087 iterator z_begin( size_type k ){ return( iterator( paccess( 0, 0, k ), 0, 1, 1 ) ); }
2088
2090 const_iterator z_begin( size_type k ) const { return( const_iterator( paccess( 0, 0, k ), 0, 1, 1 ) ); }
2091
2093 iterator z_end( size_type k ){ return( iterator( paccess( 0, 0, k ), width( ) * height( ), 1, 1 ) ); }
2094
2096 const_iterator z_end( size_type k ) const { return( const_iterator( paccess( 0, 0, k ), width( ) * height( ), 1, 1 ) ); }
2097
2098
2111 reverse_iterator z_rbegin( size_type k ){ return( reverse_iterator( z_end( k ) ) ); }
2112
2114 const_reverse_iterator z_rbegin( size_type k ) const { return( const_reverse_iterator( z_end( k )) ); }
2115
2117 reverse_iterator z_rend( size_type k ){ return( reverse_iterator( z_begin( k ) ) ); }
2118
2120 const_reverse_iterator z_rend( size_type k ) const { return( const_reverse_iterator( z_begin( k ) ) ); }
2121
2122
2123 public:
2134 template < class TT, class AAlocator >
2135 const array3& operator =( const array3< TT, AAlocator > &o )
2136 {
2137 base::operator =( o );
2138
2139 if( base::empty( ) )
2140 {
2141 size1_ = size2_ = size3_ = 0;
2142 }
2143 else
2144 {
2145 size1_ = o.size1( );
2146 size2_ = o.size2( );
2147 size3_ = o.size3( );
2148 }
2149
2150 reso3_ = o.reso3( );
2151
2152 return( *this );
2153 }
2154
2155
2165 const array3& operator =( const array3 &o )
2166 {
2167 if( this == &o ) return( *this );
2168
2169 base::operator =( o );
2170
2171 if( base::empty( ) )
2172 {
2173 size1_ = size2_ = size3_ = 0;
2174 }
2175 else
2176 {
2177 size1_ = o.size1( );
2178 size2_ = o.size2( );
2179 size3_ = o.size3( );
2180 }
2181
2182 reso3_ = o.reso3( );
2183
2184 return( *this );
2185 }
2186
2187
2188 // 要素へのアクセス
2189 protected:
2198 pointer paccess( size_type i, size_type j, size_type k )
2199 {
2200 return( base::data_ + i + ( j + k * size2_ ) * size1_ );
2201 }
2202
2211 const_pointer paccess( size_type i, size_type j, size_type k ) const
2212 {
2213 return( base::data_ + i + ( j + k * size2_ ) * size1_ );
2214 }
2215
2216 public:
2227 reference at( size_type i, size_type j, size_type k )
2228 {
2229 _CHECK_ACCESS_VIOLATION3U_( i, j, k )
2230 return( base::data_[ i + ( j + k * size2_ ) * size1_ ] );
2231 }
2232
2233
2244 const_reference at( size_type i, size_type j, size_type k ) const
2245 {
2246 _CHECK_ACCESS_VIOLATION3U_( i, j, k )
2247 return( base::data_[ i + ( j + k * size2_ ) * size1_ ] );
2248 }
2249
2250
2261 reference operator ()( size_type i, size_type j, size_type k )
2262 {
2263 _CHECK_ACCESS_VIOLATION3U_( i, j, k )
2264 return( base::data_[ i + ( j + k * size2_ ) * size1_ ] );
2265 }
2266
2267
2278 const_reference operator ()( size_type i, size_type j, size_type k ) const
2279 {
2280 _CHECK_ACCESS_VIOLATION3U_( i, j, k )
2281 return( base::data_[ i + ( j + k * size2_ ) * size1_ ] );
2282 }
2283
2284
2285 public:
2287 array3( ) : base( ), size3_( 0 ), size2_( 0 ), size1_( 0 ), reso3_( 1.0 ) {}
2288
2290 explicit array3( const Allocator &a ) : base( a ), size3_( 0 ), size2_( 0 ), size1_( 0 ), reso3_( 1.0 ) {}
2291
2293 array3( size_type num1, size_type num2, size_type num3 ) : base( num1 * num2, num3 ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( 1.0 )
2294 {
2295 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2296 }
2297
2299 array3( size_type num1, size_type num2, size_type num3, double r1, double r2, double r3 ) : base( num1 * num2, num3, r1, r2 ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( r3 )
2300 {
2301 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2302 }
2303
2305 array3( size_type num1, size_type num2, size_type num3, const Allocator &a ) : base( num1 * num2, num3, a ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( 1.0 )
2306 {
2307 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2308 }
2309
2311 array3( size_type num1, size_type num2, size_type num3, double r1, double r2, double r3, const Allocator &a ) : base( num1 * num2, num3, r1, r2, a ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( r3 )
2312 {
2313 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2314 }
2315
2316
2318 array3( size_type num1, size_type num2, size_type num3, const value_type &val ) : base( num1 * num2, num3, val ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( 1.0 )
2319 {
2320 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2321 }
2322
2324 array3( size_type num1, size_type num2, size_type num3, double r1, double r2, double r3, const value_type &val ) : base( num1 * num2, num3, r1, r2, val ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( r3 )
2325 {
2326 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2327 }
2328
2330 array3( size_type num1, size_type num2, size_type num3, const value_type &val, const Allocator &a ) : base( num1 * num2, num3, val, a ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( 1.0 )
2331 {
2332 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2333 }
2334
2336 array3( size_type num1, size_type num2, size_type num3, double r1, double r2, double r3, const value_type &val, const Allocator &a ) : base( num1 * num2, num3, r1, r2, val, a ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( r3 )
2337 {
2338 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2339 }
2340
2341
2342
2344 array3( size_type num1, size_type num2, size_type num3, pointer ptr, size_type mem_available ) : base( num1 * num2, num3, ptr, mem_available ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( 1.0 )
2345 {
2346 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2347 }
2348
2350 array3( size_type num1, size_type num2, size_type num3, double r1, double r2, double r3, pointer ptr, size_type mem_available ) : base( num1 * num2, num3, r1, r2, ptr, mem_available ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( r3 )
2351 {
2352 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2353 }
2354
2356 array3( size_type num1, size_type num2, size_type num3, double r1, double r2, double r3, const value_type &val, pointer ptr, size_type mem_available ) : base( num1 * num2, num3, r1, r2, val, ptr, mem_available ), size3_( num3 ), size2_( num2 ), size1_( num1 ), reso3_( r3 )
2357 {
2358 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2359 }
2360
2361
2362
2367 template < class TT, class AAlocator >
2368 array3( const array3< TT, AAlocator > &o ) : base( o ), size3_( o.size3( ) ), size2_( o.size2( ) ), size1_( o.size1( ) ), reso3_( o.reso3( ) )
2369 {
2370 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2371 }
2372
2374 array3( const array3< T, Allocator > &o ) : base( o ), size3_( o.size3_ ), size2_( o.size2_ ), size1_( o.size1_ ), reso3_( o.reso3_ )
2375 {
2376 if( base::empty( ) ) size1_ = size2_ = size3_ = 0;
2377 }
2378 };
2379
2380
2381
2382
2390 template < class Array >
2391 class marray : public Array
2392 {
2393 public:
2394 typedef typename Array::allocator_type allocator_type;
2395 typedef typename Array::reference reference;
2396 typedef typename Array::const_reference const_reference;
2397 typedef typename Array::value_type value_type;
2398 typedef typename Array::size_type size_type;
2399 typedef typename Array::difference_type difference_type;
2400 typedef typename Array::pointer pointer;
2401 typedef typename Array::const_pointer const_pointer;
2402
2403 typedef typename Array::iterator iterator;
2404 typedef typename Array::const_iterator const_iterator;
2405 typedef typename Array::reverse_iterator reverse_iterator;
2406 typedef typename Array::const_reverse_iterator const_reverse_iterator;
2407
2408
2409 protected:
2410 typedef Array base;
2411 size_type margin1_;
2412 size_type margin2_;
2413 size_type margin3_;
2414
2415 public:
2425 bool resize( size_type num1 )
2426 {
2427 return( base::resize( num1 + margin1_ * 2 ) );
2428 }
2429
2430
2444 bool resize( size_type num1, size_type num2 )
2445 {
2446 return( base::resize( num1 + margin1_ * 2, num2 + margin2_ * 2 ) );
2447 }
2448
2449
2464 bool resize( size_type num1, size_type num2, size_type num3 )
2465 {
2466 return( base::resize( num1 + margin1_ * 2, num2 + margin2_ * 2, num3 + margin3_ * 2 ) );
2467 }
2468
2469
2470
2482 bool swap( marray &a )
2483 {
2484 if( base::swap( a ) )
2485 {
2486 size_type tmp = margin1_;
2487 margin1_ = a.margin1_;
2488 a.margin1_ = tmp;
2489
2490 tmp = margin2_;
2491 margin2_ = a.margin2_;
2492 a.margin2_ = tmp;
2493
2494 tmp = margin3_;
2495 margin3_ = a.margin3_;
2496 a.margin3_ = tmp;
2497
2498 return( true );
2499 }
2500 else
2501 {
2502 return( false );
2503 }
2504 }
2505
2506
2511 void clear( )
2512 {
2513 base::clear( );
2514 margin1_ = margin2_ = margin3_ = 0;
2515 }
2516
2517
2524 void fill_margin( const value_type &val = value_type( ) )
2525 {
2526 if( !base::empty( ) )
2527 {
2528 base &o = *this;
2529
2530 size_type i, j, k;
2531 for( k = 0 ; k < margin3( ) ; k++ )
2532 {
2533 for( j = 0 ; j < o.size2( ) ; j++ )
2534 {
2535 for( i = 0 ; i < o.size1( ) ; i++ )
2536 {
2537 o( i, j, k ) = val;
2538 }
2539 }
2540 }
2541 for( k = o.size3( ) - margin3( ) ; k < o.size3( ) ; k++ )
2542 {
2543 for( j = 0 ; j < o.size2( ) ; j++ )
2544 {
2545 for( i = 0 ; i < o.size1( ) ; i++ )
2546 {
2547 o( i, j, k ) = val;
2548 }
2549 }
2550 }
2551
2552 for( j = 0 ; j < margin2( ) ; j++ )
2553 {
2554 for( k = 0 ; k < o.size3( ) ; k++ )
2555 {
2556 for( i = 0 ; i < o.size1( ) ; i++ )
2557 {
2558 o( i, j, k ) = val;
2559 }
2560 }
2561 }
2562 for( j = o.size2( ) - margin2( ) ; j < o.size2( ) ; j++ )
2563 {
2564 for( k = 0 ; k < o.size3( ) ; k++ )
2565 {
2566 for( i = 0 ; i < o.size1( ) ; i++ )
2567 {
2568 o( i, j, k ) = val;
2569 }
2570 }
2571 }
2572
2573 for( i = 0 ; i < margin1( ) ; i++ )
2574 {
2575 for( k = 0 ; k < o.size3( ) ; k++ )
2576 {
2577 for( j = 0 ; j < o.size2( ) ; j++ )
2578 {
2579 o( i, j, k ) = val;
2580 }
2581 }
2582 }
2583 for( i = o.size1( ) - margin1( ) ; i < o.size1( ) ; i++ )
2584 {
2585 for( k = 0 ; k < o.size3( ) ; k++ )
2586 {
2587 for( j = 0 ; j < o.size2( ) ; j++ )
2588 {
2589 o( i, j, k ) = val;
2590 }
2591 }
2592 }
2593 }
2594 }
2595
2596
2597 size_type size1( ) const { return( base::empty( ) ? 0 : base::size1( ) - 2 * margin1_ ); }
2598 size_type size2( ) const { return( base::empty( ) ? 0 : base::size2( ) - 2 * margin2_ ); }
2599 size_type size3( ) const { return( base::empty( ) ? 0 : base::size3( ) - 2 * margin3_ ); }
2600
2601 size_type width( ) const { return( size1( ) ); }
2602 size_type height( ) const { return( size2( ) ); }
2603 size_type depth( ) const { return( size3( ) ); }
2604
2605 size_type margin1( ) const { return( margin1_ ); }
2606 size_type margin2( ) const { return( margin2_ ); }
2607 size_type margin3( ) const { return( margin3_ ); }
2608
2609 private:
2618 template < class T, class Allocator >
2619 const marray& copy( const array< T, Allocator > &o )
2620 {
2621 size_type length = base::size( ) < o.size( ) ? base::size( ) : o.size( );
2622 for( size_type i = 0 ; i < length ; i++ )
2623 {
2624 ( *this )[ i ] = static_cast< value_type >( o[ i ] );
2625 }
2626 return( *this );
2627 }
2628
2629
2638 template < class T, class Allocator >
2639 const marray& copy( const array1< T, Allocator > &o )
2640 {
2641 size_type length = base::size( ) < o.size( ) ? base::size( ) : o.size( );
2642 for( size_type i = 0 ; i < length ; i++ )
2643 {
2644 ( *this )[ i ] = static_cast< value_type >( o[ i ] );
2645 }
2646 return( *this );
2647 }
2648
2649
2658 template < class T, class Allocator >
2659 const marray& copy( const array2< T, Allocator > &o )
2660 {
2661 size_type w = width( ) < o.width( ) ? width( ) : o.width( );
2662 size_type h = height( ) < o.height( ) ? height( ) : o.height( );
2663 for( size_type j = 0 ; j < h ; j++ )
2664 {
2665 for( size_type i = 0 ; i < w ; i++ )
2666 {
2667 ( *this )( i, j ) = static_cast< value_type >( o( i, j ) );
2668 }
2669 }
2670 return( *this );
2671 }
2672
2673
2682 template < class T, class Allocator >
2683 const marray& copy( const array3< T, Allocator > &o )
2684 {
2685 size_type w = width( ) < o.width( ) ? width( ) : o.width( );
2686 size_type h = height( ) < o.height( ) ? height( ) : o.height( );
2687 size_type d = depth( ) < o.depth( ) ? depth( ) : o.depth( );
2688 for( size_type k = 0 ; k < d ; k++ )
2689 {
2690 for( size_type j = 0 ; j < h ; j++ )
2691 {
2692 for( size_type i = 0 ; i < w ; i++ )
2693 {
2694 ( *this )( i, j, k ) = static_cast< value_type >( o( i, j, k ) );
2695 }
2696 }
2697 }
2698 return( *this );
2699 }
2700
2701 public:
2711 const marray& operator =( const marray &o )
2712 {
2713 if( this == &o ) return( *this );
2714
2715 base::operator =( o );
2716 margin1_ = o.margin1_;
2717 margin2_ = o.margin2_;
2718 margin3_ = o.margin3_;
2719
2720 return( *this );
2721 }
2722
2723
2733 template < class T, class Allocator >
2734 const marray& operator =( const array< T, Allocator > &o )
2735 {
2736 if( base::resize( o.size( ) + margin1_ * 2 ) )
2737 {
2738 return( copy( o ) );
2739 }
2740 else
2741 {
2742 return( *this );
2743 }
2744 }
2745
2746
2756 template < class T, class Allocator >
2757 const marray& operator =( const array1< T, Allocator > &o )
2758 {
2759 if( base::resize( o.size( ) + margin1_ * 2 ) )
2760 {
2761 reso1( o.reso1( ) );
2762 return( copy( o ) );
2763 }
2764 else
2765 {
2766 return( *this );
2767 }
2768 }
2769
2770
2780 template < class T, class Allocator >
2781 const marray& operator =( const array2< T, Allocator > &o )
2782 {
2783 if( base::resize( o.size1( ) + margin1_ * 2, o.size2( ) + margin2_ * 2 ) )
2784 {
2785 reso1( o.reso1( ) );
2786 reso2( o.reso2( ) );
2787 return( copy( o ) );
2788 }
2789 else
2790 {
2791 return( *this );
2792 }
2793 }
2794
2795
2805 template < class T, class Allocator >
2806 const marray& operator =( const array3< T, Allocator > &o )
2807 {
2808 if( base::resize( o.size1( ) + margin1_ * 2, o.size2( ) + margin2_ * 2, o.size3( ) + margin3_ * 2 ) )
2809 {
2810 reso1( o.reso1( ) );
2811 reso2( o.reso2( ) );
2812 reso3( o.reso3( ) );
2813 return( copy( o ) );
2814 }
2815 else
2816 {
2817 return( *this );
2818 }
2819 }
2820
2821 // 要素へのアクセス
2822 public:
2829 reference at( difference_type index )
2830 {
2831 return( base::at( index + margin1_ ) );
2832 }
2833
2841 reference at( difference_type i, difference_type j )
2842 {
2843 return( base::at( i + margin1_, j + margin2_ ) );
2844 }
2845
2854 reference at( difference_type i, difference_type j, difference_type k )
2855 {
2856 return( base::at( i + margin1_, j + margin2_, k + margin3_ ) );
2857 }
2858
2859
2866 const_reference at( difference_type index ) const
2867 {
2868 return( base::at( index + margin1_ ) );
2869 }
2870
2878 const_reference at( difference_type i, difference_type j ) const
2879 {
2880 return( base::at( i + margin1_, j + margin2_ ) );
2881 }
2882
2891 const_reference at( difference_type i, difference_type j, difference_type k ) const
2892 {
2893 return( base::at( i + margin1_, j + margin2_, k + margin3_ ) );
2894 }
2895
2896
2903 reference operator []( difference_type index )
2904 {
2905 return( base::operator []( index ) );
2906 }
2907
2908
2915 reference operator ()( difference_type index )
2916 {
2917 return( base::operator ()( index + margin1_ ) );
2918 }
2919
2927 reference operator ()( difference_type i, difference_type j )
2928 {
2929 return( base::operator ()( i + margin1_, j + margin2_ ) );
2930 }
2931
2940 reference operator ()( difference_type i, difference_type j, difference_type k )
2941 {
2942 return( base::operator ()( i + margin1_, j + margin2_, k + margin3_ ) );
2943 }
2944
2945
2952 const_reference operator []( difference_type index ) const
2953 {
2954 return( base::operator []( index ) );
2955 }
2956
2963 const_reference operator ()( difference_type index ) const
2964 {
2965 return( base::operator ()( index + margin1_ ) );
2966 }
2967
2975 const_reference operator ()( difference_type i, difference_type j ) const
2976 {
2977 return( base::operator ()( i + margin1_, j + margin2_ ) );
2978 }
2979
2988 const_reference operator ()( difference_type i, difference_type j, difference_type k ) const
2989 {
2990 return( base::operator ()( i + margin1_, j + margin2_, k + margin3_ ) );
2991 }
2992
2993
2994 public:
2996 marray( ) : base( ), margin1_( 0 ), margin2_( 0 ), margin3_( 0 ) {}
2997
2999 marray( size_type margin ) : base( ), margin1_( margin ), margin2_( margin ), margin3_( margin ) {}
3000
3002 marray( const marray &o ) : base( o ), margin1_( o.margin1( ) ), margin2_( o.margin2( ) ), margin3_( o.margin3( ) ) {}
3003
3004
3005
3007 marray( size_type w, size_type margin ) : base( w + margin * 2 ), margin1_( margin ), margin2_( 0 ), margin3_( 0 ) {}
3008
3010 marray( size_type w, size_type h, size_type margin ) : base( w + margin * 2, h + margin * 2 ), margin1_( margin ), margin2_( margin ), margin3_( 0 ) {}
3011
3013 marray( size_type w, size_type h, size_type d, size_type margin ) : base( w + margin * 2, h + margin * 2, d + margin * 2 ), margin1_( margin ), margin2_( margin ), margin3_( margin ) {}
3014
3015
3016
3017
3019 template < class T, class Allocator >
3020 marray( const array< T, Allocator > &o, size_type margin1, const value_type &val = value_type( 0 ) )
3021 : base( o.size( ) + margin1 * 2 ), margin1_( margin1 ), margin2_( 0 ), margin3_( 0 )
3022 {
3023 fill_margin( val );
3024 copy( o );
3025 }
3026
3027
3029 template < class T, class Allocator >
3030 marray( const array1< T, Allocator > &o, size_type margin1, const value_type &val = value_type( ) )
3031 : base( o.size( ) + margin1 * 2, o.reso1( ) ), margin1_( margin1 ), margin2_( 0 ), margin3_( 0 )
3032 {
3033 fill_margin( val );
3034 copy( o );
3035 }
3036
3037
3039 template < class T, class Allocator >
3040 marray( const array2< T, Allocator > &o, size_type margin1, size_type margin2, const value_type &val = value_type( ) )
3041 : base( o.size1( ) + margin1 * 2, o.size2( ) + margin2 * 2, o.reso1( ), o.reso2( ) ), margin1_( margin1 ), margin2_( margin2 ), margin3_( 0 )
3042 {
3043 fill_margin( val );
3044 copy( o );
3045 }
3046
3048 template < class T, class Allocator >
3049 marray( const array2< T, Allocator > &o, size_type margin1, size_type margin2, size_type /* margin3 */, const value_type &val )
3050 : base( o.size1( ) + margin1 * 2, o.size2( ) + margin2 * 2, o.reso1( ), o.reso2( ) ), margin1_( margin1 ), margin2_( margin2 ), margin3_( 0 )
3051 {
3052 fill_margin( val );
3053 copy( o );
3054 }
3055
3056
3059 template < class T, class Allocator >
3060 marray( const array3< T, Allocator > &o, size_type margin1, size_type margin2, size_type margin3, const value_type &val = value_type( ) )
3061 : base( o.size1( ) + margin1 * 2, o.size2( ) + margin2 * 2, o.size3( ) + margin3 * 2, o.reso1( ), o.reso2( ), o.reso3( ) ), margin1_( margin1 ), margin2_( margin2 ), margin3_( margin3 )
3062 {
3063 fill_margin( val );
3064 copy( o );
3065 }
3066
3067
3069 template < class T, class Allocator >
3070 marray( const array2< T, Allocator > &o, size_type margin1, const value_type &val = value_type( ) )
3071 : base( o.size1( ) + margin1 * 2, o.size2( ) + margin1 * 2, o.reso1( ), o.reso2( ) ), margin1_( margin1 ), margin2_( margin1 ), margin3_( 0 )
3072 {
3073 fill_margin( val );
3074 copy( o );
3075 }
3076
3078 template < class T, class Allocator >
3079 marray( const array3< T, Allocator > &o, size_type margin1, const value_type &val = value_type( ) )
3080 : base( o.size1( ) + margin1 * 2, o.size2( ) + margin1 * 2, o.size3( ) + margin1 * 2, o.reso1( ), o.reso2( ), o.reso3( ) ), margin1_( margin1 ), margin2_( margin1 ), margin3_( margin1 )
3081 {
3082 fill_margin( val );
3083 copy( o );
3084 }
3085 };
3086
3087
3088
3089
3090
3097 template < class Array >
3098 class buffered_array : public Array
3099 {
3100 public:
3101 typedef typename Array::allocator_type allocator_type;
3102 typedef typename Array::reference reference;
3103 typedef typename Array::const_reference const_reference;
3104 typedef typename Array::value_type value_type;
3105 typedef typename Array::size_type size_type;
3106 typedef typename Array::difference_type difference_type;
3107 typedef typename Array::pointer pointer;
3108 typedef typename Array::const_pointer const_pointer;
3109
3110 typedef typename Array::iterator iterator;
3111 typedef typename Array::const_iterator const_iterator;
3112 typedef typename Array::reverse_iterator reverse_iterator;
3113 typedef typename Array::const_reverse_iterator const_reverse_iterator;
3114
3115 protected:
3116 typedef Array base;
3117 size_type size1_;
3118 size_type size2_;
3119 size_type size3_;
3120
3127 inline size_t floor_square_index( size_t v )
3128 {
3129 if( v == 0 )
3130 {
3131 return( 0 );
3132 }
3133
3134 for( size_t i = 1, _2 = 2 ; i < 64 ; i++ )
3135 {
3136 if( v <= _2 )
3137 {
3138 return( i );
3139 }
3140 _2 *= 2;
3141 }
3142
3143 return( 0 );
3144 }
3145
3152 inline size_t floor_square( size_t v )
3153 {
3154 if( v == 0 )
3155 {
3156 return( 0 );
3157 }
3158
3159 for( size_t i = 1, _2 = 2 ; i < 64 ; i++ )
3160 {
3161 if( v <= _2 )
3162 {
3163 return( _2 );
3164 }
3165 _2 *= 2;
3166 }
3167
3168 return( 0 );
3169 }
3170
3171 public:
3181 bool resize( size_type num1 )
3182 {
3183 if( base::resize( floor_square( num1 ) ) )
3184 {
3185 size1_ = num1;
3186 return( true );
3187 }
3188 else
3189 {
3190 size1_ = 0;
3191 return( false );
3192 }
3193 }
3194
3195
3206 bool resize( size_type num1, size_type num2 )
3207 {
3208 size_type s1 = floor_square( num1 );
3209 size_type s2 = floor_square( num2 );
3210 size1_ = num1;
3211 size2_ = num2;
3212 s1 = s1 > s2 ? s1 : s2;
3213 if( !base::resize( s1, s1 ) )
3214 {
3215 size1_ = size2_ = 0;
3216 return( false );
3217 }
3218
3219 return( true );
3220 }
3221
3222
3234 bool resize( size_type num1, size_type num2, size_type num3 )
3235 {
3236 size_type s1 = floor_square( num1 );
3237 size_type s2 = floor_square( num2 );
3238 size_type s3 = floor_square( num3 );
3239 size1_ = num1;
3240 size2_ = num2;
3241 size3_ = num3;
3242 s1 = s1 > s2 ? s1 : s2;
3243 s1 = s1 > s3 ? s1 : s3;
3244
3245 if( !base::resize( s1, s1, s1 ) )
3246 {
3247 size1_ = size2_ = size3_ = 0;
3248 return( false );
3249 }
3250
3251 return( true );
3252 }
3253
3254
3266 bool swap( buffered_array &a )
3267 {
3268 if( base::swap( a ) )
3269 {
3270 size_type tmp = size1_;
3271 size1_ = a.size1_;
3272 a.size1_ = tmp;
3273
3274 tmp = size2_;
3275 size2_ = a.size2_;
3276 a.size2_ = tmp;
3277
3278 tmp = size3_;
3279 size3_ = a.size3_;
3280 a.size3_ = tmp;
3281
3282 return( true );
3283 }
3284 else
3285 {
3286 return( false );
3287 }
3288 }
3289
3290
3295 void clear( )
3296 {
3297 base::clear( );
3298 size1_ = size2_ = size3_ = 0;
3299 }
3300
3301 size_type size1( ) const { return( size1_ > 0 ? size1_ : base::size1( ) ); }
3302 size_type size2( ) const { return( size2_ > 0 ? size2_ : base::size2( ) ); }
3303 size_type size3( ) const { return( size3_ > 0 ? size3_ : base::size3( ) ); }
3304 size_type width( ) const { return( size1( ) ); }
3305 size_type height( ) const { return( size2( ) ); }
3306 size_type depth( ) const { return( size3( ) ); }
3307
3308
3309 private:
3318 template < class T, class Allocator >
3319 const buffered_array& copy( const array< T, Allocator > &o )
3320 {
3321 size_type length = base::size( ) < o.size( ) ? base::size( ) : o.size( );
3322 for( size_type i = 0 ; i < length ; i++ )
3323 {
3324 ( *this )[ i ] = static_cast< value_type >( o[ i ] );
3325 }
3326 return( *this );
3327 }
3328
3329
3338 template < class T, class Allocator >
3339 const buffered_array& copy( const array1< T, Allocator > &o )
3340 {
3341 size_type length = base::size( ) < o.size( ) ? base::size( ) : o.size( );
3342 for( size_type i = 0 ; i < length ; i++ )
3343 {
3344 ( *this )[ i ] = static_cast< value_type >( o[ i ] );
3345 }
3346 return( *this );
3347 }
3348
3349
3358 template < class T, class Allocator >
3359 const buffered_array& copy( const array2< T, Allocator > &o )
3360 {
3361 size_type w = width( ) < o.width( ) ? width( ) : o.width( );
3362 size_type h = height( ) < o.height( ) ? height( ) : o.height( );
3363 for( size_type j = 0 ; j < h ; j++ )
3364 {
3365 for( size_type i = 0 ; i < w ; i++ )
3366 {
3367 ( *this )( i, j ) = static_cast< value_type >( o( i, j ) );
3368 }
3369 }
3370 return( *this );
3371 }
3372
3373
3382 template < class T, class Allocator >
3383 const buffered_array& copy( const array3< T, Allocator > &o )
3384 {
3385 size_type w = width( ) < o.width( ) ? width( ) : o.width( );
3386 size_type h = height( ) < o.height( ) ? height( ) : o.height( );
3387 size_type d = depth( ) < o.depth( ) ? depth( ) : o.depth( );
3388 for( size_type k = 0 ; k < d ; k++ )
3389 {
3390 for( size_type j = 0 ; j < h ; j++ )
3391 {
3392 for( size_type i = 0 ; i < w ; i++ )
3393 {
3394 ( *this )( i, j, k ) = static_cast< value_type >( o( i, j, k ) );
3395 }
3396 }
3397 }
3398 return( *this );
3399 }
3400
3401
3402 public:
3412 const buffered_array& operator =( const buffered_array &o )
3413 {
3414 if( this == &o ) return( *this );
3415
3416 base::operator =( o );
3417
3418 if( base::empty( ) )
3419 {
3420 size1_ = size2_ = size3_ = 0;
3421 }
3422 else
3423 {
3424 size1_ = o.size1_;
3425 size2_ = o.size2_;
3426 size3_ = o.size3_;
3427 }
3428
3429 return( *this );
3430 }
3431
3432
3442 template < class T, class Allocator >
3443 const buffered_array& operator =( const array< T, Allocator > &o )
3444 {
3445 resize( o.size( ) );
3446 return( copy( o ) );
3447 }
3448
3449
3459 template < class T, class Allocator >
3460 const buffered_array& operator =( const array1< T, Allocator > &o )
3461 {
3462 resize( o.size( ) );
3463 reso1( o.reso1( ) );
3464 return( copy( o ) );
3465 }
3466
3467
3477 template < class T, class Allocator >
3478 const buffered_array& operator =( const array2< T, Allocator > &o )
3479 {
3480 resize( o.size1( ), o.size2( ) );
3481 reso1( o.reso1( ) );
3482 reso2( o.reso2( ) );
3483 return( copy( o ) );
3484 }
3485
3486
3496 template < class T, class Allocator >
3497 const buffered_array& operator =( const array3< T, Allocator > &o )
3498 {
3499 resize( o.size1( ), o.size2( ), o.size3( ) );
3500 reso1( o.reso1( ) );
3501 reso2( o.reso2( ) );
3502 reso3( o.reso3( ) );
3503 return( copy( o ) );
3504 }
3505
3506 public:
3508 buffered_array( ) : base( ), size1_( 0 ), size2_( 0 ), size3_( 0 ) {}
3509
3511 buffered_array( const buffered_array &o ) : base( o ), size1_( o.size1( ) ), size2_( o.size2( ) ), size3_( o.size3( ) ) {}
3512
3514 template < class T, class Allocator >
3515 buffered_array( const array< T, Allocator > &o )
3516 : base( floor_square( o.size( ) ) ), size1_( o.size( ) ), size2_( 0 ), size3_( 0 )
3517 {
3518 copy( o );
3519 }
3520
3522 template < class T, class Allocator >
3523 buffered_array( const array1< T, Allocator > &o )
3524 : base( floor_square( o.size( ) ), o.reso1( ) ), size1_( o.size( ) ), size2_( 0 ), size3_( 0 )
3525 {
3526 copy( o );
3527 }
3528
3530 template < class T, class Allocator >
3531 buffered_array( const array2< T, Allocator > &o )
3532 : base( floor_square( o.size1( ) ), floor_square( o.size2( ) ), o.reso1( ), o.reso2( ) ), size1_( o.size1( ) ), size2_( o.size2( ) ), size3_( 0 )
3533 {
3534 copy( o );
3535 }
3536
3538 template < class T, class Allocator >
3539 buffered_array( const array3< T, Allocator > &o )
3540 : base( floor_square( o.size1( ) ), floor_square( o.size2( ) ), floor_square( o.size3( ) ), o.reso1( ), o.reso2( ), o.reso3( ) ),
3541 size1_( o.size1( ) ), size2_( o.size2( ) ), size3_( o.size3( ) )
3542 {
3543 copy( o );
3544 }
3545 };
3546
3547
3559 template < class T, class Allocator >
3560 inline std::ostream &operator <<( std::ostream &out, const array< T, Allocator > &a )
3561 {
3562 typename array< T, Allocator >::size_type i;
3563 for( i = 0 ; i < a.size( ) ; i++ )
3564 {
3565 out << a[ i ];
3566 if( i != a.size1( ) - 1 ) out << ", ";
3567 }
3568
3569 return( out );
3570 }
3571
3572
3584 template < class T, class Allocator >
3585 inline std::ostream &operator <<( std::ostream &out, const array1< T, Allocator > &a )
3586 {
3587 typename array1< T, Allocator >::size_type i;
3588 for( i = 0 ; i < a.size( ) ; i++ )
3589 {
3590 out << a[ i ];
3591 if( i != a.size1( ) - 1 ) out << ", ";
3592 }
3593
3594 return( out );
3595 }
3596
3597
3611 template < class T, class Allocator >
3612 inline std::ostream &operator <<( std::ostream &out, const array2< T, Allocator > &a )
3613 {
3614 typename array2< T, Allocator >::size_type i, j;
3615 for( j = 0 ; j < a.size2( ) ; j++ )
3616 {
3617 if( j != 0 )
3618 {
3619 out << std::endl;
3620 }
3621 for( i = 0 ; i < a.size1( ) ; i++ )
3622 {
3623 out << a( i, j );
3624 if( i != a.size1( ) - 1 ) out << ", ";
3625 }
3626 }
3627
3628 return( out );
3629 }
3630
3631
3649 template < class T, class Allocator >
3650 inline std::ostream &operator <<( std::ostream &out, const array3< T, Allocator > &a )
3651 {
3652 typename array3< T, Allocator >::size_type i, j, k;
3653 for( k = 0 ; k < a.size3( ) ; k++ )
3654 {
3655 for( j = 0 ; j < a.size2( ) ; j++ )
3656 {
3657 for( i = 0 ; i < a.size1( ) ; i++ )
3658 {
3659 out << a( i, j, k );
3660 if( i != a.size1( ) - 1 ) out << ", ";
3661 }
3662 out << std::endl;
3663 }
3664 if( k != a.size3( ) - 1 )
3665 {
3666 out << "----- separator -----";
3667 }
3668 out << std::endl;
3669 }
3670
3671 return( out );
3672 }
3673
3674
3675
3676 // 各コンテナに対する画像間演算
3677
3678 #if defined(_ARRAY_BIND_OPERATION_SUPPORT_) && _ARRAY_BIND_OPERATION_SUPPORT_ != 0
3679 #include "operator/operator_array.h"
3680 #endif
3681
3682 #if defined(_ARRAY1_BIND_OPERATION_SUPPORT_) && _ARRAY1_BIND_OPERATION_SUPPORT_ != 0
3683 #include "operator/operator_array1.h"
3684 #endif
3685
3686 #if defined(_ARRAY2_BIND_OPERATION_SUPPORT_) && _ARRAY2_BIND_OPERATION_SUPPORT_ != 0
3687 #include "operator/operator_array2.h"
3688 #endif
3689
3690 #if defined(_ARRAY3_BIND_OPERATION_SUPPORT_) && _ARRAY3_BIND_OPERATION_SUPPORT_ != 0
3691 #include "operator/operator_array3.h"
3692 #endif
3693
3694
3695 // mist名前空間の終わり
3696 _MIST_END
3697
3698
3699 #endif // __INCLUDE_MIST_H__
3700