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

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.3     ! moko       11: #define IDENT_PA_VARRAY_H "$Id: pa_varray.h,v 1.2 2024/09/14 22:58:50 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){
1.3     ! moko       33:                if(index >= this->fallocated)
        !            34:                        this->resize(max(this->fallocated + this->fallocated/4, index+1));
1.2       moko       35:                this->felements[index]=element;
                     36:                if(index >= this->fused){
                     37:                        this->fused=index+1;
                     38:                }
                     39:        }
                     40: };
                     41: 
                     42: 
1.1       moko       43: class VArray: public VHashBase {
                     44: public: // value
                     45: 
                     46:        override const char* type() const { return VARRAY_TYPE; }
                     47:        override VStateless_class *get_class() { return array_class; }
                     48: 
                     49:        /// VArray: defined elements count
                     50:        override int as_int() const { return count(); }
                     51:        override double as_double() const { return count(); }
                     52:        override bool is_defined() const { return count()!=0; }
                     53:        override bool as_bool() const { return count()!=0; }
                     54:        override Value& as_expr_result() { return *new VInt(count()); }
                     55: 
                     56:        /// VArray: virtual hash
                     57:        override HashStringValue *get_hash() { return &hash(); }
                     58:        override HashStringValue* get_fields() { return &hash(); }
                     59:        override HashStringValue* get_fields_reference() { return &hash(); }
                     60: 
                     61:        /// VArray: json-string
                     62:        override const String* get_json_string(Json_options& options);
                     63: 
                     64:        /// VArray: (key)=value
                     65:        override Value* get_element(const String& aname) {
                     66:                // $element first
                     67:                if(Value* result=get(index(aname)))
                     68:                        return result;
                     69: 
                     70:                // $fields -- pseudo field to make 'hash' and 'array' more like 'table'
                     71:                if(SYMBOLS_EQ(aname,FIELDS_SYMBOL))
                     72:                        return this;
                     73: 
                     74: #if !defined(FEATURE_GET_ELEMENT4CALL) || !defined(OPTIMIZE_BYTECODE_GET_ELEMENT__SPECIAL)
                     75:                // $method, CLASS, CLASS_NAME
                     76:                if(Value* result=VStateless_object::get_element(aname))
                     77:                        return result;
                     78: #endif
                     79:                return NULL;
                     80:        }
                     81: 
                     82: #ifdef FEATURE_GET_ELEMENT4CALL
                     83:        override Value* get_element4call(const String& aname) {
                     84:                // $method first
                     85:                if(Value* result=VStateless_object::get_element(aname))
                     86:                        return result;
                     87: 
                     88:                // $element
                     89:                if(Value* result=get(index(aname)))
                     90:                        return result;
                     91: 
                     92:                return bark("%s method not found", &aname);
                     93:        }
                     94: #endif
                     95: 
                     96:        /// VArray: (key)=value
                     97:        override const VJunction* put_element(const String& aname, Value* avalue) {
                     98:                farray.fit(index(aname), avalue);
                     99:                clear_hash();
                    100:                return 0;
                    101:        }
                    102: 
                    103: public: // VHashBase
                    104: 
                    105:        override HashStringValue& hash();
                    106:        override void set_default(Value*) { }
                    107:        override Value* get_default() { return 0; }
                    108:        override void add(Value* avalue) { farray+=avalue; /* only json uses it, thus no need to clear_hash()*/ }
                    109: 
                    110: public: // usage
                    111: 
                    112:        VArray(size_t initial=0): farray(initial), fhash(0), fcount(0) {}
                    113:        ~VArray() { clear_hash(); }
                    114: 
                    115:        ArrayValue &array() { return farray; }
                    116:        size_t count() const;
                    117: 
                    118:        Value *get(size_t aindex){
                    119:                if(aindex<farray.count())
                    120:                        return farray.get(aindex);
                    121:                return NULL;
                    122:        }
                    123: 
                    124:        static size_t index(int aindex){
                    125:                if(aindex<0)
                    126:                        throw Exception("number.format", 0, "out of range (negative)");
                    127:                return aindex;
                    128:        }
                    129: 
                    130:        static size_t index(const String& aindex){
                    131:                int result=aindex.as_int();
                    132:                if(result<0)
                    133:                        throw Exception("number.format", &aindex, "out of range (negative)");
                    134:                return result;
                    135:        }
                    136: 
                    137:        static size_t index(const Value& aindex){ return index(aindex.as_int()); }
                    138: 
                    139:        void clear(size_t index){
                    140:                if(index < farray.count()){
                    141:                        farray.put(index, NULL);
                    142:                        clear_hash();
                    143:                }
                    144:        }
                    145: 
                    146:        bool contains(size_t index){
                    147:                return index < farray.count() && farray.get(index) != NULL;
                    148:        }
                    149: 
                    150:        void clear(){
                    151:                farray.clear();
                    152:                clear_hash();
                    153:        }
                    154: 
                    155:        void clear_hash() {
                    156: #ifdef USE_DESTRUCTORS
                    157:                if(fhash)
                    158:                        delete(fhash);
                    159: #endif
                    160:                fhash=0;
                    161:                fcount=0;
                    162:        }
                    163: 
                    164: private:
                    165: 
                    166:        ArrayValue farray;
                    167:        HashStringValue *fhash;
                    168:        mutable size_t fcount;
                    169: 
                    170: };
                    171: 
                    172: #endif

E-mail: