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: