Annotation of parser3/src/include/pa_array.h, revision 1.57.2.14
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.14! paf 11: static const char* IDENT_ARRAY_Y="$Date: 2003/01/28 13:15:18 $";
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.2 paf 53: felements=new T[fallocated];
54: }
55: override ~Array() {
1.57.2.3 paf 56: T *last=felements+fused;
57: for(T *current=felements; current<last; current++)
58: delete current;
59:
1.57.2.2 paf 60: delete felements;
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.2 paf 92: int needed=limit-(fallocated-fused);
93: if(needed>0)
94: expand(needed);
95:
96: memcpy(&felements[fused+=limit], &src.felements[offset], limit*sizeof(T));
1.57.2.4 paf 97: return *this;
1.57.2.2 paf 98: }
1.49 paf 99:
1.57.2.2 paf 100: /// get index-element
101: T get(int index) const {
1.57.2.4 paf 102: if(!(index>=0 && index<count())) {
103: throw Exception(0,
104: Exception::undefined_source,
1.57.2.2 paf 105: "Array::get(%d) out of range [0..%d]", index, count()-1);
106: return 0; // never
107: }
1.29 paf 108:
1.57.2.2 paf 109: return felements[index];
110: }
1.57.2.12 paf 111:
112: T operator [](int index) const { return get(index); }
1.32 paf 113:
1.57.2.2 paf 114: /// put index-element
115: void put(int index, T element) {
1.57.2.11 paf 116: if(!(index>=0 && index<count())) {
1.57.2.4 paf 117: throw Exception(0,
118: Exception::undefined_source,
1.57.2.11 paf 119: "Array::put(%d) out of range [0..%d]", index, count()-1);
1.57.2.2 paf 120: return; // never
121: }
122: felements[index]=element;
123: }
1.1 paf 124:
1.7 paf 125:
1.57.2.2 paf 126: /// iterate over all elements
1.57.2.6 paf 127: template<typename I> void for_each(void (*callback)(T, I), I info) const {
1.57.2.2 paf 128: T *last=felements+fused;
129: for(T *current=felements; current<last; current++)
130: callback(*current, info);
131: }
1.1 paf 132:
1.57.2.2 paf 133: /// iterate over all elements until condition becomes true, return that element
1.57.2.6 paf 134: template<typename I> T first_that(bool (*callback)(T, I), I info) const {
1.57.2.2 paf 135: T *last=felements+fused;
136: for(T *current=felements; current<last; current++)
137: if(callback(*current, info))
138: return *current;
1.7 paf 139:
1.57.2.6 paf 140: return 0;//T(0);
1.57.2.2 paf 141: }
1.1 paf 142:
1.57.2.3 paf 143: protected:
1.1 paf 144:
1.57.2.2 paf 145: bool is_full() {
146: return fused == fallocated;
147: }
148: void expand(int delta) {
149: fallocated+=delta;
1.57.2.10 paf 150: felements = (T *)realloc(felements, fallocated*sizeof(T));
1.1 paf 151: }
1.2 paf 152:
1.1 paf 153: private: //disabled
154:
1.12 paf 155: Array& operator = (const Array&) { return *this; }
1.57.2.5 paf 156: };
157:
158: typedef smart_ptr<char> CharPtr;
159:
160: class Pool: public Array<CharPtr> {
161: public:
162: char *malloc(size_t size) {
1.57.2.10 paf 163: CharPtr result=CharPtr((char *)Array<CharPtr>::malloc(size));
1.57.2.5 paf 164: *this += result;
165: return result.get();
1.57.2.8 paf 166: }
167:
1.57.2.11 paf 168: char *copy(const char *buf, size_t size=0) {
169: if(!size)
170: size=strlen(buf)+1;
171:
1.57.2.8 paf 172: char *result=malloc(size);
173: memcpy(result, buf, size);
174: return result;
1.57.2.5 paf 175: }
1.42 parser 176: };
1.57.2.7 paf 177:
1.57.2.14! paf 178: inline void *operator new(size_t size, Pool& pool) {
1.57.2.7 paf 179: return pool.malloc(size);
180: }
1.42 parser 181:
182: /// handy array iterator
1.57.2.2 paf 183: template<typename T> class Array_iterator {
184:
1.57.2.9 paf 185: Array<T>& farray;
1.57.2.2 paf 186: T *fcurrent;
187: T *flast;
188:
1.42 parser 189: public:
190:
1.57.2.9 paf 191: Array_iterator(Array<T>& aarray): farray(aarray) {
192: fcurrent=farray.felements;
193: flast=farray.felements+farray.count();
1.42 parser 194: }
195:
196: /// there are still elements
197: bool has_next() {
1.57.2.2 paf 198: return fcurrent<flast;
1.42 parser 199: }
200:
1.57.2.2 paf 201: /// quickly extracts next Array element
202: T next() {
1.57.2.9 paf 203: return *(fcurrent++);
1.42 parser 204: }
205:
1.1 paf 206: };
207:
208: #endif
E-mail: