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