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