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