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