Annotation of parser3/src/include/pa_array.h, revision 1.57.2.3
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.3! paf 11: static const char* IDENT_ARRAY_Y="$Date: 2003/01/23 11:37:55 $";
1.24 paf 12:
13: #include "pa_pool.h"
1.57.2.2 paf 14: //#include "pa_types.h"
1.57.2.3! paf 15: #include "pa_exception.h"
1.24 paf 16:
1.57.2.3! paf 17: template<typename T> class Array_iterator;
1.42 parser 18:
1.25 paf 19: /**
1.57.2.2 paf 20: Simple Array.
1.24 paf 21:
1.1 paf 22: */
1.57.2.2 paf 23: template<typename T> class Array: public PA_Object {
1.1 paf 24:
1.57.2.2 paf 25: friend class Array_iterator;
26:
27: // allocated size
28: int fallocated;
1.1 paf 29:
1.57.2.2 paf 30: public:
31: typedef T element_type;
1.7 paf 32:
1.57.2.3! paf 33: Array(int initial=3, int delta=1):
1.57.2.2 paf 34: fallocated(initial?initial:3),
35: fdelta(delta),
36: fused(0)
37: {
1.57.2.3! paf 38: if(fallocated<=0 || fdelta<1)
1.57.2.2 paf 39: throw Exception(0, 0,
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())) {
67: throw Exception(0, 0,
68: "Array::append(offset=%d) out of range [0..%d]", offset, src.count()-1);
69: //return 0; // never
70: }
71: // fix limit
72: {
73: int m=src.count()-offset;
74: if(!m || limit<0)
75: return *this;
76: if(!limit || limit>m)
77: limit=m;
78: }
1.29 paf 79:
1.57.2.2 paf 80: int needed=limit-(fallocated-fused);
81: if(needed>0)
82: expand(needed);
83:
84: memcpy(&felements[fused+=limit], &src.felements[offset], limit*sizeof(T));
85: }
1.49 paf 86:
1.57.2.2 paf 87: /// get index-element
88: T get(int index) const {
89: if(!(index>=0 && index<size())) {
90: throw Exception(0, 0,
91: "Array::get(%d) out of range [0..%d]", index, count()-1);
92: return 0; // never
93: }
1.29 paf 94:
1.57.2.2 paf 95: return felements[index];
96: }
1.32 paf 97:
1.57.2.2 paf 98: /// put index-element
99: void put(int index, T element) {
100: if(!(index>=0 && index<size())) {
101: throw Exception(0, 0,
102: "Array::put(%d) out of range [0..%d]", index, size()-1);
103: return; // never
104: }
105: felements[index]=element;
106: }
1.1 paf 107:
1.7 paf 108:
1.57.2.2 paf 109: /// iterate over all elements
110: template<typename I> void for_each(void callback(T, I), I info) const {
111: T *last=felements+fused;
112: for(T *current=felements; current<last; current++)
113: callback(*current, info);
114: }
1.1 paf 115:
1.57.2.2 paf 116: /// iterate over all elements until condition becomes true, return that element
117: template<typename I> T *first_that(bool callback(T, I), I info) const {
118: T *last=felements+fused;
119: for(T *current=felements; current<last; current++)
120: if(callback(*current, info))
121: return *current;
1.7 paf 122:
1.57.2.2 paf 123: return 0;
124: }
1.1 paf 125:
1.57.2.3! paf 126: protected:
! 127:
! 128: // default expand delta size
! 129: int fdelta;
! 130:
! 131: /// elements[growing size] here
! 132: T *felements;
! 133:
! 134: // array size
! 135: int fused;
1.1 paf 136:
1.57.2.2 paf 137: bool is_full() {
138: return fused == fallocated;
139: }
140: void expand(int delta) {
141: fallocated+=delta;
142: felements = (T *)pa_realloc(felements, fallocated*sizeof(T));
1.1 paf 143: }
1.2 paf 144:
1.1 paf 145: private: //disabled
146:
1.12 paf 147: Array& operator = (const Array&) { return *this; }
1.42 parser 148: };
149:
150: /// handy array iterator
1.57.2.2 paf 151: template<typename T> class Array_iterator {
152:
153: const Array<T>& farray;
154: T *fcurrent;
155: T *flast;
156:
1.42 parser 157: public:
158:
1.57.2.2 paf 159: Array_iterator(const Array<T>& aarray) : farray(aarray) {
160: fcurrent(farray.felements);
161: flast=farray+farray.count();
1.42 parser 162: }
163:
164: /// there are still elements
165: bool has_next() {
1.57.2.2 paf 166: return fcurrent<flast;
1.42 parser 167: }
168:
1.57.2.2 paf 169: /// quickly extracts next Array element
170: T next() {
171: return *(furrent++);
1.42 parser 172: }
173:
1.1 paf 174: };
175:
176: #endif
E-mail: