|
|
| version 1.57.2.9, 2003/01/27 15:07:47 | version 1.57.2.23, 2003/02/17 11:29:53 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: Array & Array_iterator classes decls. | Parser: Array & Array_iterator 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 <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| Line 23 template<typename T> class Array: public | Line 23 template<typename T> class Array: public |
| friend class Array_iterator<T>; | friend class Array_iterator<T>; |
| protected: | |
| // default expand delta size | |
| int fdelta; | |
| /// elements[growing size] here | |
| T *felements; | |
| // allocated size | // allocated size |
| int fallocated; | int fallocated; |
| // array size | |
| int fused; | |
| public: | public: |
| typedef T element_type; | typedef T element_type; |
| Line 39 public: | Line 50 public: |
| Exception::undefined_source, | Exception::undefined_source, |
| "Array::Array(%d, %d) too small", initial, delta); | "Array::Array(%d, %d) too small", initial, delta); |
| felements=new T[fallocated]; | felements=static_cast<T*>(calloc(fallocated*sizeof(T))); |
| } | } |
| override ~Array() { | override ~Array() { |
| T *last=felements+fused; | T *last=felements+fused; |
| for(T *current=felements; current<last; current++) | for(T *current=felements; current<last; current++) |
| delete current; | current->~T(); // manually invoking destructors |
| delete felements; | free(felements); |
| } | } |
| /// how many items are in Array | /// how many items are in Array |
| Line 78 public: | Line 89 public: |
| limit=m; | limit=m; |
| } | } |
| int needed=limit-(fallocated-fused); | int delta=limit-(fallocated-fused); |
| if(needed>0) | if(delta>0) |
| expand(needed); | expand(delta); |
| memcpy(&felements[fused+=limit], &src.felements[offset], limit*sizeof(T)); | T* from=&src.felements[offset]; |
| T* to=&felements[fused]; | |
| T* from_end=from+limit; | |
| while(from<from_end) | |
| *to++=*from++; | |
| fused+=limit; | |
| return *this; | return *this; |
| } | } |
| /// get index-element | /// get index-element |
| T get(int index) const { | T& get(int index) const { |
| if(!(index>=0 && index<count())) { | if(!(index>=0 && index<count())) { |
| throw Exception(0, | throw Exception(0, |
| Exception::undefined_source, | Exception::undefined_source, |
| "Array::get(%d) out of range [0..%d]", index, count()-1); | "Array::get(%d) out of range [0..%d]", index, count()-1); |
| return 0; // never | return felements[0]; // never |
| } | } |
| return felements[index]; | return felements[index]; |
| } | } |
| T& operator [](int index) const { return get(index); } | |
| /// put index-element | /// put index-element |
| void put(int index, T element) { | void put(int index, T& element) { |
| if(!(index>=0 && index<size())) { | if(!(index>=0 && index<count())) { |
| throw Exception(0, | throw Exception(0, |
| Exception::undefined_source, | Exception::undefined_source, |
| "Array::put(%d) out of range [0..%d]", index, size()-1); | "Array::put(%d) out of range [0..%d]", index, count()-1); |
| return; // never | return; // never |
| } | } |
| felements[index]=element; | felements[index]=element; |
| Line 124 public: | Line 143 public: |
| if(callback(*current, info)) | if(callback(*current, info)) |
| return *current; | return *current; |
| return 0;//T(0); | return T(0); |
| } | } |
| protected: | protected: |
| // default expand delta size | |
| int fdelta; | |
| /// elements[growing size] here | |
| T *felements; | |
| // array size | |
| int fused; | |
| bool is_full() { | bool is_full() { |
| return fused == fallocated; | return fused == fallocated; |
| } | } |
| void expand(int delta) { | void expand(int delta) { |
| felements = (T *)realloc(felements, (fallocated+delta)*sizeof(T)); | |
| memset(&felements[fallocated], 0, delta*sizeof(T)); | |
| fallocated+=delta; | fallocated+=delta; |
| felements = (T *)pa_realloc(felements, fallocated*sizeof(T)); | |
| } | } |
| private: //disabled | private: //disabled |
| Line 153 private: //disabled | Line 164 private: //disabled |
| typedef smart_ptr<char> CharPtr; | typedef smart_ptr<char> CharPtr; |
| /** | |
| Pool mechanizm allows users not to free up allocated memory, | |
| leaving that problem to 'pools'. | |
| */ | |
| class Pool: public Array<CharPtr> { | class Pool: public Array<CharPtr> { |
| public: | public: |
| char *malloc(size_t size) { | char *malloc(size_t size) { |
| CharPtr result=CharPtr(new char[size]); | CharPtr result=CharPtr((char *)Array<CharPtr>::malloc(size)); |
| *this += result; | *this += result; |
| return result.get(); | return result.get(); |
| } | } |
| char *malloc(const char *buf, size_t size) { | char *copy(const char* buf, size_t size=0) { |
| if(!size) | |
| size=strlen(buf)+1; | |
| char *result=malloc(size); | char *result=malloc(size); |
| memcpy(result, buf, size); | memcpy(result, buf, size); |
| return result; | return result; |
| } | } |
| }; | }; |
| void *operator new(size_t size, Pool& pool) { | inline void *operator new[] (size_t size, Pool& pool) { |
| return pool.malloc(size); | return pool.malloc(size); |
| } | } |
| Line 192 public: | Line 210 public: |
| } | } |
| /// quickly extracts next Array element | /// quickly extracts next Array element |
| T next() { | T& next() { |
| return *(fcurrent++); | return *(fcurrent++); |
| } | } |