--- parser3/src/include/pa_array.h 2003/02/17 09:56:15 1.57.2.22 +++ parser3/src/include/pa_array.h 2003/04/11 15:00:05 1.58 @@ -1,213 +1,198 @@ /** @file - Parser: Array & Array_iterator classes decls. + Parser: Array & Array_iter classes decls. - Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ #ifndef PA_ARRAY_H #define PA_ARRAY_H -static const char* IDENT_ARRAY_Y="$Date: 2003/02/17 09:56:15 $"; +static const char* IDENT_ARRAY_Y="$Date: 2003/04/11 15:00:05 $"; #include "pa_pool.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; - -protected: - - // default expand delta size - int fdelta; - - /// elements[growing size] here - T *felements; +class Array : public Pooled { + friend class Array_iter; +public: - // allocated size - int fallocated; + /// Array item type + typedef void Item; - // array size - int fused; + /*/// 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=1): - fallocated(initial?initial:3), - fdelta(delta), - fused(0) - { - if(fallocated<=0 || fdelta<1) - throw Exception(0, - Exception::undefined_source, - "Array::Array(%d, %d) too small", initial, delta); - - felements=static_cast(calloc(fallocated*sizeof(T))); - } - override ~Array() { - T *last=felements+fused; - for(T *current=felements; current~T(); // manually invoking destructors - - free(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; - } - - int needed=limit-(fallocated-fused); - if(needed>0) - expand(needed); - - memcpy(&felements[fused+=limit], &src.felements[offset], limit*sizeof(T)); - return *this; - } - - /// 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 CharPtr; - -/** - Pool mechanizm allows users not to free up allocated memory, - leaving that problem to 'pools'. -*/ -class Pool: public Array { -public: - char *malloc(size_t size) { - CharPtr result=CharPtr((char *)Array::malloc(size)); - *this += result; - return result.get(); - } - - char *copy(const char* buf, size_t size=0) { - if(!size) - size=strlen(buf)+1; - - char *result=malloc(size); - memcpy(result, buf, size); - return result; - } -}; - -inline void *operator new[] (size_t size, Pool& pool) { - return pool.malloc(size); -} /// handy array iterator -template class Array_iterator { - - Array& farray; - T *fcurrent; - T *flast; - +class Array_iter { public: - Array_iterator(Array& aarray): farray(aarray) { - fcurrent=farray.felements; - flast=farray.felements+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