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: