Annotation of parser3/src/include/pa_array.h, revision 1.57.2.27.2.13
1.24 paf 1: /** @file
1.57.2.2 paf 2: Parser: Array & Array_iterator classes decls.
1.26 paf 3:
1.57.2.16 paf 4: Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
1.53 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 paf 6: */
7:
1.24 paf 8: #ifndef PA_ARRAY_H
9: #define PA_ARRAY_H
1.54 paf 10:
1.57.2.27.2.1 (paf 11:): static const char* IDENT_ARRAY_H="$Date: 2003/04/02 08:11:31 $";
1.24 paf 12:
1.57.2.25 paf 13: // includes
14:
15: #include "pa_memory.h"
1.57.2.3 paf 16: #include "pa_exception.h"
1.24 paf 17:
1.57.2.27.2.1 (paf 18:): // externals
19:):
1.57.2.25 paf 20: // forwards
1.42 parser 21:
1.57.2.25 paf 22: template<typename T> class Array_iterator;
1.24 paf 23:
1.57.2.25 paf 24: /// Simple Array
1.57.2.2 paf 25: template<typename T> class Array: public PA_Object {
1.1 paf 26:
1.57.2.9 paf 27: friend class Array_iterator<T>;
1.57.2.2 paf 28:
1.57.2.13 paf 29: protected:
30:
31: /// elements[growing size] here
32: T *felements;
33:
1.57.2.2 paf 34: // allocated size
1.57.2.27.2.7 (paf 35:: size_t fallocated;
1.1 paf 36:
1.57.2.13 paf 37: // array size
1.57.2.27.2.7 (paf 38:: size_t fused;
1.57.2.13 paf 39:
1.57.2.2 paf 40: public:
41: typedef T element_type;
1.7 paf 42:
1.57.2.27.2.2 (paf 43:: Array(int initial=3):
1.57.2.27 paf 44: fallocated(initial>3?initial:3),
1.57.2.2 paf 45: fused(0)
46: {
1.57.2.27.2.2 (paf 47:: felements=static_cast<T*>(malloc(fallocated*sizeof(T)));
1.57.2.2 paf 48: }
1.24 paf 49:
1.57.2.2 paf 50: /// how many items are in Array
1.57.2.27.2.7 (paf 51:: size_t count() const { return fused; }
1.57.2.2 paf 52: /// append to array
53: Array& operator += (T src) {
54: if(is_full())
1.57.2.27.2.4 (paf 55:: expand(2);
1.24 paf 56:
1.57.2.2 paf 57: felements[fused++]=src;
1.37 paf 58:
1.57.2.2 paf 59: return *this;
1.34 paf 60: }
1.35 paf 61:
1.57.2.2 paf 62: /// append other Array portion to this one. starting from offset
63: Array& append(const Array& src, int offset=0, int limit=0) {
1.57.2.25 paf 64: if(offset<0) {
1.57.2.4 paf 65: throw Exception(0,
1.57.2.27.2.3 (paf 66:: 0,
1.57.2.25 paf 67: "Array::append(offset=%d) out <0", offset);
68: //return Nothing; // never
1.57.2.2 paf 69: }
70: // fix limit
71: {
72: int m=src.count()-offset;
73: if(!m || limit<0)
74: return *this;
75: if(!limit || limit>m)
76: limit=m;
77: }
1.29 paf 78:
1.57.2.23 paf 79: int delta=limit-(fallocated-fused);
80: if(delta>0)
81: expand(delta);
82:
83: T* from=&src.felements[offset];
84: T* to=&felements[fused];
85: T* from_end=from+limit;
86: while(from<from_end)
87: *to++=*from++;
88:
89: fused+=limit;
1.57.2.4 paf 90: return *this;
1.57.2.2 paf 91: }
1.49 paf 92:
1.57.2.27.2.1 (paf 93:): /// get index-element
94:): T get(size_t index) const {
95:): assert(index>=0 && index<count());
1.57.2.27.2.7 (paf 96:: return felements[index];
97:: }
98::
1.57.2.27.2.1 (paf 99:): /// ref version of get
100:): T& get_ref(size_t index) const {
101:): assert(index>=0 && index<count());
1.57.2.27.2.9 (paf 102:: return felements[index];
103:: }
104::
1.57.2.2 paf 105: /// put index-element
1.57.2.27.2.8 (paf 106:: void put(size_t index, T element) {
1.57.2.27.2.1 (paf 107:): assert(index>=0 && index<count());
108:): felements[index]=element;
1.57.2.2 paf 109: }
1.1 paf 110:
1.57.2.27.2.1 (paf 111:): T operator [](size_t index) const { return get(index); }
1.7 paf 112:
1.57.2.2 paf 113: /// iterate over all elements
1.57.2.6 paf 114: template<typename I> void for_each(void (*callback)(T, I), I info) const {
1.57.2.2 paf 115: T *last=felements+fused;
116: for(T *current=felements; current<last; current++)
117: callback(*current, info);
118: }
1.1 paf 119:
1.57.2.2 paf 120: /// iterate over all elements until condition becomes true, return that element
1.57.2.6 paf 121: template<typename I> T first_that(bool (*callback)(T, I), I info) const {
1.57.2.2 paf 122: T *last=felements+fused;
123: for(T *current=felements; current<last; current++)
124: if(callback(*current, info))
125: return *current;
1.7 paf 126:
1.57.2.20 paf 127: return T(0);
1.57.2.2 paf 128: }
1.1 paf 129:
1.57.2.3 paf 130: protected:
1.1 paf 131:
1.57.2.2 paf 132: bool is_full() {
133: return fused == fallocated;
134: }
1.57.2.27.2.5 (paf 135:: void expand(size_t delta) {
136:: size_t new_allocated=fallocated+delta;
137:: felements = (T *)realloc(felements, new_allocated*sizeof(T));
1.57.2.22 paf 138: memset(&felements[fallocated], 0, delta*sizeof(T));
1.57.2.27.2.5 (paf 139:: fallocated=new_allocated;
1.1 paf 140: }
1.2 paf 141:
1.1 paf 142: private: //disabled
143:
1.57.2.27.2.6 (paf 144:: Array(const Array&) {}
1.12 paf 145: Array& operator = (const Array&) { return *this; }
1.57.2.5 paf 146: };
147:
1.42 parser 148:
1.57.2.27.2.1 (paf 149:: /** Array iterator, usage:
150:: @code
151:: // Array<T> a;
1.57.2.27.2.9 (paf 152:: for(Array_iterator<T> i(a); i.has_next(); ) {
1.57.2.27.2.1 (paf 153:: T& element=i.next();
154:: ...
155:: }
156:: @endcode
157:: */
1.57.2.2 paf 158: template<typename T> class Array_iterator {
159:
1.57.2.27.2.1 (paf 160:: const Array<T>& farray;
161:: T *fcurrent;
162:: T *flast;
163::
164:: public:
165::
166:: Array_iterator(const Array<T>& aarray): farray(aarray) {
167:: fcurrent=farray.felements;
168:: flast=farray.felements+farray.count();
169:: }
170::
171:: /// there are still elements
172:: bool has_next() {
173:: return fcurrent<flast;
174:: }
175::
176:: /// quickly extracts next Array element
1.57.2.27.2.8 (paf 177:: const T next() {
1.57.2.27.2.1 (paf 178:: return *(fcurrent++);
179:: }
180::
181:: };
1.57.2.27.2.9 (paf 182:: /*
1.57.2.27.2.1 (paf 183:: /** Nonconst array iterator, usage:
184:: @code
185:: // Array<T> a;
1.57.2.27.2.9 (paf 186:: for(Array_iterator<T> i(a); i.has_next(); ) {
1.57.2.27.2.1 (paf 187:: T& element=i.next();
188:: ...
189:: }
190:: @endcode
1.57.2.27.2.9 (paf 191:: * /
1.57.2.27.2.1 (paf 192:: template<typename T> class Array_modifing_iterator {
193::
1.57.2.9 paf 194: Array<T>& farray;
1.57.2.2 paf 195: T *fcurrent;
196: T *flast;
197:
1.42 parser 198: public:
199:
1.57.2.27.2.1 (paf 200:: Array_modifing_iterator(Array<T>& aarray): farray(aarray) {
1.57.2.9 paf 201: fcurrent=farray.felements;
202: flast=farray.felements+farray.count();
1.42 parser 203: }
204:
205: /// there are still elements
206: bool has_next() {
1.57.2.2 paf 207: return fcurrent<flast;
1.42 parser 208: }
209:
1.57.2.2 paf 210: /// quickly extracts next Array element
1.57.2.27.2.9 (paf 211:: T& next() {
1.57.2.9 paf 212: return *(fcurrent++);
1.42 parser 213: }
214:
1.1 paf 215: };
1.57.2.27.2.9 (paf 216:: */
1.1 paf 217: #endif
E-mail: