Annotation of parser3/src/include/pa_array.h, revision 1.57.2.24
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.24! paf 11: static const char* IDENT_ARRAY_Y="$Date: 2003/02/17 11:29:53 $";
1.24 paf 12:
13: #include "pa_pool.h"
1.57.2.3 paf 14: #include "pa_exception.h"
1.24 paf 15:
1.57.2.3 paf 16: template<typename T> class Array_iterator;
1.42 parser 17:
1.25 paf 18: /**
1.57.2.2 paf 19: Simple Array.
1.24 paf 20:
1.1 paf 21: */
1.57.2.2 paf 22: template<typename T> class Array: public PA_Object {
1.1 paf 23:
1.57.2.9 paf 24: friend class Array_iterator<T>;
1.57.2.2 paf 25:
1.57.2.13 paf 26: protected:
27:
28: // default expand delta size
29: int fdelta;
30:
31: /// elements[growing size] here
32: T *felements;
33:
1.57.2.2 paf 34: // allocated size
35: int fallocated;
1.1 paf 36:
1.57.2.13 paf 37: // array size
38: int fused;
39:
1.57.2.2 paf 40: public:
41: typedef T element_type;
1.7 paf 42:
1.57.2.3 paf 43: Array(int initial=3, int delta=1):
1.57.2.2 paf 44: fallocated(initial?initial:3),
45: fdelta(delta),
46: fused(0)
47: {
1.57.2.3 paf 48: if(fallocated<=0 || fdelta<1)
1.57.2.4 paf 49: throw Exception(0,
50: Exception::undefined_source,
1.57.2.2 paf 51: "Array::Array(%d, %d) too small", initial, delta);
1.24 paf 52:
1.57.2.22 paf 53: felements=static_cast<T*>(calloc(fallocated*sizeof(T)));
1.57.2.2 paf 54: }
55: override ~Array() {
1.57.2.3 paf 56: T *last=felements+fused;
57: for(T *current=felements; current<last; current++)
1.57.2.22 paf 58: current->~T(); // manually invoking destructors
1.57.2.3 paf 59:
1.57.2.22 paf 60: free(felements);
1.57.2.2 paf 61: }
1.24 paf 62:
1.57.2.2 paf 63: /// how many items are in Array
64: int count() const { return fused; }
65: /// append to array
66: Array& operator += (T src) {
67: if(is_full())
68: expand(fdelta);
1.24 paf 69:
1.57.2.2 paf 70: felements[fused++]=src;
1.37 paf 71:
1.57.2.2 paf 72: return *this;
1.34 paf 73: }
1.35 paf 74:
1.57.2.2 paf 75: /// append other Array portion to this one. starting from offset
76: Array& append(const Array& src, int offset=0, int limit=0) {
77: if(!(offset>=0 && offset<src.count())) {
1.57.2.4 paf 78: throw Exception(0,
79: Exception::undefined_source,
1.57.2.2 paf 80: "Array::append(offset=%d) out of range [0..%d]", offset, src.count()-1);
81: //return 0; // never
82: }
83: // fix limit
84: {
85: int m=src.count()-offset;
86: if(!m || limit<0)
87: return *this;
88: if(!limit || limit>m)
89: limit=m;
90: }
1.29 paf 91:
1.57.2.23 paf 92: int delta=limit-(fallocated-fused);
93: if(delta>0)
94: expand(delta);
95:
96: T* from=&src.felements[offset];
97: T* to=&felements[fused];
98: T* from_end=from+limit;
99: while(from<from_end)
100: *to++=*from++;
101:
102: fused+=limit;
1.57.2.4 paf 103: return *this;
1.57.2.2 paf 104: }
1.49 paf 105:
1.57.2.2 paf 106: /// get index-element
1.57.2.21 paf 107: T& get(int index) const {
1.57.2.4 paf 108: if(!(index>=0 && index<count())) {
109: throw Exception(0,
110: Exception::undefined_source,
1.57.2.2 paf 111: "Array::get(%d) out of range [0..%d]", index, count()-1);
1.57.2.15 paf 112: return felements[0]; // never
1.57.2.2 paf 113: }
1.29 paf 114:
1.57.2.2 paf 115: return felements[index];
116: }
1.57.2.12 paf 117:
1.57.2.21 paf 118: T& operator [](int index) const { return get(index); }
1.32 paf 119:
1.57.2.2 paf 120: /// put index-element
1.57.2.15 paf 121: void put(int index, T& element) {
1.57.2.11 paf 122: if(!(index>=0 && index<count())) {
1.57.2.4 paf 123: throw Exception(0,
124: Exception::undefined_source,
1.57.2.11 paf 125: "Array::put(%d) out of range [0..%d]", index, count()-1);
1.57.2.2 paf 126: return; // never
127: }
128: felements[index]=element;
129: }
1.1 paf 130:
1.7 paf 131:
1.57.2.2 paf 132: /// iterate over all elements
1.57.2.6 paf 133: template<typename I> void for_each(void (*callback)(T, I), I info) const {
1.57.2.2 paf 134: T *last=felements+fused;
135: for(T *current=felements; current<last; current++)
136: callback(*current, info);
137: }
1.1 paf 138:
1.57.2.2 paf 139: /// iterate over all elements until condition becomes true, return that element
1.57.2.6 paf 140: template<typename I> T first_that(bool (*callback)(T, I), I info) const {
1.57.2.2 paf 141: T *last=felements+fused;
142: for(T *current=felements; current<last; current++)
143: if(callback(*current, info))
144: return *current;
1.7 paf 145:
1.57.2.20 paf 146: return T(0);
1.57.2.2 paf 147: }
1.1 paf 148:
1.57.2.3 paf 149: protected:
1.1 paf 150:
1.57.2.2 paf 151: bool is_full() {
152: return fused == fallocated;
153: }
154: void expand(int delta) {
1.57.2.22 paf 155: felements = (T *)realloc(felements, (fallocated+delta)*sizeof(T));
156: memset(&felements[fallocated], 0, delta*sizeof(T));
1.57.2.2 paf 157: fallocated+=delta;
1.1 paf 158: }
1.2 paf 159:
1.1 paf 160: private: //disabled
161:
1.12 paf 162: Array& operator = (const Array&) { return *this; }
1.57.2.5 paf 163: };
164:
165: typedef smart_ptr<char> CharPtr;
166:
1.57.2.22 paf 167: /**
168: Pool mechanizm allows users not to free up allocated memory,
169: leaving that problem to 'pools'.
170: */
1.57.2.5 paf 171: class Pool: public Array<CharPtr> {
172: public:
173: char *malloc(size_t size) {
1.57.2.10 paf 174: CharPtr result=CharPtr((char *)Array<CharPtr>::malloc(size));
1.57.2.5 paf 175: *this += result;
176: return result.get();
1.57.2.8 paf 177: }
178:
1.57.2.16 paf 179: char *copy(const char* buf, size_t size=0) {
1.57.2.11 paf 180: if(!size)
181: size=strlen(buf)+1;
182:
1.57.2.8 paf 183: char *result=malloc(size);
184: memcpy(result, buf, size);
185: return result;
1.57.2.5 paf 186: }
1.57.2.24! paf 187:
! 188: char *format_integer(int value);
1.42 parser 189: };
1.57.2.7 paf 190:
1.57.2.19 paf 191: inline void *operator new[] (size_t size, Pool& pool) {
1.57.2.7 paf 192: return pool.malloc(size);
193: }
1.42 parser 194:
195: /// handy array iterator
1.57.2.2 paf 196: template<typename T> class Array_iterator {
197:
1.57.2.9 paf 198: Array<T>& farray;
1.57.2.2 paf 199: T *fcurrent;
200: T *flast;
201:
1.42 parser 202: public:
203:
1.57.2.9 paf 204: Array_iterator(Array<T>& aarray): farray(aarray) {
205: fcurrent=farray.felements;
206: flast=farray.felements+farray.count();
1.42 parser 207: }
208:
209: /// there are still elements
210: bool has_next() {
1.57.2.2 paf 211: return fcurrent<flast;
1.42 parser 212: }
213:
1.57.2.2 paf 214: /// quickly extracts next Array element
1.57.2.17 paf 215: T& next() {
1.57.2.9 paf 216: return *(fcurrent++);
1.42 parser 217: }
218:
1.1 paf 219: };
220:
221: #endif
E-mail: