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: