--- parser3/src/include/pa_array.h 2003/01/23 15:38:05 1.57.2.3 +++ 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,169 +8,191 @@ #ifndef PA_ARRAY_H #define PA_ARRAY_H -static const char* IDENT_ARRAY_Y="$Date: 2003/01/23 15:38:05 $"; +static const char* IDENT_ARRAY_Y="$Date: 2003/04/11 15:00:05 $"; #include "pa_pool.h" -//#include "pa_types.h" -#include "pa_exception.h" +#include "pa_types.h" +#include "pa_string.h" -template 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; - - // allocated size - int fallocated; +class Array : public Pooled { + friend class Array_iter; public: - typedef T element_type; - Array(int initial=3, int delta=1): - 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); + /// Array item type + typedef void Item; - felements=new T[fallocated]; - } - override ~Array() { - T *last=felements+fused; - for(T *current=felements; current(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; - } - - int needed=limit-(fallocated-fused); - if(needed>0) - expand(needed); - - memcpy(&felements[fused+=limit], &src.felements[offset], limit*sizeof(T)); - } - - /// get index-element - T get(int index) const { - if(!(index>=0 && index=0 && index(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; + */ /// iterate over all elements - template 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::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