00001
00002
00003
00004 #ifndef _CONTAINER_CLASSES_H_
00005 #define _CONTAINER_CLASSES_H_
00006
00007 void do_dump_state(const void* buf, size_t nelem, size_t size, FILE* out, int32 magic);
00008 void do_restore_state(void* buf, size_t nelem, size_t size, FILE *in, int32 magic);
00009
00015 typedef enum { ARPA_TYPE, C_TYPE, FLX_TYPE, ML_TOP } mem_layout;
00016
00017
00018 static const int32 MA_VERS[ML_TOP] = { 120070905, 220070803, 320071126 };
00019
00020 #ifdef USE_C_TYPE
00021 #define MEM_LAYOUT_VAL C_TYPE
00022 #else
00023 #define MEM_LAYOUT_VAL ARPA_TYPE
00024 #endif
00025
00026 #ifdef BOUNDS_CHECK
00027 #define lgBOUNDSCHECKVAL true
00028 #else
00029 #define lgBOUNDSCHECKVAL false
00030 #endif
00031
00034 template<class T, int d, mem_layout ALLOC, bool lgBC>
00035 class basic_pntr
00036 {
00037 static const int p_nd = lgBC ? 3 : 1;
00038 T* p_p[p_nd];
00039
00040 T* p_index_checked ( const ptrdiff_t n ) const
00041 {
00042 T* t = p_p[0]+n;
00043 #ifdef _MSC_VER
00044
00045 # pragma warning( disable : 4127 )
00046 #endif
00047 if( lgBC )
00048 {
00049 if( t < p_p[1] || t >= p_p[2] )
00050 OUT_OF_RANGE( "basic_pntr::p_index_checked()" );
00051 }
00052 return t;
00053 }
00054 void p_set_vals( T* p0, T* p1, T* p2 )
00055 {
00056 #ifdef _MSC_VER
00057
00058 # pragma warning( disable : 4127 )
00059 #endif
00060 if( lgBC )
00061 {
00062 p_p[0] = p0; p_p[1] = p1; p_p[2] = p2;
00063 }
00064 else
00065 p_p[0] = p0;
00066 }
00067 public:
00068
00069 basic_pntr( T* p0, T* p1, T* p2 )
00070 {
00071 p_set_vals( p0, p1, p2 );
00072 }
00073 basic_pntr( T* p0 )
00074 {
00075 p_set_vals( p0, NULL, NULL );
00076 }
00077 basic_pntr()
00078 {
00079 p_set_vals( NULL, NULL, NULL );
00080 }
00081 basic_pntr( const basic_pntr& t )
00082 {
00083 *this = t;
00084 }
00085
00086 virtual ~basic_pntr() {}
00087
00088 basic_pntr& operator++ ()
00089 {
00090 ++p_p[0];
00091 return *this;
00092 }
00093
00094 basic_pntr& operator-- ()
00095 {
00096 --p_p[0];
00097 return *this;
00098 }
00099
00100
00101
00102
00103 basic_pntr& operator+= ( const ptrdiff_t n ) { p_p[0] += n; return *this; }
00104 basic_pntr& operator-= ( const ptrdiff_t n ) { p_p[0] -= n; return *this; }
00105
00106 T& operator* () const
00107 {
00108 return *(p_index_checked(0));
00109 }
00110 T* operator-> () const
00111 {
00112 return p_index_checked(0);
00113 }
00114 T& operator[] ( const ptrdiff_t n ) const
00115 {
00116 return *(p_index_checked(n));
00117 }
00118
00119 bool operator== ( const basic_pntr& t ) const { return p_p[0] == t.p_p[0]; }
00120 bool operator!= ( const basic_pntr& t ) const { return p_p[0] != t.p_p[0]; }
00121 bool operator< ( const basic_pntr& t ) const { return p_p[0] < t.p_p[0]; }
00122 bool operator<= ( const basic_pntr& t ) const { return p_p[0] <= t.p_p[0]; }
00123 bool operator> ( const basic_pntr& t ) const { return p_p[0] > t.p_p[0]; }
00124 bool operator>= ( const basic_pntr& t ) const { return p_p[0] >= t.p_p[0]; }
00125 };
00126
00128 template<class T, int d, mem_layout ALLOC, bool lgBC>
00129 class pntr : public basic_pntr<T,d,ALLOC,lgBC>
00130 {
00131 public:
00132
00133 pntr( T* p0 ) : basic_pntr<T,d,ALLOC,lgBC>( p0 ) {}
00134 pntr( T* p0, T* p1, T* p2 ) : basic_pntr<T,d,ALLOC,lgBC>( p0, p1, p2 ) {}
00135 pntr() {}
00136
00137
00138 pntr& operator++ () { return static_cast<pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator++()); }
00139 const pntr operator++ (int) { pntr t = *this; ++(*this); return t; }
00140 pntr& operator-- () { return static_cast<pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator--()); }
00141 const pntr operator-- (int) { pntr t = *this; --(*this); return t; }
00142
00143 const pntr operator+ ( const ptrdiff_t n ) const { pntr s = *this; s += n; return s; }
00144 const pntr operator- ( const ptrdiff_t n ) const { pntr s = *this; s -= n; return s; }
00145 ptrdiff_t operator- ( const pntr& t ) const { return &(*this[0]) - &t[0]; }
00146 };
00147
00148
00149 template<class T, int d, mem_layout ALLOC, bool lgBC>
00150 inline const pntr<T,d,ALLOC,lgBC> operator+ ( const ptrdiff_t n, const pntr<T,d,ALLOC,lgBC>& t )
00151 {
00152 pntr<T,d,ALLOC,lgBC> s = t;
00153 s += n;
00154 return s;
00155 }
00156
00158 template<class T, int d, mem_layout ALLOC, bool lgBC>
00159 class const_pntr : public basic_pntr<T,d,ALLOC,lgBC>
00160 {
00161 public:
00162
00163 const_pntr( T* p0 ) : basic_pntr<T,d,ALLOC,lgBC>( p0 ) {}
00164 const_pntr( T* p0, T* p1, T* p2 ) : basic_pntr<T,d,ALLOC,lgBC>( p0, p1, p2 ) {}
00165 const_pntr() {}
00166
00167 const_pntr( const pntr<T,d,ALLOC,lgBC>& t ) : basic_pntr<T,d,ALLOC,lgBC>( t ) {}
00168
00169
00170 const_pntr& operator++ () { return static_cast<const_pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator++()); }
00171 const const_pntr operator++ (int) { const_pntr t = *this; ++(*this); return t; }
00172 const_pntr& operator-- () { return static_cast<const_pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator--()); }
00173 const const_pntr operator-- (int) { const_pntr t = *this; --(*this); return t; }
00174 const_pntr& operator+= ( const ptrdiff_t n )
00175 {
00176 return static_cast<const_pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator+=(n));
00177 }
00178 const_pntr& operator-= ( const ptrdiff_t n )
00179 {
00180 return static_cast<const_pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator-=(n));
00181 }
00182
00183 const T& operator* () const { return static_cast<const T&>(basic_pntr<T,d,ALLOC,lgBC>::operator*()); }
00184 const T* operator-> () const { return static_cast<const T*>(basic_pntr<T,d,ALLOC,lgBC>::operator->()); }
00185 const T& operator[] ( const ptrdiff_t n ) const
00186 {
00187 return static_cast<const T&>(basic_pntr<T,d,ALLOC,lgBC>::operator[](n));
00188 }
00189
00190 const const_pntr operator+ ( const ptrdiff_t n ) const { const_pntr s = *this; s += n; return s; }
00191 const const_pntr operator- ( const ptrdiff_t n ) const { const_pntr s = *this; s -= n; return s; }
00192 ptrdiff_t operator- ( const const_pntr& t ) const { return &(*this[0]) - &t[0]; }
00193 };
00194
00195
00196 template<class T, int d, mem_layout ALLOC, bool lgBC>
00197 inline const const_pntr<T,d,ALLOC,lgBC> operator+ ( const ptrdiff_t n, const const_pntr<T,d,ALLOC,lgBC>& t )
00198 {
00199 const_pntr<T,d,ALLOC,lgBC> s = t;
00200 s += n;
00201 return s;
00202 }
00203
00205 struct tree_vec
00206 {
00207 typedef size_t size_type;
00208
00209 size_type n;
00210 tree_vec *d;
00211
00212 private:
00213 void p_clear0()
00214 {
00215 if( d != NULL )
00216 {
00217 for( size_type i = 0; i < n; ++i )
00218 d[i].clear();
00219 delete[] d;
00220 }
00221 }
00222 void p_clear1()
00223 {
00224 n = 0;
00225 d = NULL;
00226 }
00227
00228 public:
00229 tree_vec()
00230 {
00231 p_clear1();
00232 }
00233 ~tree_vec()
00234 {
00235 p_clear0();
00236 }
00237 void clear()
00238 {
00239 p_clear0();
00240 p_clear1();
00241 }
00242 const tree_vec& operator= ( const tree_vec& m )
00243 {
00244 if( &m != this )
00245 {
00246 clear();
00247 n = m.n;
00248 if( m.d != NULL )
00249 {
00250 d = new tree_vec[n];
00251 tree_vec *p = d;
00252 const tree_vec *mp = m.d;
00253 for( size_type i = 0; i < n; ++i )
00254 *p++ = *mp++;
00255 }
00256 }
00257 return *this;
00258 }
00259 tree_vec& getvec(const size_type i, const size_type index[])
00260 {
00261 if( i == 0 )
00262 return *this;
00263 else
00264 return getvec(i-1,index).d[index[i-1]];
00265 }
00266 const tree_vec& getvec(const size_type i, const size_type index[]) const
00267 {
00268 if( i == 0 )
00269 return *this;
00270 else
00271 return getvec(i-1,index).d[index[i-1]];
00272 }
00273 };
00274
00277 template<int d,mem_layout ALLOC=MEM_LAYOUT_VAL,bool lgBC=lgBOUNDSCHECKVAL>
00278 class multi_geom
00279 {
00280 public:
00281 typedef size_t size_type;
00282
00283 tree_vec v;
00284
00285 size_type size;
00286 size_type s[d];
00287 size_type st[d];
00288 size_type nsl[d];
00289
00290 private:
00291 void p_clear0()
00292 {
00293 v.clear();
00294 }
00295 void p_clear1()
00296 {
00297 size = 0;
00298 for( int i=0; i < d; ++i )
00299 {
00300 s[i] = 0;
00301 st[i] = 0;
00302 nsl[i] = 0;
00303 }
00304 }
00305
00306 public:
00307 multi_geom()
00308 {
00309 p_clear1();
00310 }
00311 ~multi_geom()
00312 {
00313 p_clear0();
00314 }
00315 void clear()
00316 {
00317 p_clear0();
00318 p_clear1();
00319 }
00320 const multi_geom& operator= ( const multi_geom& m )
00321 {
00322 if( &m != this )
00323 {
00324 clear();
00325 v = m.v;
00326 size = m.size;
00327 for( int i=0; i < d; ++i )
00328 {
00329 s[i] = m.s[i];
00330 st[i] = m.st[i];
00331 nsl[i] = m.nsl[i];
00332 }
00333 }
00334 return *this;
00335 }
00336 bool lgInbounds(const size_type n, const size_type index[]) const
00337 {
00338 if( n != 0 )
00339 return ( lgInbounds(n-1,index) && index[n-1] < v.getvec(n-1,index).n );
00340 else
00341 return true;
00342 }
00343 void reserve(const size_type n, const size_type index[])
00344 {
00345 ASSERT( n <= d && index[n-1] > 0 && lgInbounds( n-1, index ) );
00346
00347 tree_vec& w = v.getvec( n-1, index );
00348 if( d > n )
00349 {
00350 ASSERT( w.d == NULL );
00351 w.d = new tree_vec[ index[n-1] ];
00352 }
00353 w.n = index[n-1];
00354 s[n-1] = max(s[n-1],index[n-1]);
00355 nsl[n-1] += index[n-1];
00356 }
00357 void reserve_recursive(const size_type n, size_type index[])
00358 {
00359 if( n == 0 )
00360 {
00361 reserve( n+1, index );
00362 if( n+1 < d )
00363 reserve_recursive( n+1, index );
00364 }
00365 else
00366 {
00367 size_type top = index[n-1];
00368 for( size_type i=0; i < top; ++i )
00369 {
00370 index[n-1] = i;
00371 reserve( n+1, index );
00372 if( n+1 < d )
00373 reserve_recursive( n+1, index );
00374 }
00375 index[n-1] = top;
00376 }
00377 }
00378 void finalize(void)
00379 {
00380 #ifdef _MSC_VER
00381
00382 # pragma warning( disable : 4127 )
00383 #endif
00384 if( ALLOC == ARPA_TYPE )
00385 {
00386 size_type n1[d], n2[d];
00387 for( int dim=0; dim < d; ++dim )
00388 n1[dim] = n2[dim] = 0L;
00389
00390 p_setupArray( n1, n2, &v, 0 );
00391 for( int dim=0; dim < d-1; ++dim )
00392 ASSERT( n1[dim] == nsl[dim] && n2[dim] == nsl[dim+1] );
00393 size = nsl[d-1];
00394 }
00395 else if( ALLOC == C_TYPE )
00396 {
00397 st[d-1] = s[d-1];
00398 for( int i = d-2; i >= 0; --i )
00399 st[i] = st[i+1]*s[i];
00400 size = st[0];
00401 }
00402 else
00403 {
00404 TotalInsanity();
00405 }
00406 }
00407
00408 private:
00409 void p_setupArray( size_type n1[], size_type n2[], const tree_vec* w, int l )
00410 {
00411 for( size_type i=0; i < w->n; ++i )
00412 {
00413 n1[l]++;
00414 if( l < d-2 )
00415 {
00416 p_setupArray( n1, n2, &w->d[i], l+1 );
00417 }
00418 n2[l] += w->d[i].n;
00419 }
00420 }
00421 };
00422
00423
00424
00527
00528
00529
00530
00531 template<class T, int N, mem_layout ALLOC, bool lgBC> class n_pointer;
00532 template<class T, int N, mem_layout ALLOC, bool lgBC> class const_n_pointer;
00533
00534 template<class T, int N>
00535 class n_pointer<T,N,ARPA_TYPE,false>
00536 {
00537 T* p_p;
00538 const size_t* p_st;
00539 const tree_vec* p_v;
00540 public:
00541 n_pointer(T* p, const size_t* st=NULL, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00542 const n_pointer<T,N-1,ARPA_TYPE,false> operator[] (const size_t i) const
00543 {
00544 return n_pointer<T,N-1,ARPA_TYPE,false>( *((T**)p_p+i) );
00545 }
00546 };
00547
00548 template<class T, int N>
00549 class n_pointer<T,N,C_TYPE,false>
00550 {
00551 T* p_p;
00552 const size_t* p_st;
00553 const tree_vec* p_v;
00554 public:
00555 n_pointer(T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00556 const n_pointer<T,N-1,C_TYPE,false> operator[] (const size_t i) const
00557 {
00558 return n_pointer<T,N-1,C_TYPE,false>( p_p+i*p_st[0], p_st+1 );
00559 }
00560 };
00561
00562 template<class T>
00563 class n_pointer<T,1,ARPA_TYPE,false>
00564 {
00565 T* p_p;
00566 const size_t* p_st;
00567 const tree_vec* p_v;
00568 public:
00569 n_pointer(T* p, const size_t* st=NULL, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00570 T& operator[] (const size_t i) const
00571 {
00572 return *(p_p + i);
00573 }
00574 };
00575
00576 template<class T>
00577 class n_pointer<T,1,C_TYPE,false>
00578 {
00579 T* p_p;
00580 const size_t* p_st;
00581 const tree_vec* p_v;
00582 public:
00583 n_pointer(T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00584 T& operator[] (const size_t i) const
00585 {
00586 return *(p_p + i);
00587 }
00588 };
00589
00590 template<class T, int N>
00591 class n_pointer<T,N,ARPA_TYPE,true>
00592 {
00593 T* p_p;
00594 const size_t* p_st;
00595 const tree_vec* p_v;
00596 public:
00597 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00598 const n_pointer<T,N-1,ARPA_TYPE,true> operator[] (const size_t i) const
00599 {
00600 if( i >= p_v->n )
00601 OUT_OF_RANGE( "n_pointer::operator[]" );
00602 return n_pointer<T,N-1,ARPA_TYPE,true>( *((T**)p_p+i), NULL, &p_v->d[i] );
00603 }
00604 };
00605
00606 template<class T, int N>
00607 class n_pointer<T,N,C_TYPE,true>
00608 {
00609 T* p_p;
00610 const size_t* p_st;
00611 const tree_vec* p_v;
00612 public:
00613 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00614 const n_pointer<T,N-1,C_TYPE,true> operator[] (const size_t i) const
00615 {
00616 if( i >= p_v->n )
00617 OUT_OF_RANGE( "n_pointer::operator[]" );
00618 return n_pointer<T,N-1,C_TYPE,true>( p_p+i*p_st[0], p_st+1, &p_v->d[i] );
00619 }
00620 };
00621
00622 template<class T>
00623 class n_pointer<T,1,ARPA_TYPE,true>
00624 {
00625 T* p_p;
00626 const size_t* p_st;
00627 const tree_vec* p_v;
00628 public:
00629 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00630 T& operator[] (const size_t i) const
00631 {
00632 if( i >= p_v->n )
00633 OUT_OF_RANGE( "n_pointer::operator[]" );
00634 return *(p_p + i);
00635 }
00636 };
00637
00638 template<class T>
00639 class n_pointer<T,1,C_TYPE,true>
00640 {
00641 T* p_p;
00642 const size_t* p_st;
00643 const tree_vec* p_v;
00644 public:
00645 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00646 T& operator[] (const size_t i) const
00647 {
00648 if( i >= p_v->n )
00649 OUT_OF_RANGE( "n_pointer::operator[]" );
00650 return *(p_p + i);
00651 }
00652 };
00653
00654 template<class T, int N>
00655 class const_n_pointer<T,N,ARPA_TYPE,false>
00656 {
00657 const T* p_p;
00658 const size_t* p_st;
00659 const tree_vec* p_v;
00660 public:
00661 const_n_pointer(const T* p, const size_t* st=NULL, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00662 const const_n_pointer<T,N-1,ARPA_TYPE,false> operator[] (const size_t i) const
00663 {
00664 return const_n_pointer<T,N-1,ARPA_TYPE,false>( *((T**)p_p+i) );
00665 }
00666 };
00667
00668 template<class T, int N>
00669 class const_n_pointer<T,N,C_TYPE,false>
00670 {
00671 const T* p_p;
00672 const size_t* p_st;
00673 const tree_vec* p_v;
00674 public:
00675 const_n_pointer(const T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00676 const const_n_pointer<T,N-1,C_TYPE,false> operator[] (const size_t i) const
00677 {
00678 return const_n_pointer<T,N-1,C_TYPE,false>( p_p+i*p_st[0], p_st+1 );
00679 }
00680 };
00681
00682 template<class T>
00683 class const_n_pointer<T,1,ARPA_TYPE,false>
00684 {
00685 const T* p_p;
00686 const size_t* p_st;
00687 const tree_vec* p_v;
00688 public:
00689 const_n_pointer(const T* p, const size_t* st=NULL, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00690 const T& operator[] (const size_t i) const
00691 {
00692 return *(p_p + i);
00693 }
00694 };
00695
00696 template<class T>
00697 class const_n_pointer<T,1,C_TYPE,false>
00698 {
00699 const T* p_p;
00700 const size_t* p_st;
00701 const tree_vec* p_v;
00702 public:
00703 const_n_pointer(const T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00704 const T& operator[] (const size_t i) const
00705 {
00706 return *(p_p + i);
00707 }
00708 };
00709
00710 template<class T, int N>
00711 class const_n_pointer<T,N,ARPA_TYPE,true>
00712 {
00713 const T* p_p;
00714 const size_t* p_st;
00715 const tree_vec* p_v;
00716 public:
00717 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00718 const const_n_pointer<T,N-1,ARPA_TYPE,true> operator[] (const size_t i) const
00719 {
00720 if( i >= p_v->n )
00721 OUT_OF_RANGE( "const_n_pointer::operator[]" );
00722 return const_n_pointer<T,N-1,ARPA_TYPE,true>( *((T**)p_p+i), NULL, &p_v->d[i] );
00723 }
00724 };
00725
00726 template<class T, int N>
00727 class const_n_pointer<T,N,C_TYPE,true>
00728 {
00729 const T* p_p;
00730 const size_t* p_st;
00731 const tree_vec* p_v;
00732 public:
00733 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00734 const const_n_pointer<T,N-1,C_TYPE,true> operator[] (const size_t i) const
00735 {
00736 if( i >= p_v->n )
00737 OUT_OF_RANGE( "const_n_pointer::operator[]" );
00738 return const_n_pointer<T,N-1,C_TYPE,true>( p_p+i*p_st[0], p_st+1, &p_v->d[i] );
00739 }
00740 };
00741
00742 template<class T>
00743 class const_n_pointer<T,1,ARPA_TYPE,true>
00744 {
00745 const T* p_p;
00746 const size_t* p_st;
00747 const tree_vec* p_v;
00748 public:
00749 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00750 const T& operator[] (const size_t i) const
00751 {
00752 if( i >= p_v->n )
00753 OUT_OF_RANGE( "const_n_pointer::operator[]" );
00754 return *(p_p + i);
00755 }
00756 };
00757
00758 template<class T>
00759 class const_n_pointer<T,1,C_TYPE,true>
00760 {
00761 const T* p_p;
00762 const size_t* p_st;
00763 const tree_vec* p_v;
00764 public:
00765 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00766 const T& operator[] (const size_t i) const
00767 {
00768 if( i >= p_v->n )
00769 OUT_OF_RANGE( "const_n_pointer::operator[]" );
00770 return *(p_p + i);
00771 }
00772 };
00773
00774
00898
00899
00900 template<class T, int d, mem_layout ALLOC=MEM_LAYOUT_VAL, bool lgBC=lgBOUNDSCHECKVAL>
00901 class multi_arr
00902 {
00903
00904 multi_geom<d,ALLOC,lgBC> p_g;
00905 T** p_psl[d-1];
00906 valarray<T> p_dsl;
00907 T* p_ptr;
00908 T** p_ptr2;
00909 T*** p_ptr3;
00910 T**** p_ptr4;
00911 T***** p_ptr5;
00912 T****** p_ptr6;
00913
00914 public:
00915 typedef random_access_iterator_tag iterator_category;
00916 typedef T value_type;
00917 typedef T& reference;
00918 typedef const T& const_reference;
00919 typedef T* pointer;
00920 typedef const T* const_pointer;
00921 typedef size_t size_type;
00922 typedef ptrdiff_t difference_type;
00923 typedef pntr<T,d,ALLOC,lgBC> iterator;
00924 typedef const_pntr<T,d,ALLOC,lgBC> const_iterator;
00925
00926 private:
00927 static const size_type npos = static_cast<size_type>(-1);
00928
00929 void p_clear0()
00930 {
00931 p_g.clear();
00932 for( int i=0; i < d-1; ++i )
00933 delete[] p_psl[i];
00934 p_dsl.resize(0);
00935 }
00936 void p_clear1()
00937 {
00938 for( int i=0; i < d-1; ++i )
00939 p_psl[i] = NULL;
00940 p_ptr = NULL;
00941 p_ptr2 = NULL;
00942 p_ptr3 = NULL;
00943 p_ptr4 = NULL;
00944 p_ptr5 = NULL;
00945 p_ptr6 = NULL;
00946 }
00947
00948 public:
00949 multi_arr()
00950 {
00951 p_clear1();
00952 }
00953 multi_arr(const multi_geom<d,ALLOC,lgBC>& g)
00954 {
00955 p_clear1();
00956 alloc( g );
00957 }
00958 multi_arr(size_type d1, size_type d2, size_type d3=0, size_type d4=0, size_type d5=0, size_type d6=0)
00959 {
00960 p_clear1();
00961 size_type index[] = { d1, d2, d3, d4, d5, d6 };
00962 alloc( index );
00963 }
00964 ~multi_arr()
00965 {
00966 p_clear0();
00967 }
00968 void clear()
00969 {
00970 p_clear0();
00971 p_clear1();
00972 }
00973 const multi_arr& operator= ( const multi_arr& m )
00974 {
00975 if( &m != this )
00976 {
00977 clear();
00978 p_g = m.p_g;
00979 alloc();
00980 vals() = m.vals();
00981 }
00982 return *this;
00983 }
00984 void zero()
00985 {
00986 ASSERT( vals().size() == p_g.size );
00987 memset( data(), 0, p_g.size*sizeof(T) );
00988 }
00989 void invalidate()
00990 {
00991 ASSERT( vals().size() == p_g.size );
00992 invalidate_array( data(), p_g.size*sizeof(T) );
00993 }
00994 void state_do(FILE *io, bool lgGet)
00995 {
00996 if( lgGet )
00997 restore_state(io);
00998 else
00999 dump_state(io);
01000 }
01001
01002 void dump_state(FILE *out) const
01003 {
01004 do_dump_state( data(), p_g.size, sizeof(T), out, MA_VERS[ALLOC] );
01005 }
01006
01007 void restore_state(FILE *in)
01008 {
01009 do_restore_state( data(), p_g.size, sizeof(T), in, MA_VERS[ALLOC] );
01010 }
01011
01012 void reserve(size_type i1, size_type i2=0, size_type i3=0, size_type i4=0, size_type i5=0, size_type i6=0)
01013 {
01014 const size_type index[] = { i1, i2, i3, i4, i5, i6 };
01015 size_type n = d;
01016 while( n > 1 && index[n-1] == 0 )
01017 --n;
01018 p_g.reserve( n, index );
01019 }
01020 void alloc()
01021 {
01022 ASSERT( p_ptr == NULL );
01023 p_g.finalize();
01024 #ifdef _MSC_VER
01025
01026 # pragma warning( disable : 4127 )
01027 #endif
01028 if( ALLOC == ARPA_TYPE )
01029 {
01030 size_type n1[d], n2[d];
01031
01032 for( int dim=0; dim < d; ++dim )
01033 {
01034 n1[dim] = n2[dim] = 0L;
01035 if( dim != d-1 )
01036 {
01037 ASSERT( p_psl[dim] == NULL );
01038 p_psl[dim] = new T*[ p_g.nsl[dim] ];
01039 }
01040 else
01041 {
01042 ASSERT( p_dsl.size() == 0 );
01043 p_dsl.resize( p_g.nsl[dim] );
01044 }
01045 }
01046
01047 p_setupArray( n1, n2, &p_g.v, 0 );
01048 p_ptr = (T*)p_psl[0];
01049 }
01050 else if( ALLOC == C_TYPE )
01051 {
01052 p_dsl.resize( p_g.st[0] );
01053 p_ptr = &p_dsl[0];
01054 }
01055 else
01056 {
01057 TotalInsanity();
01058 }
01059 p_ptr2 = (T**)p_ptr;
01060 p_ptr3 = (T***)p_ptr;
01061 p_ptr4 = (T****)p_ptr;
01062 p_ptr5 = (T*****)p_ptr;
01063 p_ptr6 = (T******)p_ptr;
01064 }
01065
01066 void alloc(const multi_geom<d,ALLOC,lgBC>& g)
01067 {
01068 if( &g != &p_g )
01069 {
01070 clear();
01071 p_g = g;
01072 alloc();
01073 }
01074 }
01075
01076 void alloc(size_type d1, size_type d2, size_type d3=0, size_type d4=0, size_type d5=0, size_type d6=0)
01077 {
01078 size_type index[] = { d1, d2, d3, d4, d5, d6 };
01079 alloc( index );
01080 }
01081 void alloc(size_type index[])
01082 {
01083 for( int n=0; n < d; n++ )
01084 ASSERT( index[n] > 0 );
01085 clear();
01086 p_g.reserve_recursive( 0, index );
01087 alloc();
01088 }
01089
01090 private:
01091
01092 void p_setupArray( size_type n1[], size_type n2[], const tree_vec* g, int l )
01093 {
01094 for( size_type i=0; i < g->n; ++i )
01095 {
01096 if( l < d-2 )
01097 {
01098 p_psl[l][n1[l]++] = (T*)(p_psl[l+1]+n2[l]);
01099 p_setupArray( n1, n2, &g->d[i], l+1 );
01100 }
01101 else
01102 {
01103 p_psl[l][n1[l]++] = &p_dsl[0]+n2[l];
01104 }
01105 n2[l] += g->d[i].n;
01106 }
01107 }
01108
01109
01110
01111 iterator p_iterator(size_type i1, size_type i2) const
01112 {
01113 #ifdef _MSC_VER
01114
01115 # pragma warning( disable : 4127 )
01116 #endif
01117 if( lgBC )
01118 return p_iterator_bc( i1, i2 );
01119 else
01120 {
01121 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01122 return iterator( &(*t)[i1][i2] );
01123 }
01124 }
01125 iterator p_iterator_bc(size_type i1, size_type i2) const
01126 {
01127 size_type index[] = { i1 };
01128 if( p_g.lgInbounds( 1, index ) )
01129 {
01130 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01131 size_type n = p_g.v.getvec( 1, index ).n;
01132 T* s = ( n > 0 ) ? &(*t)[i1][0] : NULL;
01133 if( i2 == npos )
01134 return iterator( s+n, s, s+n );
01135 else
01136 return iterator( s+i2, s, s+n );
01137 }
01138 else
01139 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01140 }
01141 iterator p_iterator(size_type i1, size_type i2, size_type i3) const
01142 {
01143 #ifdef _MSC_VER
01144
01145 # pragma warning( disable : 4127 )
01146 #endif
01147 if( lgBC )
01148 return p_iterator_bc( i1, i2, i3 );
01149 else
01150 {
01151 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01152 return iterator( &(*t)[i1][i2][i3] );
01153 }
01154 }
01155 iterator p_iterator_bc(size_type i1, size_type i2, size_type i3) const
01156 {
01157 size_type index[] = { i1, i2 };
01158 if( p_g.lgInbounds( 2, index ) )
01159 {
01160 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01161 size_type n = p_g.v.getvec( 2, index ).n;
01162 T* s = ( n > 0 ) ? &(*t)[i1][i2][0] : NULL;
01163 if( i3 == npos )
01164 return iterator( s+n, s, s+n );
01165 else
01166 return iterator( s+i3, s, s+n );
01167 }
01168 else
01169 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01170 }
01171 iterator p_iterator(size_type i1, size_type i2, size_type i3, size_type i4) const
01172 {
01173 #ifdef _MSC_VER
01174
01175 # pragma warning( disable : 4127 )
01176 #endif
01177 if( lgBC )
01178 return p_iterator_bc(i1, i2, i3, i4);
01179 else
01180 {
01181 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01182 return iterator( &(*t)[i1][i2][i3][i4] );
01183 }
01184 }
01185 iterator p_iterator_bc(size_type i1, size_type i2, size_type i3, size_type i4) const
01186 {
01187 size_type index[] = { i1, i2, i3 };
01188 if( p_g.lgInbounds( 3, index ) )
01189 {
01190 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01191 size_type n = p_g.v.getvec( 3, index ).n;
01192 T* s = ( n > 0 ) ? &(*t)[i1][i2][i3][0] : NULL;
01193 if( i4 == npos )
01194 return iterator( s+n, s, s+n );
01195 else
01196 return iterator( s+i4, s, s+n );
01197 }
01198 else
01199 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01200 }
01201 iterator p_iterator(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01202 {
01203 #ifdef _MSC_VER
01204
01205 # pragma warning( disable : 4127 )
01206 #endif
01207 if( lgBC )
01208 return p_iterator_bc(i1, i2, i3, i4, i5);
01209 else
01210 {
01211 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01212 return iterator( &(*t)[i1][i2][i3][i4][i5] );
01213 }
01214 }
01215 iterator p_iterator_bc(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01216 {
01217 size_type index[] = { i1, i2, i3, i4 };
01218 if( p_g.lgInbounds( 4, index ) )
01219 {
01220 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01221 size_type n = p_g.v.getvec( 4, index ).n;
01222 T* s = ( n > 0 ) ? &(*t)[i1][i2][i3][i4][0] : NULL;
01223 if( i5 == npos )
01224 return iterator( s+n, s, s+n );
01225 else
01226 return iterator( s+i5, s, s+n );
01227 }
01228 else
01229 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01230 }
01231 iterator p_iterator(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
01232 {
01233 #ifdef _MSC_VER
01234
01235 # pragma warning( disable : 4127 )
01236 #endif
01237 if( lgBC )
01238 return p_iterator_bc(i1, i2, i3, i4, i5, i6);
01239 else
01240 {
01241 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01242 return iterator( &(*t)[i1][i2][i3][i4][i5][i6] );
01243 }
01244 }
01245 iterator p_iterator_bc(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
01246 {
01247 size_type index[] = { i1, i2, i3, i4, i5 };
01248 if( p_g.lgInbounds( 5, index ) )
01249 {
01250 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01251 size_type n = p_g.v.getvec( 5, index ).n;
01252 T* s = ( n > 0 ) ? &(*t)[i1][i2][i3][i4][i5][0] : NULL;
01253 if( i6 == npos )
01254 return iterator( s+n, s, s+n );
01255 else
01256 return iterator( s+i6, s, s+n );
01257 }
01258 else
01259 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01260 }
01261
01262 public:
01263 const n_pointer<T,d,ALLOC,lgBC> n_ptr()
01264 {
01265 return n_pointer<T,d,ALLOC,lgBC>( p_ptr, p_g.st+1, &p_g.v );
01266 }
01267 const const_n_pointer<T,d,ALLOC,lgBC> n_ptr() const
01268 {
01269 return const_n_pointer<T,d,ALLOC,lgBC>( p_ptr, p_g.st+1, &p_g.v );
01270 }
01271 const n_pointer<T,d-1,ALLOC,lgBC> operator[] (size_type i)
01272 {
01273 return n_ptr()[i];
01274 }
01275 const const_n_pointer<T,d-1,ALLOC,lgBC> operator[] (size_type i) const
01276 {
01277 return n_ptr()[i];
01278 }
01279
01280 reference at(size_type i1, size_type i2)
01281 {
01282 size_type index[] = { i1, i2 };
01283 if( !p_g.lgInbounds( 2, index ) )
01284 OUT_OF_RANGE( "multi_arr::at()" );
01285 return (*this)[i1][i2];
01286 }
01287 const_reference at(size_type i1, size_type i2) const
01288 {
01289 size_type index[] = { i1, i2 };
01290 if( !p_g.lgInbounds( 2, index ) )
01291 OUT_OF_RANGE( "multi_arr::at()" );
01292 return (*this)[i1][i2];
01293 }
01294 reference at(size_type i1, size_type i2, size_type i3)
01295 {
01296 size_type index[] = { i1, i2, i3 };
01297 if( !p_g.lgInbounds( 3, index ) )
01298 OUT_OF_RANGE( "multi_arr::at()" );
01299 return (*this)[i1][i2][i3];
01300 }
01301 const_reference at(size_type i1, size_type i2, size_type i3) const
01302 {
01303 size_type index[] = { i1, i2, i3 };
01304 if( !p_g.lgInbounds( 3, index ) )
01305 OUT_OF_RANGE( "multi_arr::at()" );
01306 return (*this)[i1][i2][i3];
01307 }
01308 reference at(size_type i1, size_type i2, size_type i3, size_type i4)
01309 {
01310 size_type index[] = { i1, i2, i3, i4 };
01311 if( !p_g.lgInbounds( 4, index ) )
01312 OUT_OF_RANGE( "multi_arr::at()" );
01313 return (*this)[i1][i2][i3][i4];
01314 }
01315 const_reference at(size_type i1, size_type i2, size_type i3, size_type i4) const
01316 {
01317 size_type index[] = { i1, i2, i3, i4 };
01318 if( !p_g.lgInbounds( 4, index ) )
01319 OUT_OF_RANGE( "multi_arr::at()" );
01320 return (*this)[i1][i2][i3][i4];
01321 }
01322 reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01323 {
01324 size_type index[] = { i1, i2, i3, i4, i5 };
01325 if( !p_g.lgInbounds( 5, index ) )
01326 OUT_OF_RANGE( "multi_arr::at()" );
01327 return (*this)[i1][i2][i3][i4][i5];
01328 }
01329 const_reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01330 {
01331 size_type index[] = { i1, i2, i3, i4, i5 };
01332 if( !p_g.lgInbounds( 5, index ) )
01333 OUT_OF_RANGE( "multi_arr::at()" );
01334 return (*this)[i1][i2][i3][i4][i5];
01335 }
01336 reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6)
01337 {
01338 size_type index[] = { i1, i2, i3, i4, i5, i6 };
01339 if( !p_g.lgInbounds( 6, index ) )
01340 OUT_OF_RANGE( "multi_arr::at()" );
01341 return (*this)[i1][i2][i3][i4][i5][i6];
01342 }
01343 const_reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
01344 {
01345 size_type index[] = { i1, i2, i3, i4, i5, i6 };
01346 if( !p_g.lgInbounds( 6, index ) )
01347 OUT_OF_RANGE( "multi_arr::at()" );
01348 return (*this)[i1][i2][i3][i4][i5][i6];
01349 }
01350
01351 iterator ptr(size_type i1, size_type i2)
01352 {
01353 return p_iterator(i1, i2);
01354 }
01355 const_iterator ptr(size_type i1, size_type i2) const
01356 {
01357 return p_iterator(i1, i2);
01358 }
01359 iterator ptr(size_type i1, size_type i2, size_type i3)
01360 {
01361 return p_iterator(i1, i2, i3);
01362 }
01363 const_iterator ptr(size_type i1, size_type i2, size_type i3) const
01364 {
01365 return p_iterator(i1, i2, i3);
01366 }
01367 iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4)
01368 {
01369 return p_iterator(i1, i2, i3, i4);
01370 }
01371 const_iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4) const
01372 {
01373 return p_iterator(i1, i2, i3, i4);
01374 }
01375 iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01376 {
01377 return p_iterator(i1, i2, i3, i4, i5);
01378 }
01379 const_iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01380 {
01381 return p_iterator(i1, i2, i3, i4, i5);
01382 }
01383 iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6)
01384 {
01385 return p_iterator(i1, i2, i3, i4, i5, i6);
01386 }
01387 const_iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
01388 {
01389 return p_iterator(i1, i2, i3, i4, i5, i6);
01390 }
01391
01392 iterator begin(size_type i1)
01393 {
01394 return p_iterator(i1, 0);
01395 }
01396 const_iterator begin(size_type i1) const
01397 {
01398 return p_iterator(i1, 0);
01399 }
01400 iterator begin(size_type i1, size_type i2)
01401 {
01402 return p_iterator(i1, i2, 0);
01403 }
01404 const_iterator begin(size_type i1, size_type i2) const
01405 {
01406 return p_iterator(i1, i2, 0);
01407 }
01408 iterator begin(size_type i1, size_type i2, size_type i3)
01409 {
01410 return p_iterator(i1, i2, i3, 0);
01411 }
01412 const_iterator begin(size_type i1, size_type i2, size_type i3) const
01413 {
01414 return p_iterator(i1, i2, i3, 0);
01415 }
01416 iterator begin(size_type i1, size_type i2, size_type i3, size_type i4)
01417 {
01418 return p_iterator(i1, i2, i3, i4, 0);
01419 }
01420 const_iterator begin(size_type i1, size_type i2, size_type i3, size_type i4) const
01421 {
01422 return p_iterator(i1, i2, i3, i4, 0);
01423 }
01424 iterator begin(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01425 {
01426 return p_iterator(i1, i2, i3, i4, i5, 0);
01427 }
01428 const_iterator begin(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01429 {
01430 return p_iterator(i1, i2, i3, i4, i5, 0);
01431 }
01432
01433 iterator end(size_type i1)
01434 {
01435 #ifdef _MSC_VER
01436
01437 # pragma warning( disable : 4127 )
01438 #endif
01439 if( lgBC )
01440 return p_iterator(i1, npos);
01441 else
01442 return p_iterator(i1, p_g.v.d[i1].n);
01443 }
01444 const_iterator end(size_type i1) const
01445 {
01446 #ifdef _MSC_VER
01447
01448 # pragma warning( disable : 4127 )
01449 #endif
01450 if( lgBC )
01451 return p_iterator(i1, npos);
01452 else
01453 return p_iterator(i1, p_g.v.d[i1].n);
01454 }
01455 iterator end(size_type i1, size_type i2)
01456 {
01457 #ifdef _MSC_VER
01458
01459 # pragma warning( disable : 4127 )
01460 #endif
01461 if( lgBC )
01462 return p_iterator(i1, i2, npos);
01463 else
01464 return p_iterator(i1, i2, p_g.v.d[i1].d[i2].n);
01465 }
01466 const_iterator end(size_type i1, size_type i2) const
01467 {
01468 #ifdef _MSC_VER
01469
01470 # pragma warning( disable : 4127 )
01471 #endif
01472 if( lgBC )
01473 return p_iterator(i1, i2, npos);
01474 else
01475 return p_iterator(i1, i2, p_g.v.d[i1].d[i2].n);
01476 }
01477 iterator end(size_type i1, size_type i2, size_type i3)
01478 {
01479 #ifdef _MSC_VER
01480
01481 # pragma warning( disable : 4127 )
01482 #endif
01483 if( lgBC )
01484 return p_iterator(i1, i2, i3, npos);
01485 else
01486 return p_iterator(i1, i2, i3, p_g.v.d[i1].d[i2].d[i3].n);
01487 }
01488 const_iterator end(size_type i1, size_type i2, size_type i3) const
01489 {
01490 #ifdef _MSC_VER
01491
01492 # pragma warning( disable : 4127 )
01493 #endif
01494 if( lgBC )
01495 return p_iterator(i1, i2, i3, npos);
01496 else
01497 return p_iterator(i1, i2, i3, p_g.v.d[i1].d[i2].d[i3].n);
01498 }
01499 iterator end(size_type i1, size_type i2, size_type i3, size_type i4)
01500 {
01501 #ifdef _MSC_VER
01502
01503 # pragma warning( disable : 4127 )
01504 #endif
01505 if( lgBC )
01506 return p_iterator(i1, i2, i3, i4, npos);
01507 else
01508 return p_iterator(i1, i2, i3, i4, p_g.v.d[i1].d[i2].d[i3].d[i4].n);
01509 }
01510 const_iterator end(size_type i1, size_type i2, size_type i3, size_type i4) const
01511 {
01512 #ifdef _MSC_VER
01513
01514 # pragma warning( disable : 4127 )
01515 #endif
01516 if( lgBC )
01517 return p_iterator(i1, i2, i3, i4, npos);
01518 else
01519 return p_iterator(i1, i2, i3, i4, p_g.v.d[i1].d[i2].d[i3].d[i4].n);
01520 }
01521 iterator end(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01522 {
01523 #ifdef _MSC_VER
01524
01525 # pragma warning( disable : 4127 )
01526 #endif
01527 if( lgBC )
01528 return p_iterator(i1, i2, i3, i4, i5, npos);
01529 else
01530 return p_iterator(i1, i2, i3, i4, i5, p_g.v.d[i1].d[i2].d[i3].d[i4].d[i5].n);
01531 }
01532 const_iterator end(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01533 {
01534 #ifdef _MSC_VER
01535
01536 # pragma warning( disable : 4127 )
01537 #endif
01538 if( lgBC )
01539 return p_iterator(i1, i2, i3, i4, i5, npos);
01540 else
01541 return p_iterator(i1, i2, i3, i4, i5, p_g.v.d[i1].d[i2].d[i3].d[i4].d[i5].n);
01542 }
01543
01544 reference front(size_type i1)
01545 {
01546 return *begin(i1);
01547 }
01548 const_reference front(size_type i1) const
01549 {
01550 return *begin(i1);
01551 }
01552 reference front(size_type i1, size_type i2)
01553 {
01554 return *begin(i1, i2);
01555 }
01556 const_reference front(size_type i1, size_type i2) const
01557 {
01558 return *begin(i1, i2);
01559 }
01560 reference front(size_type i1, size_type i2, size_type i3)
01561 {
01562 return *begin(i1, i2, i3);
01563 }
01564 const_reference front(size_type i1, size_type i2, size_type i3) const
01565 {
01566 return *begin(i1, i2, i3);
01567 }
01568 reference front(size_type i1, size_type i2, size_type i3, size_type i4)
01569 {
01570 return *begin(i1, i2, i3, i4);
01571 }
01572 const_reference front(size_type i1, size_type i2, size_type i3, size_type i4) const
01573 {
01574 return *begin(i1, i2, i3, i4);
01575 }
01576 reference front(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01577 {
01578 return *begin(i1, i2, i3, i4, i5);
01579 }
01580 const_reference front(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01581 {
01582 return *begin(i1, i2, i3, i4, i5);
01583 }
01584
01585 reference back(size_type i1)
01586 {
01587 return *(end(i1) - 1);
01588 }
01589 const_reference back(size_type i1) const
01590 {
01591 return *(end(i1) - 1);
01592 }
01593 reference back(size_type i1, size_type i2)
01594 {
01595 return *(end(i1, i2) - 1);
01596 }
01597 const_reference back(size_type i1, size_type i2) const
01598 {
01599 return *(end(i1, i2) - 1);
01600 }
01601 reference back(size_type i1, size_type i2, size_type i3)
01602 {
01603 return *(end(i1, i2, i3) - 1);
01604 }
01605 const_reference back(size_type i1, size_type i2, size_type i3) const
01606 {
01607 return *(end(i1, i2, i3) - 1);
01608 }
01609 reference back(size_type i1, size_type i2, size_type i3, size_type i4)
01610 {
01611 return *(end(i1, i2, i3, i4) - 1);
01612 }
01613 const_reference back(size_type i1, size_type i2, size_type i3, size_type i4) const
01614 {
01615 return *(end(i1, i2, i3, i4) - 1);
01616 }
01617 reference back(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01618 {
01619 return *(end(i1, i2, i3, i4, i5) - 1);
01620 }
01621 const_reference back(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01622 {
01623 return *(end(i1, i2, i3, i4, i5) - 1);
01624 }
01625
01626 size_type size() const
01627 {
01628 return p_g.size;
01629 }
01630 size_type capacity() const
01631 {
01632 return p_g.size;
01633 }
01634 bool empty() const
01635 {
01636 return ( p_g.size == 0UL );
01637 }
01638
01639 pointer data()
01640 {
01641 return &p_dsl[0];
01642 }
01643 const_pointer data() const
01644 {
01645
01646 return &const_cast<valarray<T>&>(p_dsl)[0];
01647 }
01648
01649 const multi_geom<d,ALLOC,lgBC>& clone() const
01650 {
01651 return p_g;
01652 }
01653
01654 valarray<T>& vals()
01655 {
01656 return p_dsl;
01657 }
01658 const valarray<T>& vals() const
01659 {
01660 return p_dsl;
01661 }
01662 };
01663
01664
01665 typedef multi_arr<bool,2>::iterator mb2i;
01666 typedef multi_arr<bool,2>::const_iterator mb2ci;
01667 typedef multi_arr<bool,3>::iterator mb3i;
01668 typedef multi_arr<bool,3>::const_iterator mb3ci;
01669 typedef multi_arr<bool,4>::iterator mb4i;
01670 typedef multi_arr<bool,4>::const_iterator mb4ci;
01671 typedef multi_arr<bool,5>::iterator mb5i;
01672 typedef multi_arr<bool,5>::const_iterator mb5ci;
01673 typedef multi_arr<bool,6>::iterator mb6i;
01674 typedef multi_arr<bool,6>::const_iterator mb6ci;
01675
01676 typedef multi_arr<long,2>::iterator ml2i;
01677 typedef multi_arr<long,2>::const_iterator ml2ci;
01678 typedef multi_arr<long,3>::iterator ml3i;
01679 typedef multi_arr<long,3>::const_iterator ml3ci;
01680 typedef multi_arr<long,4>::iterator ml4i;
01681 typedef multi_arr<long,4>::const_iterator ml4ci;
01682 typedef multi_arr<long,5>::iterator ml5i;
01683 typedef multi_arr<long,5>::const_iterator ml5ci;
01684 typedef multi_arr<long,6>::iterator ml6i;
01685 typedef multi_arr<long,6>::const_iterator ml6ci;
01686
01687 typedef multi_arr<realnum,2>::iterator mr2i;
01688 typedef multi_arr<realnum,2>::const_iterator mr2ci;
01689 typedef multi_arr<realnum,3>::iterator mr3i;
01690 typedef multi_arr<realnum,3>::const_iterator mr3ci;
01691 typedef multi_arr<realnum,4>::iterator mr4i;
01692 typedef multi_arr<realnum,4>::const_iterator mr4ci;
01693 typedef multi_arr<realnum,5>::iterator mr5i;
01694 typedef multi_arr<realnum,5>::const_iterator mr5ci;
01695 typedef multi_arr<realnum,6>::iterator mr6i;
01696 typedef multi_arr<realnum,6>::const_iterator mr6ci;
01697
01698 typedef multi_arr<double,2>::iterator md2i;
01699 typedef multi_arr<double,2>::const_iterator md2ci;
01700 typedef multi_arr<double,3>::iterator md3i;
01701 typedef multi_arr<double,3>::const_iterator md3ci;
01702 typedef multi_arr<double,4>::iterator md4i;
01703 typedef multi_arr<double,4>::const_iterator md4ci;
01704 typedef multi_arr<double,5>::iterator md5i;
01705 typedef multi_arr<double,5>::const_iterator md5ci;
01706 typedef multi_arr<double,6>::iterator md6i;
01707 typedef multi_arr<double,6>::const_iterator md6ci;
01708
01709 #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(_MSC_VER)
01710 #define INST_EXTERN EXTERN
01711 #else
01712 #define INST_EXTERN
01713 #endif
01714
01715 #ifdef _MSC_VER
01716
01717 # pragma warning( disable : 4231 )
01718 #endif
01719
01720
01721 #define INSTANTIATE_MULTI_ARR( TYPE, LAYOUT, BC ) \
01722 INST_EXTERN template class pntr<TYPE,2,LAYOUT,BC>; \
01723 INST_EXTERN template class pntr<TYPE,3,LAYOUT,BC>; \
01724 INST_EXTERN template class pntr<TYPE,4,LAYOUT,BC>; \
01725 INST_EXTERN template class pntr<TYPE,5,LAYOUT,BC>; \
01726 INST_EXTERN template class pntr<TYPE,6,LAYOUT,BC>; \
01727 INST_EXTERN template class const_pntr<TYPE,2,LAYOUT,BC>; \
01728 INST_EXTERN template class const_pntr<TYPE,3,LAYOUT,BC>; \
01729 INST_EXTERN template class const_pntr<TYPE,4,LAYOUT,BC>; \
01730 INST_EXTERN template class const_pntr<TYPE,5,LAYOUT,BC>; \
01731 INST_EXTERN template class const_pntr<TYPE,6,LAYOUT,BC>
01732
01733 INSTANTIATE_MULTI_ARR( bool, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL );
01734 INSTANTIATE_MULTI_ARR( long, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL );
01735 INSTANTIATE_MULTI_ARR( realnum, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL );
01736 INSTANTIATE_MULTI_ARR( double, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL );
01737 INSTANTIATE_MULTI_ARR( double, C_TYPE, lgBOUNDSCHECKVAL );
01738
01739
01740 template<class T, bool lgBC=lgBOUNDSCHECKVAL>
01741 class flex_arr
01742 {
01743 size_t p_size;
01744 long p_begin;
01745 long p_end;
01746 bool p_init;
01747
01748 T* p_ptr_alloc;
01749 T* p_ptr;
01750
01751 public:
01752 typedef random_access_iterator_tag iterator_category;
01753 typedef T value_type;
01754 typedef T& reference;
01755 typedef const T& const_reference;
01756 typedef T* pointer;
01757 typedef const T* const_pointer;
01758 typedef long size_type;
01759 typedef ptrdiff_t difference_type;
01760 typedef pntr<T,1,FLX_TYPE,lgBC> iterator;
01761 typedef const_pntr<T,1,FLX_TYPE,lgBC> const_iterator;
01762
01763 private:
01764 void p_clear0()
01765 {
01766 delete[] p_ptr_alloc;
01767 p_ptr_alloc = NULL;
01768 }
01769 void p_clear1()
01770 {
01771 p_size = 0;
01772 p_begin = 0;
01773 p_end = 0;
01774 p_init = false;
01775 p_ptr_alloc = NULL;
01776 p_ptr = NULL;
01777 }
01778
01779 public:
01780 flex_arr()
01781 {
01782 p_clear1();
01783 }
01784 flex_arr(size_type begin, size_type end)
01785 {
01786 p_clear1();
01787 alloc( begin, end );
01788 }
01789 ~flex_arr()
01790 {
01791 p_clear0();
01792 }
01793 const flex_arr& operator= ( const flex_arr& f )
01794 {
01795 if( &f != this )
01796 {
01797 clear();
01798 p_size = f.p_size;
01799 p_begin = f.p_begin;
01800 p_end = f.p_end;
01801 p_init = f.p_init;
01802 if( f.p_ptr_alloc != NULL )
01803 {
01804 p_ptr_alloc = new T[ p_size ];
01805 pointer p = p_ptr_alloc;
01806 const_pointer fp = f.p_ptr_alloc;
01807 for( size_type i=0; i < p_end-p_begin; ++i )
01808 *p++ = *fp++;
01809 p_ptr = p_ptr_alloc - p_begin;
01810 }
01811 }
01812 return *this;
01813 }
01814 void clear()
01815 {
01816 p_clear0();
01817 p_clear1();
01818 }
01819 void zero()
01820 {
01821 ASSERT( p_ptr_alloc != NULL );
01822 memset( p_ptr_alloc, 0, p_size*sizeof(T) );
01823 }
01824 void invalidate()
01825 {
01826 ASSERT( p_ptr_alloc != NULL );
01827 invalidate_array( p_ptr_alloc, p_size*sizeof(T) );
01828 }
01829 void state_do(FILE *out, bool lgGet)
01830 {
01831 if( lgGet )
01832 restore_state(out);
01833 else
01834 dump_state(out);
01835 }
01836
01837 void dump_state(FILE *out) const
01838 {
01839 do_dump_state( p_ptr_alloc, p_size, sizeof(T), out, MA_VERS[FLX_TYPE] );
01840 }
01841
01842 void restore_state(FILE *in)
01843 {
01844 do_restore_state( p_ptr_alloc, p_size, sizeof(T), in, MA_VERS[FLX_TYPE] );
01845 }
01846
01847
01848 void reserve(size_type size)
01849 {
01850
01851 clear();
01852 #ifdef _MSC_VER
01853
01854 # pragma warning( disable : 4127 )
01855 #endif
01856 if( size > 0 )
01857 {
01858 ASSERT( p_ptr_alloc == NULL );
01859 p_ptr_alloc = new T[size];
01860 p_size = (size_t)size;
01861 }
01862 }
01863
01864
01865 void alloc(size_type begin, size_type end)
01866 {
01867 if( (size_t)max(end-begin,0) > p_size )
01868 {
01869 clear();
01870
01871 ASSERT( p_ptr_alloc == NULL );
01872 p_ptr_alloc = new T[end-begin];
01873 p_ptr = p_ptr_alloc - begin;
01874 p_size = (size_t)(end-begin);
01875 }
01876 else
01877 {
01878
01879 p_ptr = p_ptr_alloc - begin;
01880 }
01881 p_begin = begin;
01882 p_end = end;
01883 p_init = true;
01884 }
01885
01886 void realloc(size_type end)
01887 {
01888 ASSERT( p_init );
01889 if( (size_t)max(end-p_begin,0) > p_size )
01890 {
01891
01892 T* nptr_alloc = new T[end-p_begin];
01893 T* nptr = nptr_alloc - p_begin;
01894
01895
01896
01897
01898 if( p_ptr_alloc != NULL && p_ptr != NULL )
01899 {
01900 for( size_type i=p_begin; i < p_end; ++i )
01901 nptr[i] = p_ptr[i];
01902 delete[] p_ptr_alloc;
01903 }
01904 p_ptr_alloc = nptr_alloc;
01905 p_ptr = nptr;
01906 p_size = (size_t)(end-p_begin);
01907 }
01908 p_end = end;
01909 }
01910
01911 private:
01912
01913 pointer p_pointer(size_type i) const
01914 {
01915 return p_ptr+i;
01916 }
01917
01918 iterator p_iterator(size_type i) const
01919 {
01920 #ifdef _MSC_VER
01921
01922 # pragma warning( disable : 4127 )
01923 #endif
01924 if( lgBC )
01925 return iterator( p_pointer(i), p_pointer(p_begin), p_pointer(p_end) );
01926 else
01927 return iterator( p_pointer(i) );
01928 }
01929
01930 bool p_lgInbounds(size_type i) const
01931 {
01932 return ( i >= p_begin && i < p_end );
01933 }
01934
01935 reference p_index(size_type i) const
01936 {
01937 #ifdef _MSC_VER
01938
01939 # pragma warning( disable : 4127 )
01940 #endif
01941 if( lgBC )
01942 {
01943 if( ! p_lgInbounds( i ) )
01944 OUT_OF_RANGE( "flex_arr::p_index()" );
01945 }
01946 return *p_pointer(i);
01947 }
01948
01949 public:
01950 reference operator[] (size_type i)
01951 {
01952 return reference(p_index(i));
01953 }
01954 const_reference operator[] (size_type i) const
01955 {
01956 return const_reference(p_index(i));
01957 }
01958
01959 reference at(size_type i)
01960 {
01961 if( ! p_lgInbounds(i) )
01962 OUT_OF_RANGE( "flex_arr::at()" );
01963 return (*this)[i];
01964 }
01965 const_reference at(size_type i) const
01966 {
01967 if( ! p_lgInbounds(i) )
01968 OUT_OF_RANGE( "flex_arr::at()" );
01969 return (*this)[i];
01970 }
01971
01972 iterator ptr(size_type i)
01973 {
01974 return iterator(p_iterator(i));
01975 }
01976 const_iterator ptr(size_type i) const
01977 {
01978 return const_iterator(p_iterator(i));
01979 }
01980
01981
01982
01983 iterator begin()
01984 {
01985 return ptr(p_begin);
01986 }
01987 const_iterator begin() const
01988 {
01989 return ptr(p_begin);
01990 }
01991
01992 iterator end()
01993 {
01994 return ptr(p_end);
01995 }
01996 const_iterator end() const
01997 {
01998 return ptr(p_end);
01999 }
02000
02001 reference front()
02002 {
02003 return *begin();
02004 }
02005 const_reference front() const
02006 {
02007 return *begin();
02008 }
02009
02010 reference back()
02011 {
02012 return *(end()-1);
02013 }
02014 const_reference back() const
02015 {
02016 return *(end()-1);
02017 }
02018
02019 size_type size() const
02020 {
02021 return max(p_end-p_begin,0);
02022 }
02023 size_type capacity() const
02024 {
02025 return p_size;
02026 }
02027 bool empty() const
02028 {
02029 return ( size() == 0 );
02030 }
02031
02032 pointer data()
02033 {
02034 return p_ptr_alloc;
02035 }
02036 const_pointer data() const
02037 {
02038 return p_ptr_alloc;
02039 }
02040 };
02041
02042
02043 typedef flex_arr<bool>::iterator fabi;
02044 typedef flex_arr<bool>::const_iterator fabci;
02045 typedef flex_arr<long>::iterator fali;
02046 typedef flex_arr<long>::const_iterator falci;
02047 typedef flex_arr<realnum>::iterator fari;
02048 typedef flex_arr<realnum>::const_iterator farci;
02049 typedef flex_arr<double>::iterator fadi;
02050 typedef flex_arr<double>::const_iterator fadci;
02051
02052 #endif