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