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

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

E-mail: