Annotation of parser3/src/include/pa_array.h, revision 1.51
1.24 paf 1: /** @file
1.42 parser 2: Parser: Array & Array_iter classes decls.
1.26 paf 3:
1.21 paf 4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
1.47 paf 5: Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru)
1.21 paf 6:
1.51 ! paf 7: $Id: pa_array.h,v 1.50 2002/02/07 11:16:27 paf Exp $
1.1 paf 8: */
9:
1.24 paf 10: #ifndef PA_ARRAY_H
11: #define PA_ARRAY_H
12:
13: #include "pa_pool.h"
14: #include "pa_types.h"
15: #include "pa_string.h"
16:
1.42 parser 17: class Array_iter;
18:
1.25 paf 19: /**
1.24 paf 20: Pooled Array.
21:
1.27 paf 22: Internal structure:
23: @verbatim
24: Array Chunk0
25: ====== ========
26: head--------------->[ptr]
27: append_here-------->[ptr]
28: link_row ........
29: . .
30: . [ptr]
31: ...........>[link to the next chunk]
1.24 paf 32: @endverbatim
1.1 paf 33: */
34:
1.13 paf 35: class Array : public Pooled {
1.45 paf 36: friend class Array_iter;
1.1 paf 37: public:
1.7 paf 38:
1.29 paf 39: /// Array item type
40: typedef void Item;
41:
1.35 paf 42: /*/// for_each iterator function type, const info
43: typedef void (*For_each_func_const)(Item *value, const void *info);
44: */
45:
1.29 paf 46: /// for_each iterator function type
47: typedef void (*For_each_func)(Item *value, void *info);
1.49 paf 48: /*
49: /// for_each iterator function type, passing item storage address
50: typedef void (*For_each_func_storage)(Item ** value, void *info);
51: */
1.29 paf 52:
1.32 paf 53: /// first_that iterator function type, const info
1.43 parser 54: typedef void *(*Item_that_func_const)(Item *value, const void *info);
1.32 paf 55:
1.29 paf 56: /// first_that iterator function type
1.43 parser 57: typedef void *(*Item_that_func)(Item *value, void *info);
1.10 paf 58:
1.1 paf 59: enum {
1.39 parser 60: CR_INITIAL_ROWS_DEFAULT=3, ///< default preallocated row count
61: CR_GROW_COUNT=3 ///< each time the Array chunk_is_full() array expanded()
1.1 paf 62: };
63:
1.6 paf 64: public:
65:
1.11 paf 66: Array(Pool& apool, int initial_rows=CR_INITIAL_ROWS_DEFAULT);
1.51 ! paf 67: Array(const Array& source, int offset=0);
1.7 paf 68:
1.33 paf 69: /// size Array. how many items are in it
70: int size() const { return fused_rows; }
1.24 paf 71: /// append Item to array
1.15 paf 72: Array& operator += (Item *src);
1.37 paf 73: /// append int value to array
74: Array& operator += (int value) { return *this+=reinterpret_cast<Item *>(value); }
1.24 paf 75:
76: /// dirty hack to allow constant items storage. I long for Array<const Item*>
1.37 paf 77: Array& operator += (const Item *src) { return *this+=const_cast<Item *>(src); }
1.24 paf 78:
79: /// append other Array portion to this one. starting from offset
1.19 paf 80: Array& append_array(const Array& src, int offset=0);
1.24 paf 81:
1.15 paf 82: Item *get(int index) const;
1.37 paf 83: int get_int(int index) const { return reinterpret_cast<int>(get(index)); }
84:
1.17 paf 85: void put(int index, Item *item);
1.50 paf 86: void put_int(int index, int value) { put(index, reinterpret_cast<Item *>(value)); }
1.24 paf 87: /// convinient way to get strings from Array. I long for Array<const String *>
1.12 paf 88: const String *get_string(int index) const {
1.28 paf 89: return const_cast<const String *>(static_cast<String *>(get(index)));
1.34 paf 90: }
1.35 paf 91:
92: /*/// iterate over all elements, const info
93: void for_each(For_each_func_const func, const void *info=0) const;
1.49 paf 94: */
1.29 paf 95:
96: /// iterate over all elements
1.31 paf 97: void for_each(For_each_func func, void *info=0) const;
1.49 paf 98:
99: /*/// iterate over all elements, passing address of item storage
100: void for_each(For_each_func_storage func, void *info=0);
101: */
1.29 paf 102:
1.32 paf 103: /// iterate over all elements until condition, const info
1.43 parser 104: void* first_that(Item_that_func_const func, const void *info=0) const;
1.32 paf 105:
1.29 paf 106: /// iterate over all elements until condition
1.43 parser 107: void* first_that(Item_that_func func, void *info=0) const;
1.51 ! paf 108:
! 109: private:
! 110:
! 111: /// constructor helper
! 112: void construct_new(int initial_rows);
1.1 paf 113:
1.7 paf 114: private:
115:
1.36 paf 116: /// several record elements
1.1 paf 117: struct Chunk {
1.36 paf 118: int count; ///< the number of rows in chunk
119: /// item or a link to next chunk union
1.1 paf 120: union Row {
1.15 paf 121: Item *item;
1.36 paf 122: Chunk *link; ///< link to the next chunk in chain
1.1 paf 123: } rows[1];
124: // next rows are here
125: }
1.36 paf 126: *head; ///< the head chunk of the chunk chain
1.1 paf 127:
1.36 paf 128: /** last allocated chunk
129: helps appending Arrays
130: */
1.5 paf 131: Chunk *tail;
132:
1.36 paf 133: /// next append would write to this record
1.1 paf 134: Chunk::Row *append_here;
135:
1.36 paf 136: /** the address of place where lies address
137: of the link to the next chunk to allocate
138: */
1.1 paf 139: Chunk::Row *link_row;
140:
141: private:
1.7 paf 142:
1.1 paf 143: // array size
144: int fused_rows;
145:
146: private:
147:
148: bool chunk_is_full() {
149: return append_here == link_row;
150: }
1.5 paf 151: void expand(int chunk_rows);
1.2 paf 152:
1.1 paf 153: private: //disabled
154:
1.11 paf 155: //Array(Array&) { }
1.12 paf 156: Array& operator = (const Array&) { return *this; }
1.42 parser 157: };
158:
159:
160: /// handy array iterator
161: class Array_iter {
162: public:
163:
164: Array_iter(const Array& aarray) : array(aarray),
165: chunk(aarray.head),
166: row(chunk->rows),
167: countdown(chunk->count) {
168: }
169:
170: /// there are still elements
171: bool has_next() {
172: return !(chunk==array.tail && row==array.append_here);
173: }
174:
175: /// quickly extracts next Array::Item
176: Array::Item *next() {
177: // assuming: never called after has_next()!
178: if(countdown==0) { // end of chunk?
179: chunk=row->link;
180: row=chunk->rows;
181: countdown=chunk->count;
182: }
183: Array::Item *result=row->item;
184: row++; countdown--;
185: return result;
186: }
187:
188: /// quickly extracts next Array::Item as const String
189: const String *next_string() {
190: return const_cast<const String *>(static_cast<String *>(next()));
191: }
192:
193: private:
194: const Array& array;
195: const Array::Chunk *chunk;
196: const Array::Chunk::Row *row;
197: int countdown;
198:
1.1 paf 199: };
200:
201: #endif
E-mail: