|
|
| version 1.30, 2001/03/29 17:11:41 | version 1.41, 2001/10/29 13:04:46 |
|---|---|
| Line 2 | Line 2 |
| Parser: array class. | Parser: array class. |
| Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) | Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) |
| $Id$ | $Id$ |
| */ | */ |
| #include "pa_config_includes.h" | |
| #include "pa_pool.h" | #include "pa_pool.h" |
| #include "pa_array.h" | #include "pa_array.h" |
| #include "pa_exception.h" | #include "pa_exception.h" |
| Line 17 | Line 14 |
| Array::Array(Pool& apool, int initial_rows) : | Array::Array(Pool& apool, int initial_rows) : |
| Pooled(apool) { | Pooled(apool) { |
| initial_rows=min(3, initial_rows); | initial_rows=max(initial_rows, CR_INITIAL_ROWS_DEFAULT); |
| head=tail=static_cast<Chunk *>( | head=tail=static_cast<Chunk *>( |
| malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *))); | malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *), 19)); |
| head->count=initial_rows; | head->count=initial_rows; |
| append_here=head->rows; | append_here=head->rows; |
| link_row=&head->rows[initial_rows]; | link_row=&head->rows[initial_rows]; |
| Line 32 Array::Array(Pool& apool, int initial_ro | Line 29 Array::Array(Pool& apool, int initial_ro |
| } | } |
| void Array::expand(int chunk_rows) { | void Array::expand(int chunk_rows) { |
| if(chunk_rows<CR_INITIAL_ROWS_DEFAULT) | |
| chunk_rows=CR_INITIAL_ROWS_DEFAULT; | |
| Chunk *chunk=tail=static_cast<Chunk *>( | Chunk *chunk=tail=static_cast<Chunk *>( |
| malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *))); | malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *), 2)); |
| chunk->count=chunk_rows; | chunk->count=chunk_rows; |
| link_row->link=chunk; | link_row->link=chunk; |
| append_here=chunk->rows; | append_here=chunk->rows; |
| Line 47 void Array::expand(int chunk_rows) { | Line 41 void Array::expand(int chunk_rows) { |
| Array& Array::operator += (Item *src) { | Array& Array::operator += (Item *src) { |
| if(chunk_is_full()) | if(chunk_is_full()) |
| expand(tail->count*CR_GROW_PERCENT/100); | expand(tail->count+CR_GROW_COUNT); |
| append_here->item=src; | append_here->item=src; |
| append_here++; fused_rows++; | append_here++; fused_rows++; |
| Line 57 Array& Array::operator += (Item *src) { | Line 51 Array& Array::operator += (Item *src) { |
| Array::Item *Array::get(int index) const { | Array::Item *Array::get(int index) const { |
| if(!(index>=0 && index<size())) { | if(!(index>=0 && index<size())) { |
| THROW(0, 0, 0, | throw Exception(0, 0, 0, |
| "Array::get(%d) out of range [0..%d]", index, size()-1); | "Array::get(%d) out of range [0..%d]", index, size()-1); |
| return 0; | return 0; // never |
| } | } |
| // if they ask index to the left of cached position, forget cache | // if they ask index to the left of cached position, forget cache |
| Line 80 Array::Item *Array::get(int index) const | Line 74 Array::Item *Array::get(int index) const |
| void Array::put(int index, Item *item) { | void Array::put(int index, Item *item) { |
| if(!(index>=0 && index<size())) { | if(!(index>=0 && index<size())) { |
| THROW(0, 0, 0, | throw Exception(0, 0, 0, |
| "Array::put(%d) out of range [0..%d]", index, size()-1); | "Array::put(%d) out of range [0..%d]", index, size()-1); |
| return; | return; // never |
| } | } |
| // if they ask index to the left of cached position, forget cache | // if they ask index to the left of cached position, forget cache |
| Line 167 void Array::for_each(For_each_func func, | Line 161 void Array::for_each(For_each_func func, |
| } | } |
| } | } |
| Array::Item* Array::first_that(First_that_func_const func, const void *info) const { | /*void Array::for_each(For_each_func_const func, const void *info) const { |
| Chunk *chunk=head; | |
| while(true) { | |
| if(chunk==tail) { // last chunk? | |
| for(Chunk::Row *row=chunk->rows; row!=append_here; row++) | |
| (*func)(row->item, info); | |
| break; | |
| } else { | |
| int count=chunk->count; | |
| for(int i=0; i<count; i++) | |
| (*func)(chunk->rows[i].item, info); | |
| chunk=chunk->rows[count].link; | |
| } | |
| } | |
| } | |
| */ | |
| void* Array::first_that(Item_that_func_const func, const void *info) const { | |
| Chunk *chunk=head; | Chunk *chunk=head; |
| while(true) { | while(true) { |
| if(chunk==tail) { // last chunk? | if(chunk==tail) { // last chunk? |
| for(Chunk::Row *row=chunk->rows; row!=append_here; row++) | for(Chunk::Row *row=chunk->rows; row!=append_here; row++) |
| if((*func)(row->item, info)) | if(void *result=(*func)(row->item, info)) |
| return row->item; | return result; |
| break; | break; |
| } else { | } else { |
| int count=chunk->count; | int count=chunk->count; |
| for(int i=0; i<count; i++) { | for(int i=0; i<count; i++) { |
| Item* item=chunk->rows[i].item; | Item* item=chunk->rows[i].item; |
| if((*func)(item, info)) | if(void *result=(*func)(item, info)) |
| return item; | return result; |
| } | } |
| chunk=chunk->rows[count].link; | chunk=chunk->rows[count].link; |
| } | } |
| Line 188 Array::Item* Array::first_that(First_tha | Line 198 Array::Item* Array::first_that(First_tha |
| return 0; | return 0; |
| } | } |
| Array::Item* Array::first_that(First_that_func func, void *info) const { | void* Array::first_that(Item_that_func func, void *info) const { |
| Chunk *chunk=head; | Chunk *chunk=head; |
| while(true) { | while(true) { |
| if(chunk==tail) { // last chunk? | if(chunk==tail) { // last chunk? |
| for(Chunk::Row *row=chunk->rows; row!=append_here; row++) | for(Chunk::Row *row=chunk->rows; row!=append_here; row++) |
| if((*func)(row->item, info)) | if(void *result=(*func)(row->item, info)) |
| return row->item; | return result; |
| break; | break; |
| } else { | } else { |
| int count=chunk->count; | int count=chunk->count; |
| for(int i=0; i<count; i++) { | for(int i=0; i<count; i++) { |
| Item* item=chunk->rows[i].item; | Item* item=chunk->rows[i].item; |
| if((*func)(item, info)) | if(void *result=(*func)(item, info)) |
| return item; | return result; |
| } | } |
| chunk=chunk->rows[count].link; | chunk=chunk->rows[count].link; |
| } | } |