Annotation of parser3/src/include/pa_array.h, revision 1.57.2.4

1.24      paf         1: /** @file
1.57.2.2  paf         2:        Parser: Array & Array_iterator classes decls.
1.26      paf         3: 
1.57      paf         4:        Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com)
1.53      paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       paf         6: */
                      7: 
1.24      paf         8: #ifndef PA_ARRAY_H
                      9: #define PA_ARRAY_H
1.54      paf        10: 
1.57.2.4! paf        11: static const char* IDENT_ARRAY_Y="$Date: 2003/01/23 15:38:05 $";
1.24      paf        12: 
                     13: #include "pa_pool.h"
1.57.2.2  paf        14: //#include "pa_types.h"
1.57.2.3  paf        15: #include "pa_exception.h"
1.24      paf        16: 
1.57.2.3  paf        17: template<typename T> class Array_iterator;
1.42      parser     18: 
1.25      paf        19: /**    
1.57.2.2  paf        20:        Simple Array.
1.24      paf        21: 
1.1       paf        22: */
1.57.2.2  paf        23: template<typename T> class Array: public PA_Object {
1.1       paf        24: 
1.57.2.2  paf        25:        friend class Array_iterator;
                     26: 
                     27:        // allocated size
                     28:        int fallocated;
1.1       paf        29: 
1.57.2.2  paf        30: public:
                     31:        typedef T element_type;
1.7       paf        32: 
1.57.2.3  paf        33:        Array(int initial=3, int delta=1):
1.57.2.2  paf        34:                fallocated(initial?initial:3),
                     35:                fdelta(delta),
                     36:                fused(0)
                     37:        {
1.57.2.3  paf        38:                if(fallocated<=0 || fdelta<1)
1.57.2.4! paf        39:                        throw Exception(0, 
        !            40:                                Exception::undefined_source,
1.57.2.2  paf        41:                                "Array::Array(%d, %d) too small", initial, delta);
1.24      paf        42: 
1.57.2.2  paf        43:                felements=new T[fallocated];
                     44:        }
                     45:        override ~Array() {
1.57.2.3  paf        46:                T *last=felements+fused;
                     47:                for(T *current=felements; current<last; current++)
                     48:                        delete current;
                     49: 
1.57.2.2  paf        50:                delete felements;
                     51:        }
1.24      paf        52: 
1.57.2.2  paf        53:        /// how many items are in Array
                     54:        int count() const { return fused; }
                     55:        /// append to array
                     56:        Array& operator += (T src) {
                     57:                if(is_full())
                     58:                        expand(fdelta);
1.24      paf        59: 
1.57.2.2  paf        60:                felements[fused++]=src;
1.37      paf        61: 
1.57.2.2  paf        62:                return *this;
1.34      paf        63:        }
1.35      paf        64: 
1.57.2.2  paf        65:        /// append other Array portion to this one. starting from offset
                     66:        Array& append(const Array& src, int offset=0, int limit=0) {
                     67:                if(!(offset>=0 && offset<src.count())) {
1.57.2.4! paf        68:                        throw Exception(0, 
        !            69:                                Exception::undefined_source,
1.57.2.2  paf        70:                                "Array::append(offset=%d) out of range [0..%d]", offset, src.count()-1);
                     71:                        //return 0; // never
                     72:                }
                     73:                // fix limit
                     74:                {
                     75:                        int m=src.count()-offset;
                     76:                        if(!m || limit<0)
                     77:                                return *this;
                     78:                        if(!limit || limit>m)
                     79:                                limit=m;
                     80:                }
1.29      paf        81: 
1.57.2.2  paf        82:                int needed=limit-(fallocated-fused);
                     83:                if(needed>0)
                     84:                        expand(needed);
                     85: 
                     86:                memcpy(&felements[fused+=limit], &src.felements[offset], limit*sizeof(T));
1.57.2.4! paf        87:                return *this;
1.57.2.2  paf        88:        }
1.49      paf        89: 
1.57.2.2  paf        90:        /// get index-element
                     91:        T get(int index) const {
1.57.2.4! paf        92:                if(!(index>=0 && index<count())) {
        !            93:                        throw Exception(0, 
        !            94:                                Exception::undefined_source,
1.57.2.2  paf        95:                                "Array::get(%d) out of range [0..%d]", index, count()-1);
                     96:                        return 0; // never
                     97:                }
1.29      paf        98: 
1.57.2.2  paf        99:                return felements[index];
                    100:        }
1.32      paf       101: 
1.57.2.2  paf       102:        /// put index-element
                    103:        void put(int index, T element) {
                    104:                if(!(index>=0 && index<size())) {
1.57.2.4! paf       105:                        throw Exception(0, 
        !           106:                                Exception::undefined_source, 
1.57.2.2  paf       107:                                "Array::put(%d) out of range [0..%d]", index, size()-1);
                    108:                        return; // never
                    109:                }
                    110:                felements[index]=element;
                    111:        }
1.1       paf       112: 
1.7       paf       113: 
1.57.2.2  paf       114:        /// iterate over all elements
                    115:        template<typename I> void for_each(void callback(T, I), I info) const {
                    116:                T *last=felements+fused;
                    117:                for(T *current=felements; current<last; current++)
                    118:                        callback(*current, info);
                    119:        }
1.1       paf       120: 
1.57.2.2  paf       121:        /// iterate over all elements until condition becomes true, return that element
                    122:        template<typename I> T *first_that(bool callback(T, I), I info) const {
                    123:                T *last=felements+fused;
                    124:                for(T *current=felements; current<last; current++)
                    125:                        if(callback(*current, info))
                    126:                                return *current;
1.7       paf       127: 
1.57.2.2  paf       128:                return 0;
                    129:        }
1.1       paf       130: 
1.57.2.3  paf       131: protected:
                    132: 
                    133:        // default expand delta size
                    134:        int fdelta;
                    135: 
                    136:        /// elements[growing size] here
                    137:        T *felements;
                    138: 
                    139:        // array size
                    140:        int fused;
1.1       paf       141: 
1.57.2.2  paf       142:        bool is_full() {
                    143:                return fused == fallocated;
                    144:        }
                    145:        void expand(int delta) {
                    146:                fallocated+=delta;
                    147:                felements = (T *)pa_realloc(felements, fallocated*sizeof(T));
1.1       paf       148:        }
1.2       paf       149: 
1.1       paf       150: private: //disabled
                    151: 
1.12      paf       152:        Array& operator = (const Array&) { return *this; }
1.42      parser    153: };
                    154: 
                    155: /// handy array iterator
1.57.2.2  paf       156: template<typename T> class Array_iterator {
                    157: 
                    158:        const Array<T>& farray;
                    159:        T *fcurrent;
                    160:        T *flast;
                    161: 
1.42      parser    162: public:
                    163: 
1.57.2.2  paf       164:        Array_iterator(const Array<T>& aarray) : farray(aarray) {
                    165:                fcurrent(farray.felements);
                    166:                flast=farray+farray.count();
1.42      parser    167:        }
                    168: 
                    169:        /// there are still elements
                    170:        bool has_next() {
1.57.2.2  paf       171:                return fcurrent<flast;
1.42      parser    172:        }
                    173: 
1.57.2.2  paf       174:        /// quickly extracts next Array element
                    175:        T next() {
                    176:                return *(furrent++);
1.42      parser    177:        }
                    178: 
1.1       paf       179: };
                    180: 
                    181: #endif

E-mail: