Diff for /parser3/src/include/pa_array.h between versions 1.1 and 1.45

version 1.1, 2001/01/27 15:00:04 version 1.45, 2001/10/29 08:23:48
Line 1 Line 1
 /*  /** @file
   $Id$          Parser: Array & Array_iter classes decls.
 */  
   
 /*  
   
         Array               Chunk0          Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
         ======              ========          Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
         head--------------->[ptr]  
         append_here-------->[ptr]  
         link_row            ........  
                         .                       .  
                         .                       [ptr]  
                         ...........>[link to the next chunk]  
   
           $Id$
 */  */
   
 #ifndef PA_ARRAY_H  #ifndef PA_ARRAY_H
 #define PA_ARRAY_H  #define PA_ARRAY_H
   
 #include <stddef.h>  #include "pa_config_includes.h"
   #include "pa_pool.h"
 #include "pa_types.h"  #include "pa_types.h"
   #include "pa_string.h"
   
   class Array_iter;
   
   /**     
           Pooled Array.
   
 class Pool;          Internal structure:
           @verbatim
                   Array               Chunk0
                   ======              ========
                   head--------------->[ptr]
                   append_here-------->[ptr]
                   link_row            ........
                                   .                       .
                                   .                       [ptr]
                                   ...........>[link to the next chunk]
           @endverbatim
   */
   
 class Array {  class Array : public Pooled {
           friend class Array_iter;
 public:  public:
         typedef void *Item;  
           /// Array item type
           typedef void Item;
   
           /*/// 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);
   
           /// 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 {          enum {
                 CR_PREALLOCATED_COUNT=10,                  CR_INITIAL_ROWS_DEFAULT=3, ///< default preallocated row count
                 CR_GROW_PERCENT=60                  CR_GROW_COUNT=3 ///< each time the Array chunk_is_full() array expanded()
         };          };
   
 private:  public:
         friend Pool;  
           Array(Pool& apool, int initial_rows=CR_INITIAL_ROWS_DEFAULT);
   
           /// 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<Item *>(value); }
   
           /// dirty hack to allow constant items storage. I long for Array<const Item*>
           Array& operator += (const Item *src) { return *this+=const_cast<Item *>(src); }
   
           /// append other Array portion to this one. starting from offset
           Array& append_array(const Array& src, int offset=0);
   
           Item *get(int index) const;
           int get_int(int index) const { return reinterpret_cast<int>(get(index)); }
   
           void put(int index, Item *item);
           /// convinient way to get strings from Array. I long for Array<const String *>
           const String *get_string(int index) const { 
                   return const_cast<const String *>(static_cast<String *>(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
           void for_each(For_each_func func, void *info=0) const;
   
         // the pool I'm allocated on          /// iterate over all elements until condition, const info
         Pool *pool;          void* first_that(Item_that_func_const func, const void *info=0) const;
   
           /// iterate over all elements until condition
           void* first_that(Item_that_func func, void *info=0) const;
   
   private:
   
           /// several record elements
         struct Chunk {          struct Chunk {
                 // the number of rows in chunk                  int count;  ///< the number of rows in chunk
                 int count;                  /// item or a link to next chunk union
                 union Row {                  union Row {
                         Item item;                          Item *item;
                         Chunk *link;  // link to the next chunk in chain                          Chunk *link;  ///< link to the next chunk in chain
                 } rows[1];                  } rows[1];
                 // next rows are here                  // next rows are here
         }          }
                 *head;  // the head chunk of the chunk chain                  *head;  ///< the head chunk of the chunk chain
   
           /** last allocated chunk
                   helps appending Arrays
           */
           Chunk *tail;
   
         // next append would write to this record          /// next append would write to this record
         Chunk::Row *append_here;          Chunk::Row *append_here;
                   
         // the address of place where lies address           /**     the address of place where lies address 
         // of the link to the next chunk to allocate                  of the link to the next chunk to allocate
           */
         Chunk::Row *link_row;          Chunk::Row *link_row;
   
 private:  private:
         // last chank allocated count  
         int curr_chunk_rows;  
   
         // array size          // array size
         int fused_rows;          int fused_rows;
   
           mutable int cache_chunk_base;
           mutable Chunk *cache_chunk;
           
 private:  private:
         // new&constructors made private to enforce factory manufacturing at pool  
         void *operator new(size_t size, Pool *apool);  
   
         void construct(Pool *apool, int initial_rows);  
         Array(Pool *apool) {  
                 construct(apool, CR_PREALLOCATED_COUNT);   
         }  
         Array(Pool *apool, int initial_rows) {  
                 construct(apool, initial_rows);   
         }  
   
   
         bool chunk_is_full() {          bool chunk_is_full() {
                 return append_here == link_row;                  return append_here == link_row;
         }          }
         void expand();          void expand(int chunk_rows);
   
 private: //disabled  private: //disabled
   
         Array& operator = (Array& src) { return *this; }          //Array(Array&) { }
         Array(Array& src) {}          Array& operator = (const Array&) { return *this; }
   };
   
   
   /// handy array iterator
   class Array_iter {
 public:  public:
   
         int size() { return fused_rows; }          Array_iter(const Array& aarray) : array(aarray),
         Array& operator += (Item src);                  chunk(aarray.head),
                   row(chunk->rows),
                   countdown(chunk->count) {
           }
   
           /// there are still elements
           bool has_next() {
                   return !(chunk==array.tail && row==array.append_here);
           }
   
           /// quickly extracts next Array::Item
           Array::Item *next() {
                   // assuming: never called after has_next()!
                   if(countdown==0) { // end of chunk?
                           chunk=row->link;
                           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<const String *>(static_cast<String *>(next())); 
           }
   
   private:
           const Array& array;
           const Array::Chunk *chunk;
           const Array::Chunk::Row *row;
           int countdown;  
   
 };  };
   
 #endif  #endif

Removed from v.1.1  
changed lines
  Added in v.1.45


E-mail: