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