Annotation of parser3/src/include/pa_array.h, revision 1.57.2.10
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.10! paf 11: static const char* IDENT_ARRAY_Y="$Date: 2003/01/27 15:07:47 $";
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.32 paf 100:
1.57.2.2 paf 101: /// put index-element
102: void put(int index, T element) {
103: if(!(index>=0 && index<size())) {
1.57.2.4 paf 104: throw Exception(0,
105: Exception::undefined_source,
1.57.2.2 paf 106: "Array::put(%d) out of range [0..%d]", index, size()-1);
107: return; // never
108: }
109: felements[index]=element;
110: }
1.1 paf 111:
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.6 paf 127: return 0;//T(0);
1.57.2.2 paf 128: }
1.1 paf 129:
1.57.2.3 paf 130: protected:
131:
132: // default expand delta size
133: int fdelta;
134:
135: /// elements[growing size] here
136: T *felements;
137:
138: // array size
139: int fused;
1.1 paf 140:
1.57.2.2 paf 141: bool is_full() {
142: return fused == fallocated;
143: }
144: void expand(int delta) {
145: fallocated+=delta;
1.57.2.10! paf 146: felements = (T *)realloc(felements, fallocated*sizeof(T));
1.1 paf 147: }
1.2 paf 148:
1.1 paf 149: private: //disabled
150:
1.12 paf 151: Array& operator = (const Array&) { return *this; }
1.57.2.5 paf 152: };
153:
154: typedef smart_ptr<char> CharPtr;
155:
156: class Pool: public Array<CharPtr> {
157: public:
158: char *malloc(size_t size) {
1.57.2.10! paf 159: CharPtr result=CharPtr((char *)Array<CharPtr>::malloc(size));
1.57.2.5 paf 160: *this += result;
161: return result.get();
1.57.2.8 paf 162: }
163:
164: char *malloc(const char *buf, size_t size) {
165: char *result=malloc(size);
166: memcpy(result, buf, size);
167: return result;
1.57.2.5 paf 168: }
1.42 parser 169: };
1.57.2.7 paf 170:
171: void *operator new(size_t size, Pool& pool) {
172: return pool.malloc(size);
173: }
1.42 parser 174:
175: /// handy array iterator
1.57.2.2 paf 176: template<typename T> class Array_iterator {
177:
1.57.2.9 paf 178: Array<T>& farray;
1.57.2.2 paf 179: T *fcurrent;
180: T *flast;
181:
1.42 parser 182: public:
183:
1.57.2.9 paf 184: Array_iterator(Array<T>& aarray): farray(aarray) {
185: fcurrent=farray.felements;
186: flast=farray.felements+farray.count();
1.42 parser 187: }
188:
189: /// there are still elements
190: bool has_next() {
1.57.2.2 paf 191: return fcurrent<flast;
1.42 parser 192: }
193:
1.57.2.2 paf 194: /// quickly extracts next Array element
195: T next() {
1.57.2.9 paf 196: return *(fcurrent++);
1.42 parser 197: }
198:
1.1 paf 199: };
200:
201: #endif
E-mail: