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