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

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

E-mail: