Annotation of parser3/src/types/pa_varray.h, revision 1.2

1.1       moko        1: /** @file
                      2:        Parser: @b array parser type decl.
                      3: 
                      4:        Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com)
                      5:        Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
                      6: */
                      7: 
                      8: #ifndef PA_VARRAY_H
                      9: #define PA_VARRAY_H
                     10: 
1.2     ! moko       11: #define IDENT_PA_VARRAY_H "$Id: pa_varray.h,v 1.1 2024/09/10 19:15:48 moko Exp $"
1.1       moko       12: 
                     13: #include "classes.h"
                     14: #include "pa_value.h"
                     15: #include "pa_array.h"
                     16: #include "pa_vhash.h"
                     17: #include "pa_vint.h"
                     18: #include "pa_globals.h"
                     19: #include "pa_symbols.h"
                     20: 
                     21: // defines
                     22: 
1.2     ! moko       23: #define VARRAY_TYPE "array"
1.1       moko       24: 
                     25: extern Methoded* array_class;
                     26: 
1.2     ! moko       27: /// Sparse Array
        !            28: template<typename T> class SparseArray: public Array<T> {
        !            29: public:
        !            30:        inline SparseArray(size_t initial=0) : Array<T>(initial) {}
        !            31: 
        !            32:        void fit(size_t index, T element){
        !            33:                if(index >= this->fallocated){
        !            34:                        size_t new_allocated=this->fallocated>0 ? this->fallocated : 3;
        !            35:                        while(new_allocated <= index){
        !            36:                                new_allocated+=2 + new_allocated/32;
        !            37:                        }
        !            38:                        this->expand(new_allocated - this->fallocated);
        !            39:                }
        !            40:                this->felements[index]=element;
        !            41:                if(index >= this->fused){
        !            42:                        this->fused=index+1;
        !            43:                }
        !            44:        }
        !            45: };
        !            46: 
        !            47: 
1.1       moko       48: class VArray: public VHashBase {
                     49: public: // value
                     50: 
                     51:        override const char* type() const { return VARRAY_TYPE; }
                     52:        override VStateless_class *get_class() { return array_class; }
                     53: 
                     54:        /// VArray: defined elements count
                     55:        override int as_int() const { return count(); }
                     56:        override double as_double() const { return count(); }
                     57:        override bool is_defined() const { return count()!=0; }
                     58:        override bool as_bool() const { return count()!=0; }
                     59:        override Value& as_expr_result() { return *new VInt(count()); }
                     60: 
                     61:        /// VArray: virtual hash
                     62:        override HashStringValue *get_hash() { return &hash(); }
                     63:        override HashStringValue* get_fields() { return &hash(); }
                     64:        override HashStringValue* get_fields_reference() { return &hash(); }
                     65: 
                     66:        /// VArray: json-string
                     67:        override const String* get_json_string(Json_options& options);
                     68: 
                     69:        /// VArray: (key)=value
                     70:        override Value* get_element(const String& aname) {
                     71:                // $element first
                     72:                if(Value* result=get(index(aname)))
                     73:                        return result;
                     74: 
                     75:                // $fields -- pseudo field to make 'hash' and 'array' more like 'table'
                     76:                if(SYMBOLS_EQ(aname,FIELDS_SYMBOL))
                     77:                        return this;
                     78: 
                     79: #if !defined(FEATURE_GET_ELEMENT4CALL) || !defined(OPTIMIZE_BYTECODE_GET_ELEMENT__SPECIAL)
                     80:                // $method, CLASS, CLASS_NAME
                     81:                if(Value* result=VStateless_object::get_element(aname))
                     82:                        return result;
                     83: #endif
                     84:                return NULL;
                     85:        }
                     86: 
                     87: #ifdef FEATURE_GET_ELEMENT4CALL
                     88:        override Value* get_element4call(const String& aname) {
                     89:                // $method first
                     90:                if(Value* result=VStateless_object::get_element(aname))
                     91:                        return result;
                     92: 
                     93:                // $element
                     94:                if(Value* result=get(index(aname)))
                     95:                        return result;
                     96: 
                     97:                return bark("%s method not found", &aname);
                     98:        }
                     99: #endif
                    100: 
                    101:        /// VArray: (key)=value
                    102:        override const VJunction* put_element(const String& aname, Value* avalue) {
                    103:                farray.fit(index(aname), avalue);
                    104:                clear_hash();
                    105:                return 0;
                    106:        }
                    107: 
                    108: public: // VHashBase
                    109: 
                    110:        override HashStringValue& hash();
                    111:        override void set_default(Value*) { }
                    112:        override Value* get_default() { return 0; }
                    113:        override void add(Value* avalue) { farray+=avalue; /* only json uses it, thus no need to clear_hash()*/ }
                    114: 
                    115: public: // usage
                    116: 
                    117:        VArray(size_t initial=0): farray(initial), fhash(0), fcount(0) {}
                    118:        ~VArray() { clear_hash(); }
                    119: 
                    120:        ArrayValue &array() { return farray; }
                    121:        size_t count() const;
                    122: 
                    123:        Value *get(size_t aindex){
                    124:                if(aindex<farray.count())
                    125:                        return farray.get(aindex);
                    126:                return NULL;
                    127:        }
                    128: 
                    129:        static size_t index(int aindex){
                    130:                if(aindex<0)
                    131:                        throw Exception("number.format", 0, "out of range (negative)");
                    132:                return aindex;
                    133:        }
                    134: 
                    135:        static size_t index(const String& aindex){
                    136:                int result=aindex.as_int();
                    137:                if(result<0)
                    138:                        throw Exception("number.format", &aindex, "out of range (negative)");
                    139:                return result;
                    140:        }
                    141: 
                    142:        static size_t index(const Value& aindex){ return index(aindex.as_int()); }
                    143: 
                    144:        void clear(size_t index){
                    145:                if(index < farray.count()){
                    146:                        farray.put(index, NULL);
                    147:                        clear_hash();
                    148:                }
                    149:        }
                    150: 
                    151:        bool contains(size_t index){
                    152:                return index < farray.count() && farray.get(index) != NULL;
                    153:        }
                    154: 
                    155:        void clear(){
                    156:                farray.clear();
                    157:                clear_hash();
                    158:        }
                    159: 
                    160:        void clear_hash() {
                    161: #ifdef USE_DESTRUCTORS
                    162:                if(fhash)
                    163:                        delete(fhash);
                    164: #endif
                    165:                fhash=0;
                    166:                fcount=0;
                    167:        }
                    168: 
                    169: private:
                    170: 
                    171:        ArrayValue farray;
                    172:        HashStringValue *fhash;
                    173:        mutable size_t fcount;
                    174: 
                    175: };
                    176: 
                    177: #endif

E-mail: