cloudy trunk
Loading...
Searching...
No Matches
container_classes.h
Go to the documentation of this file.
1/* This file is part of Cloudy and is copyright (C)1978-2013 by Gary J. Ferland and
2 * others. For conditions of distribution and use see copyright notice in license.txt */
3
4#ifndef CONTAINER_CLASSES_H_
5#define CONTAINER_CLASSES_H_
6
7void do_dump_state(const void* buf, size_t nelem, size_t size, FILE* out, int32 magic);
8void do_restore_state(void* buf, size_t nelem, size_t size, FILE *in, int32 magic);
9
16
17// magic numbers to identify each memory layout
18static const int32 MA_VERS[ML_TOP] = { 120070905, 220070803, 320071126 };
19
20#ifdef USE_C_TYPE
21#define MEM_LAYOUT_VAL C_TYPE
22#else
23#define MEM_LAYOUT_VAL ARPA_TYPE
24#endif
25
26#ifdef BOUNDS_CHECK
27#define lgBOUNDSCHECKVAL true
28#else
29#define lgBOUNDSCHECKVAL false
30#endif
31
34template<class T, bool lgBC>
36{
37 static const int p_nd = lgBC ? 3 : 1;
38 T* p_p[p_nd]; // p[0] current pointer, p[1] lower bound, p[2] upper bound
39
40 T* p_index_checked ( const ptrdiff_t n ) const
41 {
42 T* t = p_p[0]+n;
43#ifdef _MSC_VER
44 /* disable warning that conditional expression is constant, true or false in if */
45# pragma warning( disable : 4127 )
46#endif
47 if( lgBC )
48 {
49 if( t < p_p[1] || t >= p_p[2] )
50 OUT_OF_RANGE( "basic_pntr::p_index_checked()" );
51 }
52 return t;
53 }
54 void p_set_vals( T* p0, T* p1, T* p2 )
55 {
56#ifdef _MSC_VER
57 /* disable warning that conditional expression is constant, true or false in if */
58# pragma warning( disable : 4127 )
59#endif
60 if( lgBC )
61 {
62 p_p[0] = p0; p_p[1] = p1; p_p[2] = p2;
63 }
64 else
65 p_p[0] = p0;
66 }
67public:
68 typedef random_access_iterator_tag iterator_category;
69 typedef T value_type;
70 typedef T& reference;
71 typedef const T& const_reference;
72 typedef T* pointer;
73 typedef const T* const_pointer;
74 typedef size_t size_type;
75 typedef ptrdiff_t difference_type;
76
77 // constructors
78 basic_pntr( T* p0, T* p1, T* p2 )
79 {
80 p_set_vals( p0, p1, p2 );
81 }
82 basic_pntr( T* p0 )
83 {
84 p_set_vals( p0, NULL, NULL );
85 }
87 {
88 p_set_vals( NULL, NULL, NULL );
89 }
91 {
92 *this = t;
93 }
94 // protected destructor (to prevent direct instantiation or destruction via basic_pntr*, see Alexandrescu p13)
95protected:
97public:
98 // pre-increment
100 {
101 ++p_p[0];
102 return *this;
103 }
104 // pre-decrement
106 {
107 --p_p[0];
108 return *this;
109 }
110 // define operators for += and -=, normal arithmetic is defined separately in
111 // the derived classes; it cannot be done here since they would require implicit
112 // conversion from basic_pntr -> pntr or const_pntr to work; this would also create
113 // an implicit and silent conversion from const_pntr -> pntr, which is illegal...
114 basic_pntr& operator+= ( const ptrdiff_t n ) { p_p[0] += n; return *this; }
115 basic_pntr& operator-= ( const ptrdiff_t n ) { p_p[0] -= n; return *this; }
116 // dereference
117 T& operator* () const
118 {
119 return *(p_index_checked(0));
120 }
121 T* operator-> () const
122 {
123 return p_index_checked(0);
124 }
125 T& operator[] ( const ptrdiff_t n ) const
126 {
127 return *(p_index_checked(n));
128 }
129 // finally, define the boolean operators...
130 bool operator== ( const basic_pntr& t ) const { return p_p[0] == t.p_p[0]; }
131 bool operator!= ( const basic_pntr& t ) const { return p_p[0] != t.p_p[0]; }
132 bool operator< ( const basic_pntr& t ) const { return p_p[0] < t.p_p[0]; }
133 bool operator<= ( const basic_pntr& t ) const { return p_p[0] <= t.p_p[0]; }
134 bool operator> ( const basic_pntr& t ) const { return p_p[0] > t.p_p[0]; }
135 bool operator>= ( const basic_pntr& t ) const { return p_p[0] >= t.p_p[0]; }
136};
137
139template<class T, bool lgBC>
140class pntr : public basic_pntr<T,lgBC>
141{
142public:
143 // constructors are not inherited, so define them again
144 pntr( T* p0 ) : basic_pntr<T,lgBC>( p0 ) {}
145 pntr( T* p0, T* p1, T* p2 ) : basic_pntr<T,lgBC>( p0, p1, p2 ) {}
146 pntr() {}
147 // the increment / decrement operators need to be recast...
148 // otherwise expressions like p = ++q would be illegal for iterators...
149 pntr& operator++ () { return static_cast<pntr&>(basic_pntr<T,lgBC>::operator++()); }
150 const pntr operator++ (int) { pntr t = *this; ++(*this); return t; }
151 pntr& operator-- () { return static_cast<pntr&>(basic_pntr<T,lgBC>::operator--()); }
152 const pntr operator-- (int) { pntr t = *this; --(*this); return t; }
153 // define p+n, p-n, p-q
154 const pntr operator+ ( const ptrdiff_t n ) const { pntr s = *this; s += n; return s; }
155 const pntr operator- ( const ptrdiff_t n ) const { pntr s = *this; s -= n; return s; }
156 ptrdiff_t operator- ( const pntr& t ) const { return &(*this[0]) - &t[0]; }
157};
158
159// this defines n+p
160template<class T, bool lgBC>
161inline const pntr<T,lgBC> operator+ ( const ptrdiff_t n, const pntr<T,lgBC>& t )
162{
163 pntr<T,lgBC> s = t;
164 s += n;
165 return s;
166}
167
169template<class T, bool lgBC>
170class const_pntr : public basic_pntr<T,lgBC>
171{
172public:
173 // constructors are not inherited, so define them again
174 const_pntr( T* p0 ) : basic_pntr<T,lgBC>( p0 ) {}
175 const_pntr( T* p0, T* p1, T* p2 ) : basic_pntr<T,lgBC>( p0, p1, p2 ) {}
177 // make sure we can assign a pntr to a const_pntr by creating an implicit conversion to const_pntr
178 const_pntr( const pntr<T,lgBC>& t ) : basic_pntr<T,lgBC>( t ) {}
179 // the increment / decrement operators need to be recast...
180 // otherwise expressions like *p++ = 1. would be legal for const_iterators...
182 const const_pntr operator++ (int) { const_pntr t = *this; ++(*this); return t; }
184 const const_pntr operator-- (int) { const_pntr t = *this; --(*this); return t; }
185 const_pntr& operator+= ( const ptrdiff_t n )
186 {
187 return static_cast<const_pntr&>(basic_pntr<T,lgBC>::operator+=(n));
188 }
189 const_pntr& operator-= ( const ptrdiff_t n )
190 {
191 return static_cast<const_pntr&>(basic_pntr<T,lgBC>::operator-=(n));
192 }
193 // the dereference operators need to be recast...
194 const T& operator* () const { return static_cast<const T&>(basic_pntr<T,lgBC>::operator*()); }
195 const T* operator-> () const { return static_cast<const T*>(basic_pntr<T,lgBC>::operator->()); }
196 const T& operator[] ( const ptrdiff_t n ) const
197 {
198 return static_cast<const T&>(basic_pntr<T,lgBC>::operator[](n));
199 }
200 // define p+n, p-n, p-q
201 const const_pntr operator+ ( const ptrdiff_t n ) const { const_pntr s = *this; s += n; return s; }
202 const const_pntr operator- ( const ptrdiff_t n ) const { const_pntr s = *this; s -= n; return s; }
203 ptrdiff_t operator- ( const const_pntr& t ) const { return &(*this[0]) - &t[0]; }
204};
205
206// this defines n+p
207template<class T, bool lgBC>
208inline const const_pntr<T,lgBC> operator+ ( const ptrdiff_t n, const const_pntr<T,lgBC>& t )
209{
210 const_pntr<T,lgBC> s = t;
211 s += n;
212 return s;
213}
214
217{
218 typedef size_t size_type;
219
222
223private:
224 void p_clear0()
225 {
226 if( d != NULL )
227 {
228 for( size_type i = 0; i < n; ++i )
229 d[i].clear();
230 delete[] d;
231 }
232 }
233 void p_clear1()
234 {
235 n = 0;
236 d = NULL;
237 }
238
239public:
241 {
242 p_clear1();
243 }
245 {
246 p_clear1();
247 *this = m;
248 }
250 {
251 p_clear0();
252 }
253 void clear()
254 {
255 p_clear0();
256 p_clear1();
257 }
258 const tree_vec& operator= (const tree_vec& m)
259 {
260 if( &m != this )
261 {
262 clear();
263 n = m.n;
264 if( m.d != NULL )
265 {
266 d = new tree_vec[n];
267 tree_vec *p = d;
268 const tree_vec *mp = m.d;
269 for( size_type i = 0; i < n; ++i )
270 *p++ = *mp++;
271 }
272 }
273 return *this;
274 }
275 tree_vec& getvec(const size_type i, const size_type index[])
276 {
277 if( i == 0 )
278 return *this;
279 else
280 return getvec(i-1,index).d[index[i-1]];
281 }
282 const tree_vec& getvec(const size_type i, const size_type index[]) const
283 {
284 if( i == 0 )
285 return *this;
286 else
287 return getvec(i-1,index).d[index[i-1]];
288 }
289};
290
293template<int d,mem_layout ALLOC=MEM_LAYOUT_VAL>
295{
296public:
297 typedef size_t size_type;
298
300
305
306private:
307 void p_clear0()
308 {
309 v.clear();
310 }
311 void p_clear1()
312 {
313 size = 0;
314 for( int i=0; i < d; ++i )
315 {
316 s[i] = 0;
317 st[i] = 0;
318 nsl[i] = 0;
319 }
320 }
321
322public:
324 {
325 p_clear1();
326 }
328 {
329 p_clear1();
330 *this = m;
331 }
333 {
334 p_clear0();
335 }
336 void clear()
337 {
338 p_clear0();
339 p_clear1();
340 }
342 {
343 if( &m != this )
344 {
345 clear();
346 v = m.v;
347 size = m.size;
348 for( int i=0; i < d; ++i )
349 {
350 s[i] = m.s[i];
351 st[i] = m.st[i];
352 nsl[i] = m.nsl[i];
353 }
354 }
355 return *this;
356 }
357 bool lgInbounds(const size_type n, const size_type index[]) const
358 {
359 if( n != 0 )
360 return ( lgInbounds(n-1,index) && index[n-1] < v.getvec(n-1,index).n );
361 else
362 return true;
363 }
364 void reserve(const size_type n, const size_type index[])
365 {
366 ASSERT( n <= d && index[n-1] > 0 && lgInbounds( n-1, index ) );
367
368 tree_vec& w = v.getvec( n-1, index );
369 if( d > n )
370 {
371 ASSERT( w.d == NULL );
372 w.d = new tree_vec[ index[n-1] ];
373 }
374 w.n = index[n-1];
375 s[n-1] = max(s[n-1],index[n-1]);
376 nsl[n-1] += index[n-1];
377 }
378 void reserve_recursive(const size_type n, size_type index[])
379 {
380 if( n == 0 )
381 {
382 reserve( n+1, index );
383 if( n+1 < d )
384 reserve_recursive( n+1, index );
385 }
386 else
387 {
388 size_type top = index[n-1];
389 for( size_type i=0; i < top; ++i )
390 {
391 index[n-1] = i;
392 reserve( n+1, index );
393 if( n+1 < d )
394 reserve_recursive( n+1, index );
395 }
396 index[n-1] = top;
397 }
398 }
399 void finalize(void)
400 {
401#ifdef _MSC_VER
402 /* disable warning that conditional expression is constant, true or false in if */
403# pragma warning( disable : 4127 )
404#endif
405
406 STATIC_ASSERT ( ALLOC == C_TYPE || ALLOC == ARPA_TYPE );
407
408 if( ALLOC == ARPA_TYPE )
409 {
410 size_type n1[d], n2[d];
411 for( int dim=0; dim < d; ++dim )
412 n1[dim] = n2[dim] = 0L;
413 // sanity checks
414 p_setupArray( n1, n2, &v, 0 );
415 for( int dim=0; dim < d-1; ++dim )
416 ASSERT( n1[dim] == nsl[dim] && n2[dim] == nsl[dim+1] );
417 size = nsl[d-1];
418 }
419 else if( ALLOC == C_TYPE )
420 {
421 st[d-1] = s[d-1];
422 for( int i = d-2; i >= 0; --i )
423 st[i] = st[i+1]*s[i];
424 size = st[0];
425 }
426 else
427 {
429 }
430 }
431
432private:
433 void p_setupArray( size_type n1[], size_type n2[], const tree_vec* w, int l )
434 {
435 for( size_type i=0; i < w->n; ++i )
436 {
437 n1[l]++;
438 if( l < d-2 )
439 {
440 p_setupArray( n1, n2, &w->d[i], l+1 );
441 }
442 n2[l] += w->d[i].n;
443 }
444 }
445};
446
447
448//
551//
552
553
554// forward definitions
555template<class T, int N, mem_layout ALLOC, bool lgBC> class n_pointer;
556template<class T, int N, mem_layout ALLOC, bool lgBC> class const_n_pointer;
557
558template<class T, int N>
559class n_pointer<T,N,ARPA_TYPE,false>
560{
561 T* p_p;
562 const size_t* p_st;
563 const tree_vec* p_v;
564public:
565 typedef n_pointer<T,N-1,ARPA_TYPE,false> value_type;
566 n_pointer(T* p, const size_t* st=NULL, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
567 const value_type operator[] (const size_t i) const
568 {
569 return value_type( *((T**)p_p+i) );
570 }
571};
572
573template<class T, int N>
574class n_pointer<T,N,C_TYPE,false>
575{
576 T* p_p;
577 const size_t* p_st;
578 const tree_vec* p_v;
579public:
580 typedef n_pointer<T,N-1,C_TYPE,false> value_type;
581 n_pointer(T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
582 const value_type operator[] (const size_t i) const
583 {
584 return value_type( p_p+i*p_st[0], p_st+1 );
585 }
586};
587
588template<class T>
589class n_pointer<T,1,ARPA_TYPE,false>
590{
591 T* p_p;
592 const size_t* p_st;
593 const tree_vec* p_v;
594public:
595 typedef T value_type;
596 n_pointer(T* p, const size_t* st=NULL, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
597 value_type& operator[] (const size_t i) const
598 {
599 return *(p_p + i);
600 }
601};
602
603template<class T>
604class n_pointer<T,1,C_TYPE,false>
605{
606 T* p_p;
607 const size_t* p_st;
608 const tree_vec* p_v;
609public:
610 typedef T value_type;
611 n_pointer(T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
612 value_type& operator[] (const size_t i) const
613 {
614 return *(p_p + i);
615 }
616};
617
618template<class T, int N>
619class n_pointer<T,N,ARPA_TYPE,true>
620{
621 T* p_p;
622 const size_t* p_st;
623 const tree_vec* p_v;
624public:
625 typedef n_pointer<T,N-1,ARPA_TYPE,true> value_type;
626 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
627 const value_type operator[] (const size_t i) const
628 {
629 if( i >= p_v->n )
630 OUT_OF_RANGE( "n_pointer::operator[]" );
631 return value_type( *((T**)p_p+i), NULL, &p_v->d[i] );
632 }
633};
634
635template<class T, int N>
636class n_pointer<T,N,C_TYPE,true>
637{
638 T* p_p;
639 const size_t* p_st;
640 const tree_vec* p_v;
641public:
642 typedef n_pointer<T,N-1,C_TYPE,true> value_type;
643 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
644 const value_type operator[] (const size_t i) const
645 {
646 if( i >= p_v->n )
647 OUT_OF_RANGE( "n_pointer::operator[]" );
648 return value_type( p_p+i*p_st[0], p_st+1, &p_v->d[i] );
649 }
650};
651
652template<class T>
653class n_pointer<T,1,ARPA_TYPE,true>
654{
655 T* p_p;
656 const size_t* p_st;
657 const tree_vec* p_v;
658public:
659 typedef T value_type;
660 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
661 value_type& operator[] (const size_t i) const
662 {
663 if( i >= p_v->n )
664 OUT_OF_RANGE( "n_pointer::operator[]" );
665 return *(p_p + i);
666 }
667};
668
669template<class T>
670class n_pointer<T,1,C_TYPE,true>
671{
672 T* p_p;
673 const size_t* p_st;
674 const tree_vec* p_v;
675public:
676 typedef T value_type;
677 n_pointer(T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
678 value_type& operator[] (const size_t i) const
679 {
680 if( i >= p_v->n )
681 OUT_OF_RANGE( "n_pointer::operator[]" );
682 return *(p_p + i);
683 }
684};
685
686template<class T, int N>
688{
689 const T* p_p;
690 const size_t* p_st;
691 const tree_vec* p_v;
692public:
694 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) {}
695 const value_type operator[] (const size_t i) const
696 {
697 return value_type( *((T**)p_p+i) );
698 }
699};
700
701template<class T, int N>
703{
704 const T* p_p;
705 const size_t* p_st;
706 const tree_vec* p_v;
707public:
708 typedef const_n_pointer<T,N-1,C_TYPE,false> value_type;
709 const_n_pointer(const T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
710 const value_type operator[] (const size_t i) const
711 {
712 return value_type( p_p+i*p_st[0], p_st+1 );
713 }
714};
715
716template<class T>
718{
719 const T* p_p;
720 const size_t* p_st;
721 const tree_vec* p_v;
722public:
723 typedef const T value_type;
724 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) {}
725 value_type& operator[] (const size_t i) const
726 {
727 return *(p_p + i);
728 }
729};
730
731template<class T>
732class const_n_pointer<T,1,C_TYPE,false>
733{
734 const T* p_p;
735 const size_t* p_st;
736 const tree_vec* p_v;
737public:
738 typedef const T value_type;
739 const_n_pointer(const T* p, const size_t* st, const tree_vec* v=NULL) : p_p(p), p_st(st), p_v(v) {}
740 value_type& operator[] (const size_t i) const
741 {
742 return *(p_p + i);
743 }
744};
745
746template<class T, int N>
748{
749 const T* p_p;
750 const size_t* p_st;
751 const tree_vec* p_v;
752public:
754 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
755 const value_type operator[] (const size_t i) const
756 {
757 if( i >= p_v->n )
758 OUT_OF_RANGE( "const_n_pointer::operator[]" );
759 return value_type( *((T**)p_p+i), NULL, &p_v->d[i] );
760 }
761};
762
763template<class T, int N>
765{
766 const T* p_p;
767 const size_t* p_st;
768 const tree_vec* p_v;
769public:
771 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
772 const value_type operator[] (const size_t i) const
773 {
774 if( i >= p_v->n )
775 OUT_OF_RANGE( "const_n_pointer::operator[]" );
776 return value_type( p_p+i*p_st[0], p_st+1, &p_v->d[i] );
777 }
778};
779
780template<class T>
782{
783 const T* p_p;
784 const size_t* p_st;
785 const tree_vec* p_v;
786public:
787 typedef const T value_type;
788 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
789 value_type& operator[] (const size_t i) const
790 {
791 if( i >= p_v->n )
792 OUT_OF_RANGE( "const_n_pointer::operator[]" );
793 return *(p_p + i);
794 }
795};
796
797template<class T>
798class const_n_pointer<T,1,C_TYPE,true>
799{
800 const T* p_p;
801 const size_t* p_st;
802 const tree_vec* p_v;
803public:
804 typedef const T value_type;
805 const_n_pointer(const T* p, const size_t* st, const tree_vec* v) : p_p(p), p_st(st), p_v(v) {}
806 value_type& operator[] (const size_t i) const
807 {
808 if( i >= p_v->n )
809 OUT_OF_RANGE( "const_n_pointer::operator[]" );
810 return *(p_p + i);
811 }
812};
813
814//
938//
939
940template<class T, int d, mem_layout ALLOC=MEM_LAYOUT_VAL, bool lgBC=lgBOUNDSCHECKVAL>
942{
943 // ancillary data describing the memory layout of the multi_arr
945 T** p_psl[d-1]; // pointer arrays for ARPA structure
946 valarray<T> p_dsl; // this contains the actual data
947 T* p_ptr; // main pointer to allocated structure
948 T** p_ptr2; // used in debugger to get access to internal representation
949 T*** p_ptr3;
950 T**** p_ptr4;
951 T***** p_ptr5;
952 T****** p_ptr6;
953
954public:
955 typedef random_access_iterator_tag iterator_category;
956 typedef T value_type;
957 typedef T& reference;
958 typedef const T& const_reference;
959 typedef T* pointer;
960 typedef const T* const_pointer;
961 typedef size_t size_type;
962 typedef ptrdiff_t difference_type;
965
966private:
967 static const size_type npos = static_cast<size_type>(-1);
968
969 void p_clear0()
970 {
971 p_g.clear();
972 for( int i=0; i < d-1; ++i )
973 delete[] p_psl[i];
974 p_dsl.resize(0);
975 }
976 void p_clear1()
977 {
978 for( int i=0; i < d-1; ++i )
979 p_psl[i] = NULL;
980 p_ptr = NULL;
981 p_ptr2 = NULL;
982 p_ptr3 = NULL;
983 p_ptr4 = NULL;
984 p_ptr5 = NULL;
985 p_ptr6 = NULL;
986 }
987
988public:
990 {
991 p_clear1();
992 }
994 {
995 p_clear1();
996 alloc( g );
997 }
999 {
1000 p_clear1();
1001 size_type index[] = { d1, d2 };
1002 alloc( index );
1003 }
1005 {
1006 p_clear1();
1007 size_type index[] = { d1, d2, d3 };
1008 alloc( index );
1009 }
1011 {
1012 p_clear1();
1013 size_type index[] = { d1, d2, d3, d4 };
1014 alloc( index );
1015 }
1017 {
1018 p_clear1();
1019 size_type index[] = { d1, d2, d3, d4, d5 };
1020 alloc( index );
1021 }
1023 {
1024 p_clear1();
1025 size_type index[] = { d1, d2, d3, d4, d5, d6 };
1026 alloc( index );
1027 }
1029 {
1030 p_clear1();
1031 *this = m;
1032 }
1034 {
1035 p_clear0();
1036 }
1037 void clear()
1038 {
1039 p_clear0();
1040 p_clear1();
1041 }
1043 {
1044 if( &m != this )
1045 {
1046 alloc( m.p_g );
1047 vals() = m.vals();
1048 }
1049 return *this;
1050 }
1051 void zero()
1052 {
1053 ASSERT( vals().size() == p_g.size );
1054 if( p_g.size > 0 )
1055 memset( data(), 0, p_g.size*sizeof(T) );
1056 }
1058 {
1059 ASSERT( vals().size() == p_g.size );
1060 invalidate_array( data(), p_g.size*sizeof(T) );
1061 }
1062 void state_do(FILE *io, bool lgGet)
1063 {
1064 if( lgGet )
1065 restore_state(io);
1066 else
1067 dump_state(io);
1068 }
1069 // dump the array to a file in binary format
1070 void dump_state(FILE *out) const
1071 {
1072 do_dump_state( data(), p_g.size, sizeof(T), out, MA_VERS[ALLOC] );
1073 }
1074 // restore the array from a file in binary format
1075 void restore_state(FILE *in)
1076 {
1077 do_restore_state( data(), p_g.size, sizeof(T), in, MA_VERS[ALLOC] );
1078 }
1079
1081 {
1082 ASSERT( vals().size() == 0 );
1083 const size_type index[] = { i1 };
1084 p_g.reserve( 1, index );
1085 }
1087 {
1088 ASSERT( vals().size() == 0 );
1089 const size_type index[] = { i1, i2 };
1090 p_g.reserve( 2, index );
1091 }
1093 {
1094 ASSERT( vals().size() == 0 );
1095 const size_type index[] = { i1, i2, i3 };
1096 p_g.reserve( 3, index );
1097 }
1099 {
1100 ASSERT( vals().size() == 0 );
1101 const size_type index[] = { i1, i2, i3, i4 };
1102 p_g.reserve( 4, index );
1103 }
1105 {
1106 ASSERT( vals().size() == 0 );
1107 const size_type index[] = { i1, i2, i3, i4, i5 };
1108 p_g.reserve( 5, index );
1109 }
1111 {
1112 ASSERT( vals().size() == 0 );
1113 const size_type index[] = { i1, i2, i3, i4, i5, i6 };
1114 p_g.reserve( 6, index );
1115 }
1116 void alloc()
1117 {
1118 p_g.finalize();
1119#ifdef _MSC_VER
1120 /* disable warning that conditional expression is constant, true or false in if */
1121# pragma warning( disable : 4127 )
1122#endif
1123 STATIC_ASSERT ( ALLOC == C_TYPE || ALLOC == ARPA_TYPE );
1124
1125 if( ALLOC == ARPA_TYPE )
1126 {
1127 size_type n1[d], n2[d];
1128 // allocate the pointer arrays ( p_psl[0..d-2] ) and data ( p_dsl )
1129 for( int dim=0; dim < d; ++dim )
1130 {
1131 n1[dim] = n2[dim] = 0L;
1132 if( dim != d-1 )
1133 {
1134 ASSERT( p_psl[dim] == NULL );
1135 if( p_g.nsl[dim] > 0 )
1136 p_psl[dim] = new T*[ p_g.nsl[dim] ];
1137 }
1138 else
1139 {
1140 ASSERT( p_dsl.size() == 0 );
1141 p_dsl.resize( p_g.nsl[dim] );
1142 }
1143 }
1144 // now initialize all the pointer arrays
1145 p_setupArray( n1, n2, &p_g.v, 0 );
1146 p_ptr = (T*)p_psl[0];
1147 }
1148 else if( ALLOC == C_TYPE )
1149 {
1150 for( int i=0; i < d-1; ++i )
1151 p_psl[i] = NULL;
1152 ASSERT( p_dsl.size() == 0 );
1153 p_dsl.resize( p_g.st[0] );
1154 p_ptr = &p_dsl[0];
1155 }
1156 else
1157 {
1158 TotalInsanity();
1159 }
1160 p_ptr2 = (T**)p_ptr;
1161 p_ptr3 = (T***)p_ptr;
1162 p_ptr4 = (T****)p_ptr;
1163 p_ptr5 = (T*****)p_ptr;
1164 p_ptr6 = (T******)p_ptr;
1165 }
1166 // clone the geometry from another multi_arr
1168 {
1169 if( &g != &p_g )
1170 {
1171 clear();
1172 p_g = g;
1173 alloc();
1174 }
1175 }
1176 // set up a rectangular block of data with dimensions d1 x d2 x ....
1178 {
1179 size_type index[] = { d1, d2 };
1180 alloc( index );
1181 }
1183 {
1184 size_type index[] = { d1, d2, d3 };
1185 alloc( index );
1186 }
1188 {
1189 size_type index[] = { d1, d2, d3, d4 };
1190 alloc( index );
1191 }
1193 {
1194 size_type index[] = { d1, d2, d3, d4, d5 };
1195 alloc( index );
1196 }
1198 {
1199 size_type index[] = { d1, d2, d3, d4, d5, d6 };
1200 alloc( index );
1201 }
1202 void alloc(size_type index[])
1203 {
1204 for( int n=0; n < d; n++ )
1205 ASSERT( index[n] > 0 );
1206 clear();
1207 p_g.reserve_recursive( 0, index );
1208 alloc();
1209 }
1210
1211private:
1212 // helper routine for alloc(), this fills in the pointer arrays for the ARPA layout
1213 void p_setupArray( size_type n1[], size_type n2[], const tree_vec* g, int l )
1214 {
1215 // this test is needed to stop g++ 4.6.0 from complaining about out-of-bounds access below
1216 if( l < 0 )
1217 TotalInsanity();
1218
1219 for( size_type i=0; i < g->n; ++i )
1220 {
1221 if( l < d-2 )
1222 {
1223 p_psl[l][n1[l]++] = (T*)(p_psl[l+1]+n2[l]);
1224 p_setupArray( n1, n2, &g->d[i], l+1 );
1225 }
1226 else
1227 {
1228 p_psl[l][n1[l]++] = &p_dsl[0]+n2[l];
1229 }
1230 n2[l] += g->d[i].n;
1231 }
1232 }
1233
1234 // in the p_iterator methods the bound-checking part is split off into a separate
1235 // routine p_iterator_bc in order to make it easier for compilers to inline the code
1237 {
1238#ifdef _MSC_VER
1239 /* disable warning that conditional expression is constant, true or false in if */
1240# pragma warning( disable : 4127 )
1241#endif
1242 if( lgBC )
1243 return p_iterator_bc( i1, i2 );
1244 else
1245 {
1247 return iterator( &(*t)[i1][i2] );
1248 }
1249 }
1251 {
1252 size_type index[] = { i1 };
1253 if( p_g.lgInbounds( 1, index ) )
1254 {
1256 size_type n = p_g.v.getvec( 1, index ).n;
1257 T* s = ( n > 0 ) ? &(*t)[i1][0] : NULL;
1258 if( i2 == npos )
1259 return iterator( s+n, s, s+n );
1260 else
1261 return iterator( s+i2, s, s+n );
1262 }
1263 else
1264 OUT_OF_RANGE( "multi_arr::p_iterator()" );
1265 }
1267 {
1268#ifdef _MSC_VER
1269 /* disable warning that conditional expression is constant, true or false in if */
1270# pragma warning( disable : 4127 )
1271#endif
1272 if( lgBC )
1273 return p_iterator_bc( i1, i2, i3 );
1274 else
1275 {
1277 return iterator( &(*t)[i1][i2][i3] );
1278 }
1279 }
1281 {
1282 size_type index[] = { i1, i2 };
1283 if( p_g.lgInbounds( 2, index ) )
1284 {
1286 size_type n = p_g.v.getvec( 2, index ).n;
1287 T* s = ( n > 0 ) ? &(*t)[i1][i2][0] : NULL;
1288 if( i3 == npos )
1289 return iterator( s+n, s, s+n );
1290 else
1291 return iterator( s+i3, s, s+n );
1292 }
1293 else
1294 OUT_OF_RANGE( "multi_arr::p_iterator()" );
1295 }
1297 {
1298#ifdef _MSC_VER
1299 /* disable warning that conditional expression is constant, true or false in if */
1300# pragma warning( disable : 4127 )
1301#endif
1302 if( lgBC )
1303 return p_iterator_bc(i1, i2, i3, i4);
1304 else
1305 {
1307 return iterator( &(*t)[i1][i2][i3][i4] );
1308 }
1309 }
1311 {
1312 size_type index[] = { i1, i2, i3 };
1313 if( p_g.lgInbounds( 3, index ) )
1314 {
1316 size_type n = p_g.v.getvec( 3, index ).n;
1317 T* s = ( n > 0 ) ? &(*t)[i1][i2][i3][0] : NULL;
1318 if( i4 == npos )
1319 return iterator( s+n, s, s+n );
1320 else
1321 return iterator( s+i4, s, s+n );
1322 }
1323 else
1324 OUT_OF_RANGE( "multi_arr::p_iterator()" );
1325 }
1327 {
1328#ifdef _MSC_VER
1329 /* disable warning that conditional expression is constant, true or false in if */
1330# pragma warning( disable : 4127 )
1331#endif
1332 if( lgBC )
1333 return p_iterator_bc(i1, i2, i3, i4, i5);
1334 else
1335 {
1337 return iterator( &(*t)[i1][i2][i3][i4][i5] );
1338 }
1339 }
1341 {
1342 size_type index[] = { i1, i2, i3, i4 };
1343 if( p_g.lgInbounds( 4, index ) )
1344 {
1346 size_type n = p_g.v.getvec( 4, index ).n;
1347 T* s = ( n > 0 ) ? &(*t)[i1][i2][i3][i4][0] : NULL;
1348 if( i5 == npos )
1349 return iterator( s+n, s, s+n );
1350 else
1351 return iterator( s+i5, s, s+n );
1352 }
1353 else
1354 OUT_OF_RANGE( "multi_arr::p_iterator()" );
1355 }
1357 {
1358#ifdef _MSC_VER
1359 /* disable warning that conditional expression is constant, true or false in if */
1360# pragma warning( disable : 4127 )
1361#endif
1362 if( lgBC )
1363 return p_iterator_bc(i1, i2, i3, i4, i5, i6);
1364 else
1365 {
1367 return iterator( &(*t)[i1][i2][i3][i4][i5][i6] );
1368 }
1369 }
1371 {
1372 size_type index[] = { i1, i2, i3, i4, i5 };
1373 if( p_g.lgInbounds( 5, index ) )
1374 {
1376 size_type n = p_g.v.getvec( 5, index ).n;
1377 T* s = ( n > 0 ) ? &(*t)[i1][i2][i3][i4][i5][0] : NULL;
1378 if( i6 == npos )
1379 return iterator( s+n, s, s+n );
1380 else
1381 return iterator( s+i6, s, s+n );
1382 }
1383 else
1384 OUT_OF_RANGE( "multi_arr::p_iterator()" );
1385 }
1386
1387public:
1389 {
1390 return n_pointer<T,d,ALLOC,lgBC>( p_ptr, p_g.st+1, &p_g.v );
1391 }
1393 {
1394 return const_n_pointer<T,d,ALLOC,lgBC>( p_ptr, p_g.st+1, &p_g.v );
1395 }
1396 typedef n_pointer<T,d-1,ALLOC,lgBC> indexed_type;
1398 {
1399 return n_ptr()[i];
1400 }
1401 typedef const_n_pointer<T,d-1,ALLOC,lgBC> const_indexed_type;
1403 {
1404 return n_ptr()[i];
1405 }
1406
1408 {
1409 size_type index[] = { i1, i2 };
1410 if( !p_g.lgInbounds( 2, index ) )
1411 OUT_OF_RANGE( "multi_arr::at()" );
1412 return (*this)[i1][i2];
1413 }
1415 {
1416 size_type index[] = { i1, i2 };
1417 if( !p_g.lgInbounds( 2, index ) )
1418 OUT_OF_RANGE( "multi_arr::at()" );
1419 return (*this)[i1][i2];
1420 }
1422 {
1423 size_type index[] = { i1, i2, i3 };
1424 if( !p_g.lgInbounds( 3, index ) )
1425 OUT_OF_RANGE( "multi_arr::at()" );
1426 return (*this)[i1][i2][i3];
1427 }
1429 {
1430 size_type index[] = { i1, i2, i3 };
1431 if( !p_g.lgInbounds( 3, index ) )
1432 OUT_OF_RANGE( "multi_arr::at()" );
1433 return (*this)[i1][i2][i3];
1434 }
1436 {
1437 size_type index[] = { i1, i2, i3, i4 };
1438 if( !p_g.lgInbounds( 4, index ) )
1439 OUT_OF_RANGE( "multi_arr::at()" );
1440 return (*this)[i1][i2][i3][i4];
1441 }
1443 {
1444 size_type index[] = { i1, i2, i3, i4 };
1445 if( !p_g.lgInbounds( 4, index ) )
1446 OUT_OF_RANGE( "multi_arr::at()" );
1447 return (*this)[i1][i2][i3][i4];
1448 }
1450 {
1451 size_type index[] = { i1, i2, i3, i4, i5 };
1452 if( !p_g.lgInbounds( 5, index ) )
1453 OUT_OF_RANGE( "multi_arr::at()" );
1454 return (*this)[i1][i2][i3][i4][i5];
1455 }
1457 {
1458 size_type index[] = { i1, i2, i3, i4, i5 };
1459 if( !p_g.lgInbounds( 5, index ) )
1460 OUT_OF_RANGE( "multi_arr::at()" );
1461 return (*this)[i1][i2][i3][i4][i5];
1462 }
1464 {
1465 size_type index[] = { i1, i2, i3, i4, i5, i6 };
1466 if( !p_g.lgInbounds( 6, index ) )
1467 OUT_OF_RANGE( "multi_arr::at()" );
1468 return (*this)[i1][i2][i3][i4][i5][i6];
1469 }
1471 {
1472 size_type index[] = { i1, i2, i3, i4, i5, i6 };
1473 if( !p_g.lgInbounds( 6, index ) )
1474 OUT_OF_RANGE( "multi_arr::at()" );
1475 return (*this)[i1][i2][i3][i4][i5][i6];
1476 }
1477
1479 {
1480 return p_iterator(i1, i2);
1481 }
1483 {
1484 return p_iterator(i1, i2);
1485 }
1487 {
1488 return p_iterator(i1, i2, i3);
1489 }
1491 {
1492 return p_iterator(i1, i2, i3);
1493 }
1495 {
1496 return p_iterator(i1, i2, i3, i4);
1497 }
1499 {
1500 return p_iterator(i1, i2, i3, i4);
1501 }
1503 {
1504 return p_iterator(i1, i2, i3, i4, i5);
1505 }
1507 {
1508 return p_iterator(i1, i2, i3, i4, i5);
1509 }
1511 {
1512 return p_iterator(i1, i2, i3, i4, i5, i6);
1513 }
1515 {
1516 return p_iterator(i1, i2, i3, i4, i5, i6);
1517 }
1518
1520 {
1521 return p_iterator(i1, 0);
1522 }
1524 {
1525 return p_iterator(i1, 0);
1526 }
1528 {
1529 return p_iterator(i1, i2, 0);
1530 }
1532 {
1533 return p_iterator(i1, i2, 0);
1534 }
1536 {
1537 return p_iterator(i1, i2, i3, 0);
1538 }
1540 {
1541 return p_iterator(i1, i2, i3, 0);
1542 }
1544 {
1545 return p_iterator(i1, i2, i3, i4, 0);
1546 }
1548 {
1549 return p_iterator(i1, i2, i3, i4, 0);
1550 }
1552 {
1553 return p_iterator(i1, i2, i3, i4, i5, 0);
1554 }
1556 {
1557 return p_iterator(i1, i2, i3, i4, i5, 0);
1558 }
1559
1561 {
1562#ifdef _MSC_VER
1563 /* disable warning that conditional expression is constant, true or false in if */
1564# pragma warning( disable : 4127 )
1565#endif
1566 if( lgBC )
1567 return p_iterator(i1, npos);
1568 else
1569 return p_iterator(i1, p_g.v.d[i1].n);
1570 }
1572 {
1573#ifdef _MSC_VER
1574 /* disable warning that conditional expression is constant, true or false in if */
1575# pragma warning( disable : 4127 )
1576#endif
1577 if( lgBC )
1578 return p_iterator(i1, npos);
1579 else
1580 return p_iterator(i1, p_g.v.d[i1].n);
1581 }
1583 {
1584#ifdef _MSC_VER
1585 /* disable warning that conditional expression is constant, true or false in if */
1586# pragma warning( disable : 4127 )
1587#endif
1588 if( lgBC )
1589 return p_iterator(i1, i2, npos);
1590 else
1591 return p_iterator(i1, i2, p_g.v.d[i1].d[i2].n);
1592 }
1594 {
1595#ifdef _MSC_VER
1596 /* disable warning that conditional expression is constant, true or false in if */
1597# pragma warning( disable : 4127 )
1598#endif
1599 if( lgBC )
1600 return p_iterator(i1, i2, npos);
1601 else
1602 return p_iterator(i1, i2, p_g.v.d[i1].d[i2].n);
1603 }
1605 {
1606#ifdef _MSC_VER
1607 /* disable warning that conditional expression is constant, true or false in if */
1608# pragma warning( disable : 4127 )
1609#endif
1610 if( lgBC )
1611 return p_iterator(i1, i2, i3, npos);
1612 else
1613 return p_iterator(i1, i2, i3, p_g.v.d[i1].d[i2].d[i3].n);
1614 }
1616 {
1617#ifdef _MSC_VER
1618 /* disable warning that conditional expression is constant, true or false in if */
1619# pragma warning( disable : 4127 )
1620#endif
1621 if( lgBC )
1622 return p_iterator(i1, i2, i3, npos);
1623 else
1624 return p_iterator(i1, i2, i3, p_g.v.d[i1].d[i2].d[i3].n);
1625 }
1627 {
1628#ifdef _MSC_VER
1629 /* disable warning that conditional expression is constant, true or false in if */
1630# pragma warning( disable : 4127 )
1631#endif
1632 if( lgBC )
1633 return p_iterator(i1, i2, i3, i4, npos);
1634 else
1635 return p_iterator(i1, i2, i3, i4, p_g.v.d[i1].d[i2].d[i3].d[i4].n);
1636 }
1638 {
1639#ifdef _MSC_VER
1640 /* disable warning that conditional expression is constant, true or false in if */
1641# pragma warning( disable : 4127 )
1642#endif
1643 if( lgBC )
1644 return p_iterator(i1, i2, i3, i4, npos);
1645 else
1646 return p_iterator(i1, i2, i3, i4, p_g.v.d[i1].d[i2].d[i3].d[i4].n);
1647 }
1649 {
1650#ifdef _MSC_VER
1651 /* disable warning that conditional expression is constant, true or false in if */
1652# pragma warning( disable : 4127 )
1653#endif
1654 if( lgBC )
1655 return p_iterator(i1, i2, i3, i4, i5, npos);
1656 else
1657 return p_iterator(i1, i2, i3, i4, i5, p_g.v.d[i1].d[i2].d[i3].d[i4].d[i5].n);
1658 }
1660 {
1661#ifdef _MSC_VER
1662 /* disable warning that conditional expression is constant, true or false in if */
1663# pragma warning( disable : 4127 )
1664#endif
1665 if( lgBC )
1666 return p_iterator(i1, i2, i3, i4, i5, npos);
1667 else
1668 return p_iterator(i1, i2, i3, i4, i5, p_g.v.d[i1].d[i2].d[i3].d[i4].d[i5].n);
1669 }
1670
1672 {
1673 return *begin(i1);
1674 }
1676 {
1677 return *begin(i1);
1678 }
1680 {
1681 return *begin(i1, i2);
1682 }
1684 {
1685 return *begin(i1, i2);
1686 }
1688 {
1689 return *begin(i1, i2, i3);
1690 }
1692 {
1693 return *begin(i1, i2, i3);
1694 }
1696 {
1697 return *begin(i1, i2, i3, i4);
1698 }
1700 {
1701 return *begin(i1, i2, i3, i4);
1702 }
1704 {
1705 return *begin(i1, i2, i3, i4, i5);
1706 }
1708 {
1709 return *begin(i1, i2, i3, i4, i5);
1710 }
1711
1713 {
1714 return *(end(i1) - 1);
1715 }
1717 {
1718 return *(end(i1) - 1);
1719 }
1721 {
1722 return *(end(i1, i2) - 1);
1723 }
1725 {
1726 return *(end(i1, i2) - 1);
1727 }
1729 {
1730 return *(end(i1, i2, i3) - 1);
1731 }
1733 {
1734 return *(end(i1, i2, i3) - 1);
1735 }
1737 {
1738 return *(end(i1, i2, i3, i4) - 1);
1739 }
1741 {
1742 return *(end(i1, i2, i3, i4) - 1);
1743 }
1745 {
1746 return *(end(i1, i2, i3, i4, i5) - 1);
1747 }
1749 {
1750 return *(end(i1, i2, i3, i4, i5) - 1);
1751 }
1752
1754 {
1755 return p_g.size;
1756 }
1758 {
1759 return p_g.size;
1760 }
1761 bool empty() const
1762 {
1763 for( int i=0; i < d-1; ++i )
1764 if( p_psl[i] != NULL )
1765 return false;
1766 return ( p_g.size == 0UL && p_dsl.size() == 0 );
1767 }
1768
1770 {
1771 if( p_g.size > 0 )
1772 return get_ptr( p_dsl );
1773 else
1774 return NULL;
1775 }
1777 {
1778 if( p_g.size > 0 )
1779 return get_ptr( p_dsl );
1780 else
1781 return NULL;
1782 }
1783
1785 {
1786 return p_g;
1787 }
1788
1789 valarray<T>& vals()
1790 {
1791 return p_dsl;
1792 }
1793 const valarray<T>& vals() const
1794 {
1795 return p_dsl;
1796 }
1797};
1798
1799// predefine commonly used iterators
1810
1821
1832
1843
1844// on Mac systems these instantiations need to be extern in order to avoid duplicate symbols
1845#define INSTANTIATE_MULTI_ARR( TYPE, BC ) \
1846template class pntr<TYPE,BC>; \
1847template class const_pntr<TYPE,BC>;
1848
1849template<class T, bool lgBC=lgBOUNDSCHECKVAL>
1851{
1852 size_t p_size; // number of elements allocated
1853 long p_begin; // first valid array index
1854 long p_end; // one beyond last valid array index
1855 bool p_init; // set true when alloc() has been called
1856
1857 T* p_ptr_alloc; // pointer to start of allocated data
1858 T* p_ptr; // pointer used for calculating array indices
1859
1860public:
1861 typedef random_access_iterator_tag iterator_category;
1862 typedef T value_type;
1863 typedef T& reference;
1864 typedef const T& const_reference;
1865 typedef T* pointer;
1866 typedef const T* const_pointer;
1867 typedef long size_type;
1868 typedef ptrdiff_t difference_type;
1871
1872private:
1874 {
1875 delete[] p_ptr_alloc;
1876 p_ptr_alloc = NULL;
1877 }
1879 {
1880 p_size = 0;
1881 p_begin = 0;
1882 p_end = 0;
1883 p_init = false;
1884 p_ptr_alloc = NULL;
1885 p_ptr = NULL;
1886 }
1887
1888public:
1890 {
1891 p_clear1();
1892 }
1894 {
1895 p_clear1();
1896 alloc( begin, end );
1897 }
1899 {
1900 p_clear1();
1901 *this = f;
1902 }
1904 {
1905 p_clear0();
1906 }
1908 {
1909 if( &f != this )
1910 {
1911 clear();
1912 p_size = f.p_size;
1913 p_begin = f.p_begin;
1914 p_end = f.p_end;
1915 p_init = f.p_init;
1916 if( f.p_ptr_alloc != NULL )
1917 {
1918 p_ptr_alloc = new T[ p_size ];
1919 pointer p = p_ptr_alloc;
1921 for( size_type i=0; i < p_end-p_begin; ++i )
1922 *p++ = *fp++;
1924 }
1925 }
1926 return *this;
1927 }
1928 void clear()
1929 {
1930 p_clear0();
1931 p_clear1();
1932 }
1933 void zero()
1934 {
1935 if( p_size > 0 )
1936 memset( p_ptr_alloc, 0, p_size*sizeof(T) );
1937 }
1939 {
1940 invalidate_array( p_ptr_alloc, p_size*sizeof(T) );
1941 }
1942 void state_do(FILE *out, bool lgGet)
1943 {
1944 if( lgGet )
1945 restore_state(out);
1946 else
1947 dump_state(out);
1948 }
1949 // dump the array to a file in binary format
1950 void dump_state(FILE *out) const
1951 {
1952 do_dump_state( p_ptr_alloc, p_size, sizeof(T), out, MA_VERS[FLX_TYPE] );
1953 }
1954 // restore the array from a file in binary format
1955 void restore_state(FILE *in)
1956 {
1957 do_restore_state( p_ptr_alloc, p_size, sizeof(T), in, MA_VERS[FLX_TYPE] );
1958 }
1959
1960 // reserve memory for the array
1962 {
1963 // make sure we start with a clean slate...
1964 clear();
1965#ifdef _MSC_VER
1966 /* disable warning that conditional expression is constant, true or false in if */
1967# pragma warning( disable : 4127 )
1968#endif
1969 if( size > 0 )
1970 {
1971 ASSERT( p_ptr_alloc == NULL );
1972 p_ptr_alloc = new T[size];
1973 p_size = (size_t)size;
1974 }
1975 }
1976 // allocate array with index between begin <= ind < end
1977 // memory is allocated here, if not already done with reserve() before
1979 {
1980 if( (size_t)max(end-begin,0) > p_size )
1981 {
1982 clear();
1983
1984 ASSERT( p_ptr_alloc == NULL );
1985 p_ptr_alloc = new T[end-begin];
1987 p_size = (size_t)(end-begin);
1988 }
1989 else
1990 {
1991 // store was already allocated with reserve()
1993 }
1994 p_begin = begin;
1995 p_end = end;
1996 p_init = true;
1997 }
1998 // adjust upper limit of array, reallocate store if necessary
2000 {
2001 ASSERT( p_init );
2002 if( (size_t)max(end-p_begin,0) > p_size )
2003 {
2004 // reallocate the store
2005 T* nptr_alloc = new T[end-p_begin];
2006 T* nptr = nptr_alloc - p_begin;
2007 // copy store over using operator= from T, using memcpy would be a bug!
2008 // this could trip valgrind / purify since we don't know if this is initialized
2009 // there is nothing safe we can do here, so the caller should take care of this
2010 // note that we ignore fields above p_end, we assume nothing of interest is there
2011 if( p_ptr_alloc != NULL && p_ptr != NULL )
2012 {
2013 for( size_type i=p_begin; i < p_end; ++i )
2014 nptr[i] = p_ptr[i];
2015 delete[] p_ptr_alloc;
2016 }
2017 p_ptr_alloc = nptr_alloc;
2018 p_ptr = nptr;
2019 p_size = (size_t)(end-p_begin);
2020 }
2021 p_end = end;
2022 }
2023
2024private:
2025 // the p_pointer() method below defines indexing into the flex_arr
2027 {
2028 return p_ptr+i;
2029 }
2030
2032 {
2033#ifdef _MSC_VER
2034 /* disable warning that conditional expression is constant, true or false in if */
2035# pragma warning( disable : 4127 )
2036#endif
2037 if( lgBC )
2039 else
2040 return iterator( p_pointer(i) );
2041 }
2042
2044 {
2045 return ( i >= p_begin && i < p_end );
2046 }
2047
2049 {
2050#ifdef _MSC_VER
2051 /* disable warning that conditional expression is constant, true or false in if */
2052# pragma warning( disable : 4127 )
2053#endif
2054 if( lgBC )
2055 {
2056 if( ! p_lgInbounds( i ) )
2057 OUT_OF_RANGE( "flex_arr::p_index()" );
2058 }
2059 return *p_pointer(i);
2060 }
2061
2062public:
2064 {
2065 return reference(p_index(i));
2066 }
2068 {
2069 return const_reference(p_index(i));
2070 }
2071
2073 {
2074 if( ! p_lgInbounds(i) )
2075 OUT_OF_RANGE( "flex_arr::at()" );
2076 return (*this)[i];
2077 }
2079 {
2080 if( ! p_lgInbounds(i) )
2081 OUT_OF_RANGE( "flex_arr::at()" );
2082 return (*this)[i];
2083 }
2084
2086 {
2087 return iterator(p_iterator(i));
2088 }
2090 {
2091 return const_iterator(p_iterator(i));
2092 }
2093
2094 // \todo: add: assign, swap?, ... (go over stl_vector.h)
2095
2097 {
2098 return ptr(p_begin);
2099 }
2101 {
2102 return ptr(p_begin);
2103 }
2104
2106 {
2107 return ptr(p_end);
2108 }
2110 {
2111 return ptr(p_end);
2112 }
2113
2115 {
2116 return *begin();
2117 }
2119 {
2120 return *begin();
2121 }
2122
2124 {
2125 return *(end()-1);
2126 }
2128 {
2129 return *(end()-1);
2130 }
2131
2133 {
2134 return max(p_end-p_begin,0);
2135 }
2137 {
2138 return p_size;
2139 }
2140 bool empty() const
2141 {
2142 return ( size() == 0 );
2143 }
2144
2146 {
2147 return p_ptr_alloc;
2148 }
2150 {
2151 return p_ptr_alloc;
2152 }
2153};
2154
2155// predefine commonly used iterators
2164
2165#endif /* CONTAINER_CLASSES_H_ */
#define ASSERT(exp)
Definition cddefines.h:578
NORETURN void OUT_OF_RANGE(const char *str)
Definition cddefines.h:608
T * get_ptr(T *v)
Definition cddefines.h:1079
long max(int a, long b)
Definition cddefines.h:775
#define STATIC_ASSERT(x)
Definition cddefines.h:113
NORETURN void TotalInsanity(void)
Definition service.cpp:886
void invalidate_array(T *p, size_t size)
Definition cddefines.h:1061
bool operator<(const basic_pntr &t) const
basic_pntr & operator-=(const ptrdiff_t n)
bool operator<=(const basic_pntr &t) const
void p_set_vals(T *p0, T *p1, T *p2)
bool operator!=(const basic_pntr &t) const
basic_pntr(T *p0, T *p1, T *p2)
bool operator>(const basic_pntr &t) const
random_access_iterator_tag iterator_category
basic_pntr & operator++()
bool operator>=(const basic_pntr &t) const
bool operator==(const basic_pntr &t) const
T & operator*() const
const T * const_pointer
const T & const_reference
T & operator[](const ptrdiff_t n) const
T * p_index_checked(const ptrdiff_t n) const
basic_pntr(const basic_pntr &t)
basic_pntr & operator+=(const ptrdiff_t n)
T * operator->() const
basic_pntr & operator--()
static const int p_nd
ptrdiff_t difference_type
const_n_pointer(const T *p, const size_t *st=NULL, const tree_vec *v=NULL)
const_n_pointer(const T *p, const size_t *st, const tree_vec *v)
const_n_pointer(const T *p, const size_t *st, const tree_vec *v=NULL)
const_n_pointer(const T *p, const size_t *st, const tree_vec *v)
const_n_pointer(const T *p, const size_t *st=NULL, const tree_vec *v=NULL)
const_n_pointer< T, N-1, ARPA_TYPE, false > value_type
const_n_pointer(const T *p, const size_t *st, const tree_vec *v)
const_n_pointer< T, N-1, ARPA_TYPE, true > value_type
const_n_pointer< T, N-1, C_TYPE, false > value_type
const_n_pointer(const T *p, const size_t *st, const tree_vec *v=NULL)
const_n_pointer< T, N-1, C_TYPE, true > value_type
const_n_pointer(const T *p, const size_t *st, const tree_vec *v)
const_pntr - same as pntr, except that it replaces const pointers rather than normal pointers
const T * operator->() const
const T & operator[](const ptrdiff_t n) const
const_pntr & operator++()
const T & operator*() const
const_pntr(const pntr< T, lgBC > &t)
const_pntr & operator+=(const ptrdiff_t n)
const_pntr & operator-=(const ptrdiff_t n)
const const_pntr operator-(const ptrdiff_t n) const
const_pntr(T *p0, T *p1, T *p2)
const const_pntr operator+(const ptrdiff_t n) const
const_pntr & operator--()
void reserve(size_type size)
reference at(size_type i)
reference front()
flex_arr(const flex_arr &f)
void restore_state(FILE *in)
const T & const_reference
void realloc(size_type end)
iterator p_iterator(size_type i) const
random_access_iterator_tag iterator_category
const flex_arr & operator=(const flex_arr &f)
reference operator[](size_type i)
ptrdiff_t difference_type
size_type capacity() const
const_pointer data() const
const_iterator end() const
const_reference at(size_type i) const
pntr< T, lgBC > iterator
size_type size() const
iterator end()
bool empty() const
bool p_lgInbounds(size_type i) const
pointer p_pointer(size_type i) const
const_pntr< T, lgBC > const_iterator
void state_do(FILE *out, bool lgGet)
reference back()
iterator ptr(size_type i)
const_iterator ptr(size_type i) const
void alloc(size_type begin, size_type end)
iterator begin()
const_iterator begin() const
const_reference front() const
flex_arr(size_type begin, size_type end)
void dump_state(FILE *out) const
const T * const_pointer
const_reference back() const
reference p_index(size_type i) const
const_iterator begin(size_type i1) const
void alloc(size_type d1, size_type d2, size_type d3, size_type d4)
const valarray< T > & vals() const
const_iterator ptr(size_type i1, size_type i2) const
void restore_state(FILE *in)
bool **** p_ptr4
iterator p_iterator_bc(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
const_iterator begin(size_type i1, size_type i2, size_type i3, size_type i4) const
const_reference at(size_type i1, size_type i2, size_type i3, size_type i4) const
iterator begin(size_type i1, size_type i2, size_type i3)
iterator ptr(size_type i1, size_type i2, size_type i3)
const_iterator begin(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
const_reference back(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
iterator p_iterator_bc(size_type i1, size_type i2, size_type i3) const
bool ** p_psl[d-1]
valarray< bool > p_dsl
void reserve(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
iterator ptr(size_type i1, size_type i2)
void state_do(FILE *io, bool lgGet)
const_reference front(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
iterator end(size_type i1, size_type i2, size_type i3)
reference front(size_type i1, size_type i2)
const_reference at(size_type i1, size_type i2, size_type i3) const
const_pntr< T, lgBC > const_iterator
const_reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
reference back(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
reference front(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
const_iterator end(size_type i1, size_type i2, size_type i3) const
static const size_type npos
iterator p_iterator(size_type i1, size_type i2, size_type i3) const
bool ***** p_ptr5
reference back(size_type i1, size_type i2)
multi_arr(size_type d1, size_type d2, size_type d3, size_type d4)
reference back(size_type i1)
iterator p_iterator_bc(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
random_access_iterator_tag iterator_category
const n_pointer< T, d, ALLOC, lgBC > n_ptr()
const_reference back(size_type i1, size_type i2) const
void alloc(size_type d1, size_type d2)
multi_arr(size_type d1, size_type d2, size_type d3, size_type d4, size_type d5, size_type d6)
const_reference at(size_type i1, size_type i2) const
iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6)
const_reference back(size_type i1, size_type i2, size_type i3, size_type i4) const
const T * const_pointer
void alloc(const multi_geom< d, ALLOC > &g)
const_reference front(size_type i1, size_type i2, size_type i3, size_type i4) const
bool ****** p_ptr6
iterator begin(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
iterator end(size_type i1, size_type i2)
const_iterator ptr(size_type i1, size_type i2, size_type i3) const
reference at(size_type i1, size_type i2, size_type i3)
iterator p_iterator(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
multi_geom< d, MEM_LAYOUT_VAL > p_g
iterator p_iterator(size_type i1, size_type i2, size_type i3, size_type i4) const
void dump_state(FILE *out) const
reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6)
reference at(size_type i1, size_type i2, size_type i3, size_type i4)
const_n_pointer< T, d-1, ALLOC, lgBC > const_indexed_type
const_iterator begin(size_type i1, size_type i2) const
iterator begin(size_type i1, size_type i2)
const T & const_reference
iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4)
valarray< T > & vals()
reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
iterator p_iterator(size_type i1, size_type i2) const
void reserve(size_type i1, size_type i2, size_type i3, size_type i4)
void reserve(size_type i1)
iterator p_iterator(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
const_reference front(size_type i1, size_type i2, size_type i3) const
reference back(size_type i1, size_type i2, size_type i3, size_type i4)
iterator end(size_type i1, size_type i2, size_type i3, size_type i4)
const_iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4) const
iterator begin(size_type i1)
const_pointer data() const
multi_arr(const multi_arr &m)
const_reference front(size_type i1, size_type i2) const
iterator p_iterator_bc(size_type i1, size_type i2, size_type i3, size_type i4) const
size_type size() const
multi_arr(size_type d1, size_type d2, size_type d3)
multi_arr(const multi_geom< d, ALLOC > &g)
void reserve(size_type i1, size_type i2, size_type i3)
void p_setupArray(size_type n1[], size_type n2[], const tree_vec *g, int l)
pntr< T, lgBC > iterator
bool empty() const
const_reference back(size_type i1, size_type i2, size_type i3) const
void alloc(size_type index[])
const const_n_pointer< T, d, ALLOC, lgBC > n_ptr() const
iterator p_iterator_bc(size_type i1, size_type i2) const
const_iterator begin(size_type i1, size_type i2, size_type i3) const
const_iterator end(size_type i1, size_type i2, size_type i3, size_type i4) const
bool *** p_ptr3
void alloc(size_type d1, size_type d2, size_type d3, size_type d4, size_type d5, size_type d6)
const_iterator end(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
const_iterator end(size_type i1, size_type i2) const
const_iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
const indexed_type operator[](size_type i)
const_reference at(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6) const
iterator end(size_type i1)
void reserve(size_type i1, size_type i2)
reference front(size_type i1)
multi_arr(size_type d1, size_type d2, size_type d3, size_type d4, size_type d5)
reference front(size_type i1, size_type i2, size_type i3, size_type i4)
reference at(size_type i1, size_type i2)
ptrdiff_t difference_type
const multi_geom< d, ALLOC > & clone() const
void alloc(size_type d1, size_type d2, size_type d3)
iterator end(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
multi_arr(size_type d1, size_type d2)
iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5)
const_iterator end(size_type i1) const
const_reference front(size_type i1) const
reference back(size_type i1, size_type i2, size_type i3)
size_type capacity() const
void reserve(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5, size_type i6)
void alloc(size_type d1, size_type d2, size_type d3, size_type d4, size_type d5)
reference front(size_type i1, size_type i2, size_type i3)
const_iterator ptr(size_type i1, size_type i2, size_type i3, size_type i4, size_type i5) const
const multi_arr & operator=(const multi_arr &m)
n_pointer< T, d-1, ALLOC, lgBC > indexed_type
const_reference back(size_type i1) const
iterator begin(size_type i1, size_type i2, size_type i3, size_type i4)
size_type st[d]
size of each dimension (only used in C_TYPE layout)
void finalize(void)
void p_clear0()
sizes of each of the pointer arrays
const multi_geom & operator=(const multi_geom &m)
bool lgInbounds(const size_type n, const size_type index[]) const
void p_setupArray(size_type n1[], size_type n2[], const tree_vec *w, int l)
void reserve(const size_type n, const size_type index[])
size_type nsl[d]
stride for each dimension (only used in C_TYPE layout)
void reserve_recursive(const size_type n, size_type index[])
multi_geom(const multi_geom &m)
size_type s[d]
allocated size (number of data elements, pointers are not counted)
n_pointer(T *p, const size_t *st=NULL, const tree_vec *v=NULL)
n_pointer(T *p, const size_t *st, const tree_vec *v)
n_pointer(T *p, const size_t *st, const tree_vec *v=NULL)
n_pointer(T *p, const size_t *st, const tree_vec *v)
n_pointer< T, N-1, ARPA_TYPE, false > value_type
n_pointer(T *p, const size_t *st=NULL, const tree_vec *v=NULL)
n_pointer(T *p, const size_t *st, const tree_vec *v)
n_pointer< T, N-1, ARPA_TYPE, true > value_type
n_pointer< T, N-1, C_TYPE, false > value_type
n_pointer(T *p, const size_t *st, const tree_vec *v=NULL)
n_pointer< T, N-1, C_TYPE, true > value_type
n_pointer(T *p, const size_t *st, const tree_vec *v)
pntr - interface class to replace normal pointers
pntr(T *p0, T *p1, T *p2)
pntr & operator--()
pntr & operator++()
pntr(T *p0)
const pntr operator+(const ptrdiff_t n) const
const pntr operator-(const ptrdiff_t n) const
multi_arr< long, 6 >::const_iterator ml6ci
flex_arr< realnum >::iterator fari
multi_arr< double, 3 >::iterator md3i
void do_restore_state(void *buf, size_t nelem, size_t size, FILE *in, int32 magic)
multi_arr< realnum, 6 >::const_iterator mr6ci
multi_arr< bool, 2 >::const_iterator mb2ci
multi_arr< bool, 4 >::iterator mb4i
flex_arr< long >::iterator fali
multi_arr< double, 2 >::const_iterator md2ci
flex_arr< realnum >::const_iterator farci
flex_arr< bool >::const_iterator fabci
multi_arr< long, 3 >::const_iterator ml3ci
multi_arr< long, 4 >::const_iterator ml4ci
flex_arr< long >::const_iterator falci
multi_arr< realnum, 4 >::const_iterator mr4ci
@ C_TYPE
@ ML_TOP
@ FLX_TYPE
@ ARPA_TYPE
multi_arr< bool, 6 >::const_iterator mb6ci
multi_arr< bool, 2 >::iterator mb2i
multi_arr< realnum, 5 >::iterator mr5i
flex_arr< double >::const_iterator fadci
multi_arr< long, 2 >::iterator ml2i
multi_arr< long, 2 >::const_iterator ml2ci
multi_arr< long, 4 >::iterator ml4i
multi_arr< long, 5 >::const_iterator ml5ci
multi_arr< double, 4 >::iterator md4i
multi_arr< realnum, 4 >::iterator mr4i
multi_arr< realnum, 6 >::iterator mr6i
multi_arr< long, 5 >::iterator ml5i
multi_arr< realnum, 2 >::const_iterator mr2ci
flex_arr< bool >::iterator fabi
flex_arr< double >::iterator fadi
const pntr< T, lgBC > operator+(const ptrdiff_t n, const pntr< T, lgBC > &t)
multi_arr< double, 2 >::iterator md2i
multi_arr< double, 6 >::const_iterator md6ci
multi_arr< double, 4 >::const_iterator md4ci
multi_arr< bool, 5 >::const_iterator mb5ci
void do_dump_state(const void *buf, size_t nelem, size_t size, FILE *out, int32 magic)
multi_arr< bool, 6 >::iterator mb6i
multi_arr< realnum, 5 >::const_iterator mr5ci
multi_arr< realnum, 3 >::iterator mr3i
multi_arr< bool, 3 >::iterator mb3i
multi_arr< realnum, 3 >::const_iterator mr3ci
multi_arr< long, 6 >::iterator ml6i
multi_arr< bool, 4 >::const_iterator mb4ci
multi_arr< double, 3 >::const_iterator md3ci
multi_arr< bool, 5 >::iterator mb5i
multi_arr< double, 6 >::iterator md6i
multi_arr< double, 5 >::iterator md5i
multi_arr< bool, 3 >::const_iterator mb3ci
static const int32 MA_VERS[ML_TOP]
multi_arr< realnum, 2 >::iterator mr2i
multi_arr< double, 5 >::const_iterator md5ci
multi_arr< long, 3 >::iterator ml3i
static double * g
Definition species2.cpp:28
static bool lgGet
Definition state.cpp:20
tree_vec - a simple class to store the bounds checking information for multi_arr
const tree_vec & getvec(const size_type i, const size_type index[]) const
tree_vec & getvec(const size_type i, const size_type index[])
tree_vec * d
tree_vec(const tree_vec &m)
const tree_vec & operator=(const tree_vec &m)
static const int N