Annotation of parser3/src/include/pa_array.h, revision 1.57.2.5
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.5! paf 11: static const char* IDENT_ARRAY_Y="$Date: 2003/01/23 16:08:00 $";
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.2 paf 24: friend class Array_iterator;
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
114: template<typename I> void for_each(void callback(T, I), I info) const {
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
121: template<typename I> T *first_that(bool callback(T, I), I info) const {
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.2 paf 127: return 0;
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;
146: felements = (T *)pa_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) {
! 159: CharPtr result=CharPtr(new char[size]);
! 160: *this += result;
! 161: return result.get();
! 162: }
1.42 parser 163: };
164:
165: /// handy array iterator
1.57.2.2 paf 166: template<typename T> class Array_iterator {
167:
168: const Array<T>& farray;
169: T *fcurrent;
170: T *flast;
171:
1.42 parser 172: public:
173:
1.57.2.2 paf 174: Array_iterator(const Array<T>& aarray) : farray(aarray) {
175: fcurrent(farray.felements);
176: flast=farray+farray.count();
1.42 parser 177: }
178:
179: /// there are still elements
180: bool has_next() {
1.57.2.2 paf 181: return fcurrent<flast;
1.42 parser 182: }
183:
1.57.2.2 paf 184: /// quickly extracts next Array element
185: T next() {
186: return *(furrent++);
1.42 parser 187: }
188:
1.1 paf 189: };
190:
191: #endif
E-mail: