0001
0002 #ifndef _PSARRAY_H_
0003 #define _PSARRAY_H_
0004
0005 struct PSArray : public CHAINABLE_OBJ
0006 {
0007 private:
0008 PSArray(PSSharedState *ss,PSInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
0009 ~PSArray()
0010 {
0011 REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
0012 }
0013 public:
0014 static PSArray* Create(PSSharedState *ss,PSInteger nInitialSize){
0015 PSArray *newarray=(PSArray*)PS_MALLOC(sizeof(PSArray));
0016 new (newarray) PSArray(ss,nInitialSize);
0017 return newarray;
0018 }
0019 #ifndef NO_GARBAGE_COLLECTOR
0020 void Mark(PSCollectable **chain);
0021 PSObjectType GetType() {return OT_ARRAY;}
0022 #endif
0023 void Finalize(){
0024 _values.resize(0);
0025 }
0026 bool Get(const PSInteger nidx,PSObjectPtr &val)
0027 {
0028 if(nidx>=0 && nidx<(PSInteger)_values.size()){
0029 PSObjectPtr &o = _values[nidx];
0030 val = _realval(o);
0031 return true;
0032 }
0033 else return false;
0034 }
0035 bool Set(const PSInteger nidx,const PSObjectPtr &val)
0036 {
0037 if(nidx>=0 && nidx<(PSInteger)_values.size()){
0038 _values[nidx]=val;
0039 return true;
0040 }
0041 else return false;
0042 }
0043 PSInteger Next(const PSObjectPtr &refpos,PSObjectPtr &outkey,PSObjectPtr &outval)
0044 {
0045 PSUnsignedInteger idx=TranslateIndex(refpos);
0046 while(idx<_values.size()){
0047
0048 outkey=(PSInteger)idx;
0049 PSObjectPtr &o = _values[idx];
0050 outval = _realval(o);
0051
0052 return ++idx;
0053 }
0054
0055 return -1;
0056 }
0057 PSArray *Clone(){PSArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; }
0058 PSInteger Size() const {return _values.size();}
0059 void Resize(PSInteger size)
0060 {
0061 PSObjectPtr _null;
0062 Resize(size,_null);
0063 }
0064 void Resize(PSInteger size,PSObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); }
0065 void Reserve(PSInteger size) { _values.reserve(size); }
0066 void Append(const PSObject &o){_values.push_back(o);}
0067 void Extend(const PSArray *a);
0068 PSObjectPtr &Top(){return _values.top();}
0069 void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
0070 bool Insert(PSInteger idx,const PSObject &val){
0071 if(idx < 0 || idx > (PSInteger)_values.size())
0072 return false;
0073 _values.insert(idx,val);
0074 return true;
0075 }
0076 void ShrinkIfNeeded() {
0077 if(_values.size() <= _values.capacity()>>2)
0078 _values.shrinktofit();
0079 }
0080 bool Remove(PSInteger idx){
0081 if(idx < 0 || idx >= (PSInteger)_values.size())
0082 return false;
0083 _values.remove(idx);
0084 ShrinkIfNeeded();
0085 return true;
0086 }
0087 void Release()
0088 {
0089 ps_delete(this,PSArray);
0090 }
0091
0092 PSObjectPtrVec _values;
0093 };
0094 #endif