text: /*	see copyright notice in squirrel.h */
  #ifndef _SQARRAY_H_
  #define _SQARRAY_H_
  
  struct SQArray : public CHAINABLE_OBJ
  {
  private:
  	SQArray(SQSharedState *ss,SQInteger nsize) {
          _values.resize(nsize);
          INIT_CHAIN();
          ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
      }
      
  	~SQArray() {
  		REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
  	}
  public:
  	static SQArray *Create(SQSharedState *ss,SQInteger nInitialSize) {
  		SQArray *newarray = (SQArray *)SQ_MALLOC(sizeof(SQArray));
  		new (newarray) SQArray(ss,nInitialSize);
  		return newarray;
  	}
      
  #ifndef NO_GARBAGE_COLLECTOR
  	void Mark(SQCollectable **chain);
  	SQObjectType GetType() {return OT_ARRAY;}
  #endif
      
  	void Finalize() {
  		_values.resize(0);
  	}
      
  	bool Get(const SQInteger nidx,SQObjectPtr &val) const {
  		if (nidx>=0 && nidx<(SQInteger)_values.size()) {
  			SQObjectPtr &o = _values[nidx];
  			val = _realval(o);
  			return true;
  		}
          else {
              return false;
          }
  	}
      
  	bool Set(const SQInteger nidx,const SQObjectPtr &val) {
  		if(nidx>=0 && nidx<(SQInteger)_values.size()){
  			_values[nidx]=val;
  			return true;
  		}
  		else return false;
  	}
      
  	SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval) const {
  		SQUnsignedInteger idx=TranslateIndex(refpos);
  		while(idx<_values.size()){
  			//first found
  			outkey=(SQInteger)idx;
  			SQObjectPtr &o = _values[idx];
  			outval = _realval(o);
  			//return idx for the next iteration
  			return ++idx;
  		}
  		//nothing to iterate anymore
  		return -1;
  	}
      
  	SQArray *Clone() const {
          SQArray *anew = Create(_opt_ss(this),0);
          anew->_values.copy(_values);
          return anew;
      }
      
      SQInteger Size() const {
          return _values.size();
      }
      
  	void Resize(SQInteger size) {
  		SQObjectPtr _null;
  		Resize(size,_null);
  	}
      
  	void Resize(SQInteger size,SQObjectPtr &fill) {
          _values.resize(size,fill);
          ShrinkIfNeeded();
      }
      
  	void Reserve(SQInteger size) {
          _values.reserve(size);
      }
      
  	void Append(const SQObject &o) {
          _values.push_back(o);
      }
      
  	void Extend(const SQArray *a);
  	
      SQObjectPtr &Top() const {
          return _values.top();
      }
      
  	void Pop() {
          _values.pop_back();
          ShrinkIfNeeded();
      }
      
  	bool Insert(SQInteger idx,const SQObject &val) {
          if (idx < 0 || idx > (SQInteger)_values.size()) {
  			return false;
          }
  		_values.insert(idx,val);
  		return true;
  	}
      
  	void ShrinkIfNeeded() {
          if (_values.size() <= _values.capacity()>>2) { //shrink the array
  			_values.shrinktofit();
          }
  	}
      
  	bool Remove(SQInteger idx) {
          if (idx < 0 || idx >= (SQInteger)_values.size()) {
  			return false;
          }
  		_values.remove(idx);
  		ShrinkIfNeeded();
  		return true;
  	}
      
  	void Release() {
  		sq_delete(this,SQArray);
  	}
  
  	SQObjectPtrVec _values;
  };
  #endif //_SQARRAY_H_
  