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 typedef n_pointer<T,N-1,ARPA_TYPE,false> value_type;
00566 n_pointer(T* p, const size_t* st=NULL, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00567 const value_type operator[] (const size_t i) const
00568 {
00569 return value_type( *((T**)p_p+i) );
00570 }
00571 };
00572
00573 template<class T, int N>
00574 class n_pointer<T,N,C_TYPE,false>
00575 {
00576 T* p_p;
00577 const size_t* p_st;
00578 const tree_vec* p_v;
00579 public:
00580 typedef n_pointer<T,N-1,C_TYPE,false> value_type;
00581 n_pointer(T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00582 const value_type operator[] (const size_t i) const
00583 {
00584 return value_type( p_p+i*p_st[0], p_st+1 );
00585 }
00586 };
00587
00588 template<class T>
00589 class n_pointer<T,1,ARPA_TYPE,false>
00590 {
00591 T* p_p;
00592 const size_t* p_st;
00593 const tree_vec* p_v;
00594 public:
00595 typedef T value_type;
00596 n_pointer(T* p, const size_t* st=NULL, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00597 value_type& operator[] (const size_t i) const
00598 {
00599 return *(p_p + i);
00600 }
00601 };
00602
00603 template<class T>
00604 class n_pointer<T,1,C_TYPE,false>
00605 {
00606 T* p_p;
00607 const size_t* p_st;
00608 const tree_vec* p_v;
00609 public:
00610 typedef T value_type;
00611 n_pointer(T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00612 value_type& operator[] (const size_t i) const
00613 {
00614 return *(p_p + i);
00615 }
00616 };
00617
00618 template<class T, int N>
00619 class n_pointer<T,N,ARPA_TYPE,true>
00620 {
00621 T* p_p;
00622 const size_t* p_st;
00623 const tree_vec* p_v;
00624 public:
00625 typedef n_pointer<T,N-1,ARPA_TYPE,true> value_type;
00626 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00627 const value_type operator[] (const size_t i) const
00628 {
00629 if( i >= p_v->n )
00630 OUT_OF_RANGE( "n_pointer::operator[]" );
00631 return value_type( *((T**)p_p+i), NULL, &p_v->d[i] );
00632 }
00633 };
00634
00635 template<class T, int N>
00636 class n_pointer<T,N,C_TYPE,true>
00637 {
00638 T* p_p;
00639 const size_t* p_st;
00640 const tree_vec* p_v;
00641 public:
00642 typedef n_pointer<T,N-1,C_TYPE,true> value_type;
00643 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00644 const value_type operator[] (const size_t i) const
00645 {
00646 if( i >= p_v->n )
00647 OUT_OF_RANGE( "n_pointer::operator[]" );
00648 return value_type( p_p+i*p_st[0], p_st+1, &p_v->d[i] );
00649 }
00650 };
00651
00652 template<class T>
00653 class n_pointer<T,1,ARPA_TYPE,true>
00654 {
00655 T* p_p;
00656 const size_t* p_st;
00657 const tree_vec* p_v;
00658 public:
00659 typedef T value_type;
00660 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00661 value_type& operator[] (const size_t i) const
00662 {
00663 if( i >= p_v->n )
00664 OUT_OF_RANGE( "n_pointer::operator[]" );
00665 return *(p_p + i);
00666 }
00667 };
00668
00669 template<class T>
00670 class n_pointer<T,1,C_TYPE,true>
00671 {
00672 T* p_p;
00673 const size_t* p_st;
00674 const tree_vec* p_v;
00675 public:
00676 typedef T value_type;
00677 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00678 value_type& operator[] (const size_t i) const
00679 {
00680 if( i >= p_v->n )
00681 OUT_OF_RANGE( "n_pointer::operator[]" );
00682 return *(p_p + i);
00683 }
00684 };
00685
00686 template<class T, int N>
00687 class const_n_pointer<T,N,ARPA_TYPE,false>
00688 {
00689 const T* p_p;
00690 const size_t* p_st;
00691 const tree_vec* p_v;
00692 public:
00693 typedef const_n_pointer<T,N-1,ARPA_TYPE,false> value_type;
00694 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) {}
00695 const value_type operator[] (const size_t i) const
00696 {
00697 return value_type( *((T**)p_p+i) );
00698 }
00699 };
00700
00701 template<class T, int N>
00702 class const_n_pointer<T,N,C_TYPE,false>
00703 {
00704 const T* p_p;
00705 const size_t* p_st;
00706 const tree_vec* p_v;
00707 public:
00708 typedef const_n_pointer<T,N-1,C_TYPE,false> value_type;
00709 const_n_pointer(const T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00710 const value_type operator[] (const size_t i) const
00711 {
00712 return value_type( p_p+i*p_st[0], p_st+1 );
00713 }
00714 };
00715
00716 template<class T>
00717 class const_n_pointer<T,1,ARPA_TYPE,false>
00718 {
00719 const T* p_p;
00720 const size_t* p_st;
00721 const tree_vec* p_v;
00722 public:
00723 typedef const T value_type;
00724 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) {}
00725 value_type& operator[] (const size_t i) const
00726 {
00727 return *(p_p + i);
00728 }
00729 };
00730
00731 template<class T>
00732 class const_n_pointer<T,1,C_TYPE,false>
00733 {
00734 const T* p_p;
00735 const size_t* p_st;
00736 const tree_vec* p_v;
00737 public:
00738 typedef const T value_type;
00739 const_n_pointer(const T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
00740 value_type& operator[] (const size_t i) const
00741 {
00742 return *(p_p + i);
00743 }
00744 };
00745
00746 template<class T, int N>
00747 class const_n_pointer<T,N,ARPA_TYPE,true>
00748 {
00749 const T* p_p;
00750 const size_t* p_st;
00751 const tree_vec* p_v;
00752 public:
00753 typedef const_n_pointer<T,N-1,ARPA_TYPE,true> value_type;
00754 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00755 const value_type operator[] (const size_t i) const
00756 {
00757 if( i >= p_v->n )
00758 OUT_OF_RANGE( "const_n_pointer::operator[]" );
00759 return value_type( *((T**)p_p+i), NULL, &p_v->d[i] );
00760 }
00761 };
00762
00763 template<class T, int N>
00764 class const_n_pointer<T,N,C_TYPE,true>
00765 {
00766 const T* p_p;
00767 const size_t* p_st;
00768 const tree_vec* p_v;
00769 public:
00770 typedef const_n_pointer<T,N-1,C_TYPE,true> value_type;
00771 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00772 const value_type operator[] (const size_t i) const
00773 {
00774 if( i >= p_v->n )
00775 OUT_OF_RANGE( "const_n_pointer::operator[]" );
00776 return value_type( p_p+i*p_st[0], p_st+1, &p_v->d[i] );
00777 }
00778 };
00779
00780 template<class T>
00781 class const_n_pointer<T,1,ARPA_TYPE,true>
00782 {
00783 const T* p_p;
00784 const size_t* p_st;
00785 const tree_vec* p_v;
00786 public:
00787 typedef const T value_type;
00788 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00789 value_type& operator[] (const size_t i) const
00790 {
00791 if( i >= p_v->n )
00792 OUT_OF_RANGE( "const_n_pointer::operator[]" );
00793 return *(p_p + i);
00794 }
00795 };
00796
00797 template<class T>
00798 class const_n_pointer<T,1,C_TYPE,true>
00799 {
00800 const T* p_p;
00801 const size_t* p_st;
00802 const tree_vec* p_v;
00803 public:
00804 typedef const T value_type;
00805 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
00806 value_type& operator[] (const size_t i) const
00807 {
00808 if( i >= p_v->n )
00809 OUT_OF_RANGE( "const_n_pointer::operator[]" );
00810 return *(p_p + i);
00811 }
00812 };
00813
00814
00938
00939
00940 template<class T, int d, mem_layout ALLOC=MEM_LAYOUT_VAL, bool lgBC=lgBOUNDSCHECKVAL>
00941 class multi_arr
00942 {
00943
00944 multi_geom<d,ALLOC> p_g;
00945 T** p_psl[d-1];
00946 valarray<T> p_dsl;
00947 T* p_ptr;
00948 T** p_ptr2;
00949 T*** p_ptr3;
00950 T**** p_ptr4;
00951 T***** p_ptr5;
00952 T****** p_ptr6;
00953
00954 public:
00955 typedef random_access_iterator_tag iterator_category;
00956 typedef T value_type;
00957 typedef T& reference;
00958 typedef const T& const_reference;
00959 typedef T* pointer;
00960 typedef const T* const_pointer;
00961 typedef size_t size_type;
00962 typedef ptrdiff_t difference_type;
00963 typedef pntr<T,lgBC> iterator;
00964 typedef const_pntr<T,lgBC> const_iterator;
00965
00966 private:
00967 static const size_type npos = static_cast<size_type>(-1);
00968
00969 void p_clear0()
00970 {
00971 p_g.clear();
00972 for( int i=0; i < d-1; ++i )
00973 delete[] p_psl[i];
00974 p_dsl.resize(0);
00975 }
00976 void p_clear1()
00977 {
00978 for( int i=0; i < d-1; ++i )
00979 p_psl[i] = NULL;
00980 p_ptr = NULL;
00981 p_ptr2 = NULL;
00982 p_ptr3 = NULL;
00983 p_ptr4 = NULL;
00984 p_ptr5 = NULL;
00985 p_ptr6 = NULL;
00986 }
00987
00988 public:
00989 multi_arr()
00990 {
00991 p_clear1();
00992 }
00993 multi_arr(const multi_geom<d,ALLOC>& g)
00994 {
00995 p_clear1();
00996 alloc( g );
00997 }
00998 multi_arr(size_type d1, size_type d2)
00999 {
01000 p_clear1();
01001 size_type index[] = { d1, d2 };
01002 alloc( index );
01003 }
01004 multi_arr(size_type d1, size_type d2, size_type d3)
01005 {
01006 p_clear1();
01007 size_type index[] = { d1, d2, d3 };
01008 alloc( index );
01009 }
01010 multi_arr(size_type d1, size_type d2, size_type d3, size_type d4)
01011 {
01012 p_clear1();
01013 size_type index[] = { d1, d2, d3, d4 };
01014 alloc( index );
01015 }
01016 multi_arr(size_type d1, size_type d2, size_type d3, size_type d4, size_type d5)
01017 {
01018 p_clear1();
01019 size_type index[] = { d1, d2, d3, d4, d5 };
01020 alloc( index );
01021 }
01022 multi_arr(size_type d1, size_type d2, size_type d3, size_type d4, size_type d5, size_type d6)
01023 {
01024 p_clear1();
01025 size_type index[] = { d1, d2, d3, d4, d5, d6 };
01026 alloc( index );
01027 }
01028 multi_arr(const multi_arr& m)
01029 {
01030 p_clear1();
01031 *this = m;
01032 }
01033 ~multi_arr()
01034 {
01035 p_clear0();
01036 }
01037 void clear()
01038 {
01039 p_clear0();
01040 p_clear1();
01041 }
01042 const multi_arr& operator= (const multi_arr& m)
01043 {
01044 if( &m != this )
01045 {
01046 alloc( m.p_g );
01047 vals() = m.vals();
01048 }
01049 return *this;
01050 }
01051 void zero()
01052 {
01053 ASSERT( vals().size() == p_g.size );
01054 if( p_g.size > 0 )
01055 memset( data(), 0, p_g.size*sizeof(T) );
01056 }
01057 void invalidate()
01058 {
01059 ASSERT( vals().size() == p_g.size );
01060 invalidate_array( data(), p_g.size*sizeof(T) );
01061 }
01062 void state_do(FILE *io, bool lgGet)
01063 {
01064 if( lgGet )
01065 restore_state(io);
01066 else
01067 dump_state(io);
01068 }
01069
01070 void dump_state(FILE *out) const
01071 {
01072 do_dump_state( data(), p_g.size, sizeof(T), out, MA_VERS[ALLOC] );
01073 }
01074
01075 void restore_state(FILE *in)
01076 {
01077 do_restore_state( data(), p_g.size, sizeof(T), in, MA_VERS[ALLOC] );
01078 }
01079
01080 void reserve(size_type i1)
01081 {
01082 ASSERT( vals().size() == 0 );
01083 const size_type index[] = { i1 };
01084 p_g.reserve( 1, index );
01085 }
01086 void reserve(size_type i1, size_type i2)
01087 {
01088 ASSERT( vals().size() == 0 );
01089 const size_type index[] = { i1, i2 };
01090 p_g.reserve( 2, index );
01091 }
01092 void reserve(size_type i1, size_type i2, size_type i3)
01093 {
01094 ASSERT( vals().size() == 0 );
01095 const size_type index[] = { i1, i2, i3 };
01096 p_g.reserve( 3, index );
01097 }
01098 void reserve(size_type i1, size_type i2, size_type i3, size_type i4)
01099 {
01100 ASSERT( vals().size() == 0 );
01101 const size_type index[] = { i1, i2, i3, i4 };
01102 p_g.reserve( 4, index );
01103 }
01104 void reserve(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01105 {
01106 ASSERT( vals().size() == 0 );
01107 const size_type index[] = { i1, i2, i3, i4, i5 };
01108 p_g.reserve( 5, index );
01109 }
01110 void reserve(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6)
01111 {
01112 ASSERT( vals().size() == 0 );
01113 const size_type index[] = { i1, i2, i3, i4, i5, i6 };
01114 p_g.reserve( 6, index );
01115 }
01116 void alloc()
01117 {
01118 p_g.finalize();
01119 #ifdef _MSC_VER
01120
01121 # pragma warning( disable : 4127 )
01122 #endif
01123 STATIC_ASSERT ( ALLOC == C_TYPE || ALLOC == ARPA_TYPE );
01124
01125 if( ALLOC == ARPA_TYPE )
01126 {
01127 size_type n1[d], n2[d];
01128
01129 for( int dim=0; dim < d; ++dim )
01130 {
01131 n1[dim] = n2[dim] = 0L;
01132 if( dim != d-1 )
01133 {
01134 ASSERT( p_psl[dim] == NULL );
01135 if( p_g.nsl[dim] > 0 )
01136 p_psl[dim] = new T*[ p_g.nsl[dim] ];
01137 }
01138 else
01139 {
01140 ASSERT( p_dsl.size() == 0 );
01141 p_dsl.resize( p_g.nsl[dim] );
01142 }
01143 }
01144
01145 p_setupArray( n1, n2, &p_g.v, 0 );
01146 p_ptr = (T*)p_psl[0];
01147 }
01148 else if( ALLOC == C_TYPE )
01149 {
01150 for( int i=0; i < d-1; ++i )
01151 p_psl[i] = NULL;
01152 ASSERT( p_dsl.size() == 0 );
01153 p_dsl.resize( p_g.st[0] );
01154 p_ptr = &p_dsl[0];
01155 }
01156 else
01157 {
01158 TotalInsanity();
01159 }
01160 p_ptr2 = (T**)p_ptr;
01161 p_ptr3 = (T***)p_ptr;
01162 p_ptr4 = (T****)p_ptr;
01163 p_ptr5 = (T*****)p_ptr;
01164 p_ptr6 = (T******)p_ptr;
01165 }
01166
01167 void alloc(const multi_geom<d,ALLOC>& g)
01168 {
01169 if( &g != &p_g )
01170 {
01171 clear();
01172 p_g = g;
01173 alloc();
01174 }
01175 }
01176
01177 void alloc(size_type d1, size_type d2)
01178 {
01179 size_type index[] = { d1, d2 };
01180 alloc( index );
01181 }
01182 void alloc(size_type d1, size_type d2, size_type d3)
01183 {
01184 size_type index[] = { d1, d2, d3 };
01185 alloc( index );
01186 }
01187 void alloc(size_type d1, size_type d2, size_type d3, size_type d4)
01188 {
01189 size_type index[] = { d1, d2, d3, d4 };
01190 alloc( index );
01191 }
01192 void alloc(size_type d1, size_type d2, size_type d3, size_type d4, size_type d5)
01193 {
01194 size_type index[] = { d1, d2, d3, d4, d5 };
01195 alloc( index );
01196 }
01197 void alloc(size_type d1, size_type d2, size_type d3, size_type d4, size_type d5, size_type d6)
01198 {
01199 size_type index[] = { d1, d2, d3, d4, d5, d6 };
01200 alloc( index );
01201 }
01202 void alloc(size_type index[])
01203 {
01204 for( int n=0; n < d; n++ )
01205 ASSERT( index[n] > 0 );
01206 clear();
01207 p_g.reserve_recursive( 0, index );
01208 alloc();
01209 }
01210
01211 private:
01212
01213 void p_setupArray( size_type n1[], size_type n2[], const tree_vec* g, int l )
01214 {
01215
01216 if( l < 0 )
01217 TotalInsanity();
01218
01219 for( size_type i=0; i < g->n; ++i )
01220 {
01221 if( l < d-2 )
01222 {
01223 p_psl[l][n1[l]++] = (T*)(p_psl[l+1]+n2[l]);
01224 p_setupArray( n1, n2, &g->d[i], l+1 );
01225 }
01226 else
01227 {
01228 p_psl[l][n1[l]++] = &p_dsl[0]+n2[l];
01229 }
01230 n2[l] += g->d[i].n;
01231 }
01232 }
01233
01234
01235
01236 iterator p_iterator(size_type i1, size_type i2) const
01237 {
01238 #ifdef _MSC_VER
01239
01240 # pragma warning( disable : 4127 )
01241 #endif
01242 if( lgBC )
01243 return p_iterator_bc( i1, i2 );
01244 else
01245 {
01246 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01247 return iterator( &(*t)[i1][i2] );
01248 }
01249 }
01250 iterator p_iterator_bc(size_type i1, size_type i2) const
01251 {
01252 size_type index[] = { i1 };
01253 if( p_g.lgInbounds( 1, index ) )
01254 {
01255 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01256 size_type n = p_g.v.getvec( 1, index ).n;
01257 T* s = ( n > 0 ) ? &(*t)[i1][0] : NULL;
01258 if( i2 == npos )
01259 return iterator( s+n, s, s+n );
01260 else
01261 return iterator( s+i2, s, s+n );
01262 }
01263 else
01264 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01265 }
01266 iterator p_iterator(size_type i1, size_type i2, size_type i3) const
01267 {
01268 #ifdef _MSC_VER
01269
01270 # pragma warning( disable : 4127 )
01271 #endif
01272 if( lgBC )
01273 return p_iterator_bc( i1, i2, i3 );
01274 else
01275 {
01276 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01277 return iterator( &(*t)[i1][i2][i3] );
01278 }
01279 }
01280 iterator p_iterator_bc(size_type i1, size_type i2, size_type i3) const
01281 {
01282 size_type index[] = { i1, i2 };
01283 if( p_g.lgInbounds( 2, index ) )
01284 {
01285 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01286 size_type n = p_g.v.getvec( 2, index ).n;
01287 T* s = ( n > 0 ) ? &(*t)[i1][i2][0] : NULL;
01288 if( i3 == npos )
01289 return iterator( s+n, s, s+n );
01290 else
01291 return iterator( s+i3, s, s+n );
01292 }
01293 else
01294 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01295 }
01296 iterator p_iterator(size_type i1, size_type i2, size_type i3, size_type i4) const
01297 {
01298 #ifdef _MSC_VER
01299
01300 # pragma warning( disable : 4127 )
01301 #endif
01302 if( lgBC )
01303 return p_iterator_bc(i1, i2, i3, i4);
01304 else
01305 {
01306 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01307 return iterator( &(*t)[i1][i2][i3][i4] );
01308 }
01309 }
01310 iterator p_iterator_bc(size_type i1, size_type i2, size_type i3, size_type i4) const
01311 {
01312 size_type index[] = { i1, i2, i3 };
01313 if( p_g.lgInbounds( 3, index ) )
01314 {
01315 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01316 size_type n = p_g.v.getvec( 3, index ).n;
01317 T* s = ( n > 0 ) ? &(*t)[i1][i2][i3][0] : NULL;
01318 if( i4 == npos )
01319 return iterator( s+n, s, s+n );
01320 else
01321 return iterator( s+i4, s, s+n );
01322 }
01323 else
01324 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01325 }
01326 iterator p_iterator(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01327 {
01328 #ifdef _MSC_VER
01329
01330 # pragma warning( disable : 4127 )
01331 #endif
01332 if( lgBC )
01333 return p_iterator_bc(i1, i2, i3, i4, i5);
01334 else
01335 {
01336 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01337 return iterator( &(*t)[i1][i2][i3][i4][i5] );
01338 }
01339 }
01340 iterator p_iterator_bc(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01341 {
01342 size_type index[] = { i1, i2, i3, i4 };
01343 if( p_g.lgInbounds( 4, index ) )
01344 {
01345 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01346 size_type n = p_g.v.getvec( 4, index ).n;
01347 T* s = ( n > 0 ) ? &(*t)[i1][i2][i3][i4][0] : NULL;
01348 if( i5 == npos )
01349 return iterator( s+n, s, s+n );
01350 else
01351 return iterator( s+i5, s, s+n );
01352 }
01353 else
01354 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01355 }
01356 iterator p_iterator(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
01357 {
01358 #ifdef _MSC_VER
01359
01360 # pragma warning( disable : 4127 )
01361 #endif
01362 if( lgBC )
01363 return p_iterator_bc(i1, i2, i3, i4, i5, i6);
01364 else
01365 {
01366 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01367 return iterator( &(*t)[i1][i2][i3][i4][i5][i6] );
01368 }
01369 }
01370 iterator p_iterator_bc(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
01371 {
01372 size_type index[] = { i1, i2, i3, i4, i5 };
01373 if( p_g.lgInbounds( 5, index ) )
01374 {
01375 multi_arr<T,d,ALLOC,lgBC>* t = const_cast<multi_arr<T,d,ALLOC,lgBC>*>(this);
01376 size_type n = p_g.v.getvec( 5, index ).n;
01377 T* s = ( n > 0 ) ? &(*t)[i1][i2][i3][i4][i5][0] : NULL;
01378 if( i6 == npos )
01379 return iterator( s+n, s, s+n );
01380 else
01381 return iterator( s+i6, s, s+n );
01382 }
01383 else
01384 OUT_OF_RANGE( "multi_arr::p_iterator()" );
01385 }
01386
01387 public:
01388 const n_pointer<T,d,ALLOC,lgBC> n_ptr()
01389 {
01390 return n_pointer<T,d,ALLOC,lgBC>( p_ptr, p_g.st+1, &p_g.v );
01391 }
01392 const const_n_pointer<T,d,ALLOC,lgBC> n_ptr() const
01393 {
01394 return const_n_pointer<T,d,ALLOC,lgBC>( p_ptr, p_g.st+1, &p_g.v );
01395 }
01396 typedef n_pointer<T,d-1,ALLOC,lgBC> indexed_type;
01397 const indexed_type operator[] (size_type i)
01398 {
01399 return n_ptr()[i];
01400 }
01401 typedef const_n_pointer<T,d-1,ALLOC,lgBC> const_indexed_type;
01402 const const_indexed_type operator[] (size_type i) const
01403 {
01404 return n_ptr()[i];
01405 }
01406
01407 reference at(size_type i1, size_type i2)
01408 {
01409 size_type index[] = { i1, i2 };
01410 if( !p_g.lgInbounds( 2, index ) )
01411 OUT_OF_RANGE( "multi_arr::at()" );
01412 return (*this)[i1][i2];
01413 }
01414 const_reference at(size_type i1, size_type i2) const
01415 {
01416 size_type index[] = { i1, i2 };
01417 if( !p_g.lgInbounds( 2, index ) )
01418 OUT_OF_RANGE( "multi_arr::at()" );
01419 return (*this)[i1][i2];
01420 }
01421 reference at(size_type i1, size_type i2, size_type i3)
01422 {
01423 size_type index[] = { i1, i2, i3 };
01424 if( !p_g.lgInbounds( 3, index ) )
01425 OUT_OF_RANGE( "multi_arr::at()" );
01426 return (*this)[i1][i2][i3];
01427 }
01428 const_reference at(size_type i1, size_type i2, size_type i3) const
01429 {
01430 size_type index[] = { i1, i2, i3 };
01431 if( !p_g.lgInbounds( 3, index ) )
01432 OUT_OF_RANGE( "multi_arr::at()" );
01433 return (*this)[i1][i2][i3];
01434 }
01435 reference at(size_type i1, size_type i2, size_type i3, size_type i4)
01436 {
01437 size_type index[] = { i1, i2, i3, i4 };
01438 if( !p_g.lgInbounds( 4, index ) )
01439 OUT_OF_RANGE( "multi_arr::at()" );
01440 return (*this)[i1][i2][i3][i4];
01441 }
01442 const_reference at(size_type i1, size_type i2, size_type i3, size_type i4) const
01443 {
01444 size_type index[] = { i1, i2, i3, i4 };
01445 if( !p_g.lgInbounds( 4, index ) )
01446 OUT_OF_RANGE( "multi_arr::at()" );
01447 return (*this)[i1][i2][i3][i4];
01448 }
01449 reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01450 {
01451 size_type index[] = { i1, i2, i3, i4, i5 };
01452 if( !p_g.lgInbounds( 5, index ) )
01453 OUT_OF_RANGE( "multi_arr::at()" );
01454 return (*this)[i1][i2][i3][i4][i5];
01455 }
01456 const_reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01457 {
01458 size_type index[] = { i1, i2, i3, i4, i5 };
01459 if( !p_g.lgInbounds( 5, index ) )
01460 OUT_OF_RANGE( "multi_arr::at()" );
01461 return (*this)[i1][i2][i3][i4][i5];
01462 }
01463 reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6)
01464 {
01465 size_type index[] = { i1, i2, i3, i4, i5, i6 };
01466 if( !p_g.lgInbounds( 6, index ) )
01467 OUT_OF_RANGE( "multi_arr::at()" );
01468 return (*this)[i1][i2][i3][i4][i5][i6];
01469 }
01470 const_reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
01471 {
01472 size_type index[] = { i1, i2, i3, i4, i5, i6 };
01473 if( !p_g.lgInbounds( 6, index ) )
01474 OUT_OF_RANGE( "multi_arr::at()" );
01475 return (*this)[i1][i2][i3][i4][i5][i6];
01476 }
01477
01478 iterator ptr(size_type i1, size_type i2)
01479 {
01480 return p_iterator(i1, i2);
01481 }
01482 const_iterator ptr(size_type i1, size_type i2) const
01483 {
01484 return p_iterator(i1, i2);
01485 }
01486 iterator ptr(size_type i1, size_type i2, size_type i3)
01487 {
01488 return p_iterator(i1, i2, i3);
01489 }
01490 const_iterator ptr(size_type i1, size_type i2, size_type i3) const
01491 {
01492 return p_iterator(i1, i2, i3);
01493 }
01494 iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4)
01495 {
01496 return p_iterator(i1, i2, i3, i4);
01497 }
01498 const_iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4) const
01499 {
01500 return p_iterator(i1, i2, i3, i4);
01501 }
01502 iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01503 {
01504 return p_iterator(i1, i2, i3, i4, i5);
01505 }
01506 const_iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01507 {
01508 return p_iterator(i1, i2, i3, i4, i5);
01509 }
01510 iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6)
01511 {
01512 return p_iterator(i1, i2, i3, i4, i5, i6);
01513 }
01514 const_iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
01515 {
01516 return p_iterator(i1, i2, i3, i4, i5, i6);
01517 }
01518
01519 iterator begin(size_type i1)
01520 {
01521 return p_iterator(i1, 0);
01522 }
01523 const_iterator begin(size_type i1) const
01524 {
01525 return p_iterator(i1, 0);
01526 }
01527 iterator begin(size_type i1, size_type i2)
01528 {
01529 return p_iterator(i1, i2, 0);
01530 }
01531 const_iterator begin(size_type i1, size_type i2) const
01532 {
01533 return p_iterator(i1, i2, 0);
01534 }
01535 iterator begin(size_type i1, size_type i2, size_type i3)
01536 {
01537 return p_iterator(i1, i2, i3, 0);
01538 }
01539 const_iterator begin(size_type i1, size_type i2, size_type i3) const
01540 {
01541 return p_iterator(i1, i2, i3, 0);
01542 }
01543 iterator begin(size_type i1, size_type i2, size_type i3, size_type i4)
01544 {
01545 return p_iterator(i1, i2, i3, i4, 0);
01546 }
01547 const_iterator begin(size_type i1, size_type i2, size_type i3, size_type i4) const
01548 {
01549 return p_iterator(i1, i2, i3, i4, 0);
01550 }
01551 iterator begin(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01552 {
01553 return p_iterator(i1, i2, i3, i4, i5, 0);
01554 }
01555 const_iterator begin(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01556 {
01557 return p_iterator(i1, i2, i3, i4, i5, 0);
01558 }
01559
01560 iterator end(size_type i1)
01561 {
01562 #ifdef _MSC_VER
01563
01564 # pragma warning( disable : 4127 )
01565 #endif
01566 if( lgBC )
01567 return p_iterator(i1, npos);
01568 else
01569 return p_iterator(i1, p_g.v.d[i1].n);
01570 }
01571 const_iterator end(size_type i1) const
01572 {
01573 #ifdef _MSC_VER
01574
01575 # pragma warning( disable : 4127 )
01576 #endif
01577 if( lgBC )
01578 return p_iterator(i1, npos);
01579 else
01580 return p_iterator(i1, p_g.v.d[i1].n);
01581 }
01582 iterator end(size_type i1, size_type i2)
01583 {
01584 #ifdef _MSC_VER
01585
01586 # pragma warning( disable : 4127 )
01587 #endif
01588 if( lgBC )
01589 return p_iterator(i1, i2, npos);
01590 else
01591 return p_iterator(i1, i2, p_g.v.d[i1].d[i2].n);
01592 }
01593 const_iterator end(size_type i1, size_type i2) const
01594 {
01595 #ifdef _MSC_VER
01596
01597 # pragma warning( disable : 4127 )
01598 #endif
01599 if( lgBC )
01600 return p_iterator(i1, i2, npos);
01601 else
01602 return p_iterator(i1, i2, p_g.v.d[i1].d[i2].n);
01603 }
01604 iterator end(size_type i1, size_type i2, size_type i3)
01605 {
01606 #ifdef _MSC_VER
01607
01608 # pragma warning( disable : 4127 )
01609 #endif
01610 if( lgBC )
01611 return p_iterator(i1, i2, i3, npos);
01612 else
01613 return p_iterator(i1, i2, i3, p_g.v.d[i1].d[i2].d[i3].n);
01614 }
01615 const_iterator end(size_type i1, size_type i2, size_type i3) const
01616 {
01617 #ifdef _MSC_VER
01618
01619 # pragma warning( disable : 4127 )
01620 #endif
01621 if( lgBC )
01622 return p_iterator(i1, i2, i3, npos);
01623 else
01624 return p_iterator(i1, i2, i3, p_g.v.d[i1].d[i2].d[i3].n);
01625 }
01626 iterator end(size_type i1, size_type i2, size_type i3, size_type i4)
01627 {
01628 #ifdef _MSC_VER
01629
01630 # pragma warning( disable : 4127 )
01631 #endif
01632 if( lgBC )
01633 return p_iterator(i1, i2, i3, i4, npos);
01634 else
01635 return p_iterator(i1, i2, i3, i4, p_g.v.d[i1].d[i2].d[i3].d[i4].n);
01636 }
01637 const_iterator end(size_type i1, size_type i2, size_type i3, size_type i4) const
01638 {
01639 #ifdef _MSC_VER
01640
01641 # pragma warning( disable : 4127 )
01642 #endif
01643 if( lgBC )
01644 return p_iterator(i1, i2, i3, i4, npos);
01645 else
01646 return p_iterator(i1, i2, i3, i4, p_g.v.d[i1].d[i2].d[i3].d[i4].n);
01647 }
01648 iterator end(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01649 {
01650 #ifdef _MSC_VER
01651
01652 # pragma warning( disable : 4127 )
01653 #endif
01654 if( lgBC )
01655 return p_iterator(i1, i2, i3, i4, i5, npos);
01656 else
01657 return p_iterator(i1, i2, i3, i4, i5, p_g.v.d[i1].d[i2].d[i3].d[i4].d[i5].n);
01658 }
01659 const_iterator end(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01660 {
01661 #ifdef _MSC_VER
01662
01663 # pragma warning( disable : 4127 )
01664 #endif
01665 if( lgBC )
01666 return p_iterator(i1, i2, i3, i4, i5, npos);
01667 else
01668 return p_iterator(i1, i2, i3, i4, i5, p_g.v.d[i1].d[i2].d[i3].d[i4].d[i5].n);
01669 }
01670
01671 reference front(size_type i1)
01672 {
01673 return *begin(i1);
01674 }
01675 const_reference front(size_type i1) const
01676 {
01677 return *begin(i1);
01678 }
01679 reference front(size_type i1, size_type i2)
01680 {
01681 return *begin(i1, i2);
01682 }
01683 const_reference front(size_type i1, size_type i2) const
01684 {
01685 return *begin(i1, i2);
01686 }
01687 reference front(size_type i1, size_type i2, size_type i3)
01688 {
01689 return *begin(i1, i2, i3);
01690 }
01691 const_reference front(size_type i1, size_type i2, size_type i3) const
01692 {
01693 return *begin(i1, i2, i3);
01694 }
01695 reference front(size_type i1, size_type i2, size_type i3, size_type i4)
01696 {
01697 return *begin(i1, i2, i3, i4);
01698 }
01699 const_reference front(size_type i1, size_type i2, size_type i3, size_type i4) const
01700 {
01701 return *begin(i1, i2, i3, i4);
01702 }
01703 reference front(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01704 {
01705 return *begin(i1, i2, i3, i4, i5);
01706 }
01707 const_reference front(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01708 {
01709 return *begin(i1, i2, i3, i4, i5);
01710 }
01711
01712 reference back(size_type i1)
01713 {
01714 return *(end(i1) - 1);
01715 }
01716 const_reference back(size_type i1) const
01717 {
01718 return *(end(i1) - 1);
01719 }
01720 reference back(size_type i1, size_type i2)
01721 {
01722 return *(end(i1, i2) - 1);
01723 }
01724 const_reference back(size_type i1, size_type i2) const
01725 {
01726 return *(end(i1, i2) - 1);
01727 }
01728 reference back(size_type i1, size_type i2, size_type i3)
01729 {
01730 return *(end(i1, i2, i3) - 1);
01731 }
01732 const_reference back(size_type i1, size_type i2, size_type i3) const
01733 {
01734 return *(end(i1, i2, i3) - 1);
01735 }
01736 reference back(size_type i1, size_type i2, size_type i3, size_type i4)
01737 {
01738 return *(end(i1, i2, i3, i4) - 1);
01739 }
01740 const_reference back(size_type i1, size_type i2, size_type i3, size_type i4) const
01741 {
01742 return *(end(i1, i2, i3, i4) - 1);
01743 }
01744 reference back(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
01745 {
01746 return *(end(i1, i2, i3, i4, i5) - 1);
01747 }
01748 const_reference back(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
01749 {
01750 return *(end(i1, i2, i3, i4, i5) - 1);
01751 }
01752
01753 size_type size() const
01754 {
01755 return p_g.size;
01756 }
01757 size_type capacity() const
01758 {
01759 return p_g.size;
01760 }
01761 bool empty() const
01762 {
01763 for( int i=0; i < d-1; ++i )
01764 if( p_psl[i] != NULL )
01765 return false;
01766 return ( p_g.size == 0UL && p_dsl.size() == 0 );
01767 }
01768
01769 pointer data()
01770 {
01771 if( p_g.size > 0 )
01772 return get_ptr( p_dsl );
01773 else
01774 return NULL;
01775 }
01776 const_pointer data() const
01777 {
01778 if( p_g.size > 0 )
01779 return get_ptr( p_dsl );
01780 else
01781 return NULL;
01782 }
01783
01784 const multi_geom<d,ALLOC>& clone() const
01785 {
01786 return p_g;
01787 }
01788
01789 valarray<T>& vals()
01790 {
01791 return p_dsl;
01792 }
01793 const valarray<T>& vals() const
01794 {
01795 return p_dsl;
01796 }
01797 };
01798
01799
01800 typedef multi_arr<bool,2>::iterator mb2i;
01801 typedef multi_arr<bool,2>::const_iterator mb2ci;
01802 typedef multi_arr<bool,3>::iterator mb3i;
01803 typedef multi_arr<bool,3>::const_iterator mb3ci;
01804 typedef multi_arr<bool,4>::iterator mb4i;
01805 typedef multi_arr<bool,4>::const_iterator mb4ci;
01806 typedef multi_arr<bool,5>::iterator mb5i;
01807 typedef multi_arr<bool,5>::const_iterator mb5ci;
01808 typedef multi_arr<bool,6>::iterator mb6i;
01809 typedef multi_arr<bool,6>::const_iterator mb6ci;
01810
01811 typedef multi_arr<long,2>::iterator ml2i;
01812 typedef multi_arr<long,2>::const_iterator ml2ci;
01813 typedef multi_arr<long,3>::iterator ml3i;
01814 typedef multi_arr<long,3>::const_iterator ml3ci;
01815 typedef multi_arr<long,4>::iterator ml4i;
01816 typedef multi_arr<long,4>::const_iterator ml4ci;
01817 typedef multi_arr<long,5>::iterator ml5i;
01818 typedef multi_arr<long,5>::const_iterator ml5ci;
01819 typedef multi_arr<long,6>::iterator ml6i;
01820 typedef multi_arr<long,6>::const_iterator ml6ci;
01821
01822 typedef multi_arr<realnum,2>::iterator mr2i;
01823 typedef multi_arr<realnum,2>::const_iterator mr2ci;
01824 typedef multi_arr<realnum,3>::iterator mr3i;
01825 typedef multi_arr<realnum,3>::const_iterator mr3ci;
01826 typedef multi_arr<realnum,4>::iterator mr4i;
01827 typedef multi_arr<realnum,4>::const_iterator mr4ci;
01828 typedef multi_arr<realnum,5>::iterator mr5i;
01829 typedef multi_arr<realnum,5>::const_iterator mr5ci;
01830 typedef multi_arr<realnum,6>::iterator mr6i;
01831 typedef multi_arr<realnum,6>::const_iterator mr6ci;
01832
01833 typedef multi_arr<double,2>::iterator md2i;
01834 typedef multi_arr<double,2>::const_iterator md2ci;
01835 typedef multi_arr<double,3>::iterator md3i;
01836 typedef multi_arr<double,3>::const_iterator md3ci;
01837 typedef multi_arr<double,4>::iterator md4i;
01838 typedef multi_arr<double,4>::const_iterator md4ci;
01839 typedef multi_arr<double,5>::iterator md5i;
01840 typedef multi_arr<double,5>::const_iterator md5ci;
01841 typedef multi_arr<double,6>::iterator md6i;
01842 typedef multi_arr<double,6>::const_iterator md6ci;
01843
01844
01845 #define INSTANTIATE_MULTI_ARR( TYPE, BC ) \
01846 template class pntr<TYPE,BC>; \
01847 template class const_pntr<TYPE,BC>;
01848
01849 template<class T, bool lgBC=lgBOUNDSCHECKVAL>
01850 class flex_arr
01851 {
01852 size_t p_size;
01853 long p_begin;
01854 long p_end;
01855 bool p_init;
01856
01857 T* p_ptr_alloc;
01858 T* p_ptr;
01859
01860 public:
01861 typedef random_access_iterator_tag iterator_category;
01862 typedef T value_type;
01863 typedef T& reference;
01864 typedef const T& const_reference;
01865 typedef T* pointer;
01866 typedef const T* const_pointer;
01867 typedef long size_type;
01868 typedef ptrdiff_t difference_type;
01869 typedef pntr<T,lgBC> iterator;
01870 typedef const_pntr<T,lgBC> const_iterator;
01871
01872 private:
01873 void p_clear0()
01874 {
01875 delete[] p_ptr_alloc;
01876 p_ptr_alloc = NULL;
01877 }
01878 void p_clear1()
01879 {
01880 p_size = 0;
01881 p_begin = 0;
01882 p_end = 0;
01883 p_init = false;
01884 p_ptr_alloc = NULL;
01885 p_ptr = NULL;
01886 }
01887
01888 public:
01889 flex_arr()
01890 {
01891 p_clear1();
01892 }
01893 flex_arr(size_type begin, size_type end)
01894 {
01895 p_clear1();
01896 alloc( begin, end );
01897 }
01898 flex_arr(const flex_arr& f)
01899 {
01900 p_clear1();
01901 *this = f;
01902 }
01903 ~flex_arr()
01904 {
01905 p_clear0();
01906 }
01907 const flex_arr& operator= (const flex_arr& f)
01908 {
01909 if( &f != this )
01910 {
01911 clear();
01912 p_size = f.p_size;
01913 p_begin = f.p_begin;
01914 p_end = f.p_end;
01915 p_init = f.p_init;
01916 if( f.p_ptr_alloc != NULL )
01917 {
01918 p_ptr_alloc = new T[ p_size ];
01919 pointer p = p_ptr_alloc;
01920 const_pointer fp = f.p_ptr_alloc;
01921 for( size_type i=0; i < p_end-p_begin; ++i )
01922 *p++ = *fp++;
01923 p_ptr = p_ptr_alloc - p_begin;
01924 }
01925 }
01926 return *this;
01927 }
01928 void clear()
01929 {
01930 p_clear0();
01931 p_clear1();
01932 }
01933 void zero()
01934 {
01935 if( p_size > 0 )
01936 memset( p_ptr_alloc, 0, p_size*sizeof(T) );
01937 }
01938 void invalidate()
01939 {
01940 invalidate_array( p_ptr_alloc, p_size*sizeof(T) );
01941 }
01942 void state_do(FILE *out, bool lgGet)
01943 {
01944 if( lgGet )
01945 restore_state(out);
01946 else
01947 dump_state(out);
01948 }
01949
01950 void dump_state(FILE *out) const
01951 {
01952 do_dump_state( p_ptr_alloc, p_size, sizeof(T), out, MA_VERS[FLX_TYPE] );
01953 }
01954
01955 void restore_state(FILE *in)
01956 {
01957 do_restore_state( p_ptr_alloc, p_size, sizeof(T), in, MA_VERS[FLX_TYPE] );
01958 }
01959
01960
01961 void reserve(size_type size)
01962 {
01963
01964 clear();
01965 #ifdef _MSC_VER
01966
01967 # pragma warning( disable : 4127 )
01968 #endif
01969 if( size > 0 )
01970 {
01971 ASSERT( p_ptr_alloc == NULL );
01972 p_ptr_alloc = new T[size];
01973 p_size = (size_t)size;
01974 }
01975 }
01976
01977
01978 void alloc(size_type begin, size_type end)
01979 {
01980 if( (size_t)max(end-begin,0) > p_size )
01981 {
01982 clear();
01983
01984 ASSERT( p_ptr_alloc == NULL );
01985 p_ptr_alloc = new T[end-begin];
01986 p_ptr = p_ptr_alloc - begin;
01987 p_size = (size_t)(end-begin);
01988 }
01989 else
01990 {
01991
01992 p_ptr = p_ptr_alloc - begin;
01993 }
01994 p_begin = begin;
01995 p_end = end;
01996 p_init = true;
01997 }
01998
01999 void realloc(size_type end)
02000 {
02001 ASSERT( p_init );
02002 if( (size_t)max(end-p_begin,0) > p_size )
02003 {
02004
02005 T* nptr_alloc = new T[end-p_begin];
02006 T* nptr = nptr_alloc - p_begin;
02007
02008
02009
02010
02011 if( p_ptr_alloc != NULL && p_ptr != NULL )
02012 {
02013 for( size_type i=p_begin; i < p_end; ++i )
02014 nptr[i] = p_ptr[i];
02015 delete[] p_ptr_alloc;
02016 }
02017 p_ptr_alloc = nptr_alloc;
02018 p_ptr = nptr;
02019 p_size = (size_t)(end-p_begin);
02020 }
02021 p_end = end;
02022 }
02023
02024 private:
02025
02026 pointer p_pointer(size_type i) const
02027 {
02028 return p_ptr+i;
02029 }
02030
02031 iterator p_iterator(size_type i) const
02032 {
02033 #ifdef _MSC_VER
02034
02035 # pragma warning( disable : 4127 )
02036 #endif
02037 if( lgBC )
02038 return iterator( p_pointer(i), p_pointer(p_begin), p_pointer(p_end) );
02039 else
02040 return iterator( p_pointer(i) );
02041 }
02042
02043 bool p_lgInbounds(size_type i) const
02044 {
02045 return ( i >= p_begin && i < p_end );
02046 }
02047
02048 reference p_index(size_type i) const
02049 {
02050 #ifdef _MSC_VER
02051
02052 # pragma warning( disable : 4127 )
02053 #endif
02054 if( lgBC )
02055 {
02056 if( ! p_lgInbounds( i ) )
02057 OUT_OF_RANGE( "flex_arr::p_index()" );
02058 }
02059 return *p_pointer(i);
02060 }
02061
02062 public:
02063 reference operator[] (size_type i)
02064 {
02065 return reference(p_index(i));
02066 }
02067 const_reference operator[] (size_type i) const
02068 {
02069 return const_reference(p_index(i));
02070 }
02071
02072 reference at(size_type i)
02073 {
02074 if( ! p_lgInbounds(i) )
02075 OUT_OF_RANGE( "flex_arr::at()" );
02076 return (*this)[i];
02077 }
02078 const_reference at(size_type i) const
02079 {
02080 if( ! p_lgInbounds(i) )
02081 OUT_OF_RANGE( "flex_arr::at()" );
02082 return (*this)[i];
02083 }
02084
02085 iterator ptr(size_type i)
02086 {
02087 return iterator(p_iterator(i));
02088 }
02089 const_iterator ptr(size_type i) const
02090 {
02091 return const_iterator(p_iterator(i));
02092 }
02093
02094
02095
02096 iterator begin()
02097 {
02098 return ptr(p_begin);
02099 }
02100 const_iterator begin() const
02101 {
02102 return ptr(p_begin);
02103 }
02104
02105 iterator end()
02106 {
02107 return ptr(p_end);
02108 }
02109 const_iterator end() const
02110 {
02111 return ptr(p_end);
02112 }
02113
02114 reference front()
02115 {
02116 return *begin();
02117 }
02118 const_reference front() const
02119 {
02120 return *begin();
02121 }
02122
02123 reference back()
02124 {
02125 return *(end()-1);
02126 }
02127 const_reference back() const
02128 {
02129 return *(end()-1);
02130 }
02131
02132 size_type size() const
02133 {
02134 return max(p_end-p_begin,0);
02135 }
02136 size_type capacity() const
02137 {
02138 return p_size;
02139 }
02140 bool empty() const
02141 {
02142 return ( size() == 0 );
02143 }
02144
02145 pointer data()
02146 {
02147 return p_ptr_alloc;
02148 }
02149 const_pointer data() const
02150 {
02151 return p_ptr_alloc;
02152 }
02153 };
02154
02155
02156 typedef flex_arr<bool>::iterator fabi;
02157 typedef flex_arr<bool>::const_iterator fabci;
02158 typedef flex_arr<long>::iterator fali;
02159 typedef flex_arr<long>::const_iterator falci;
02160 typedef flex_arr<realnum>::iterator fari;
02161 typedef flex_arr<realnum>::const_iterator farci;
02162 typedef flex_arr<double>::iterator fadi;
02163 typedef flex_arr<double>::const_iterator fadci;
02164
02165 #endif