--- parser3/src/include/pa_array.h 2003/01/23 11:37:55 1.57.2.2 +++ parser3/src/include/pa_array.h 2003/04/11 15:00:05 1.58 @@ -1,5 +1,5 @@ /** @file - Parser: Array & Array_iterator classes decls. + Parser: Array & Array_iter classes decls. Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) @@ -8,164 +8,191 @@ #ifndef PA_ARRAY_H #define PA_ARRAY_H -static const char* IDENT_ARRAY_Y="$Date: 2003/01/23 11:37:55 $"; +static const char* IDENT_ARRAY_Y="$Date: 2003/04/11 15:00:05 $"; #include "pa_pool.h" -//#include "pa_types.h" +#include "pa_types.h" +#include "pa_string.h" -class Array_iterator; +class Array_iter; /** - Simple Array. + Pooled Array. + Internal structure: + @verbatim + Array Chunk0 + ====== ======== + head--------------->[ptr] + append_here-------->[ptr] + link_row ........ + . . + . [ptr] + ...........>[link to the next chunk] + @endverbatim */ -template class Array: public PA_Object { - friend class Array_iterator; - - /// elements[growing size] here - T *felements; - - // array size - int fused; +class Array : public Pooled { + friend class Array_iter; +public: - // allocated size - int fallocated; + /// Array item type + typedef void Item; - // default expand delta size - int fdelta; + /*/// for_each iterator function type, const info + typedef void (*For_each_func_const)(Item *value, const void *info); + */ + + /// for_each iterator function type + typedef void (*For_each_func)(Item *value, void *info); + /* + /// for_each iterator function type, passing item storage address + typedef void (*For_each_func_storage)(Item ** value, void *info); + */ + + /// first_that iterator function type, const info + typedef void *(*Item_that_func_const)(Item *value, const void *info); + + /// first_that iterator function type + typedef void *(*Item_that_func)(Item *value, void *info); + + enum { + CR_INITIAL_ROWS_DEFAULT=3, ///< default preallocated row count + CR_GROW_COUNT=3 ///< each time the Array chunk_is_full() array expanded() + }; public: - typedef T element_type; - - Array(int initial=3, int delta=5): - fallocated(initial?initial:3), - fdelta(delta), - fused(0) - { - if(fallocated<=0 || fdelta<1) { - throw Exception(0, 0, - "Array::Array(%d, %d) too small", initial, delta); - - felements=new T[fallocated]; - } - override ~Array() { - delete felements; - } - /// how many items are in Array - int count() const { return fused; } - /// append to array - Array& operator += (T src) { - if(is_full()) - expand(fdelta); + Array(Pool& apool, int initial_rows=CR_INITIAL_ROWS_DEFAULT); - felements[fused++]=src; + /// size Array. how many items are in it + int size() const { return fused_rows; } + /// append Item to array + Array& operator += (Item *src); + /// append int value to array + Array& operator += (int value) { return *this+=reinterpret_cast(value); } - return *this; - } + /// dirty hack to allow constant items storage. I long for Array + Array& operator += (const Item *src) { return *this+=const_cast(src); } /// append other Array portion to this one. starting from offset - Array& append(const Array& src, int offset=0, int limit=0) { - if(!(offset>=0 && offsetm) - limit=m; - } + Array& append_array(const Array& src, + int offset=0, + int limit=-1, //< negative limit means 'all'. zero limit means 'nothing' + bool reverse=false); + + Item *get(int index) const; + int get_int(int index) const { return reinterpret_cast(get(index)); } + + void put(int index, Item *item); + void put_int(int index, int value) { put(index, reinterpret_cast(value)); } + /// convinient way to get strings from Array. I long for Array + const String *get_string(int index) const { + return const_cast(static_cast(get(index))); + } + + /*/// iterate over all elements, const info + void for_each(For_each_func_const func, const void *info=0) const; + */ - int needed=limit-(fallocated-fused); - if(needed>0) - expand(needed); - - memcpy(&felements[fused+=limit], &src.felements[offset], limit*sizeof(T)); - } + /// iterate over all elements + void for_each(For_each_func func, void *info=0) const; - /// get index-element - T get(int index) const { - if(!(index>=0 && index=0 && index void for_each(void callback(T, I), I info) const { - T *last=felements+fused; - for(T *current=felements; current T *first_that(bool callback(T, I), I info) const { - T *last=felements+fused; - for(T *current=felements; current class Array_iterator { - - const Array& farray; - T *fcurrent; - T *flast; +/// handy array iterator +class Array_iter { public: - Array_iterator(const Array& aarray) : farray(aarray) { - fcurrent(farray.felements); - flast=farray+farray.count(); + Array_iter(const Array& aarray) : array(aarray), + chunk(aarray.head), + row(chunk->rows), + countdown(chunk->count) { } /// there are still elements bool has_next() { - return fcurrentlink; + row=chunk->rows; + countdown=chunk->count; + } + Array::Item *result=row->item; + row++; countdown--; + return result; } - /// quickly extracts next Array element - T next() { - return *(furrent++); + /// quickly extracts next Array::Item as const String + const String *next_string() { + return const_cast(static_cast(next())); } +private: + const Array& array; + const Array::Chunk *chunk; + const Array::Chunk::Row *row; + int countdown; + }; #endif