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

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

E-mail: