00001 00002 #ifndef RCARRAY_H 00003 #define RCARRAY_H 00004 00029 #include "GrowableArray.h" 00030 #include "RCObject.h" 00031 #include "RCPtr.h" 00032 #include "RCBase.h" 00033 00155 template <class T> 00156 class RCArray : public RCBase<T> 00157 { 00158 00159 protected: 00160 class SharedData : public RCObject 00161 { 00162 public: 00163 GrowableArray<T> data; 00164 00165 SharedData() {}; 00166 SharedData(const GrowableArray<T> &v ) { copy( v ); } 00167 SharedData( size_t initialSize ) : data( initialSize ) {} 00168 SharedData(const SharedData& rhs) { copy( rhs.data ); } 00169 ~SharedData() {} 00170 size_t getRefCnt() { return refCnt(); } 00171 00172 private: 00173 void copy(const GrowableArray<T> &v ) 00174 { 00175 size_t len = v.length(); 00176 for (size_t i = 0; i < len; i++) { 00177 data.append( v[i] ); 00178 } 00179 } // copy 00180 }; // class SharedData 00181 00182 RCPtr<SharedData> value; 00183 00184 void init(T intialVal ); 00185 00186 RCArray(size_t initialSize); 00187 RCArray(size_t initialSize, T initVal ); 00188 00189 T read(const int i) const; 00190 void write(const int i, const T v); 00191 00192 size_t length() const; 00193 size_t getRefCnt(); 00194 00195 public: 00196 RCArray(); 00197 00198 ValRef operator[](const int ix) throw(std::out_of_range); 00199 T operator[](const int ix) const; 00200 00201 ValRef operator[](const size_t ix) throw(std::out_of_range); 00202 T operator[](const size_t ix) const; 00203 00204 void append(T val); 00205 }; // RCArray 00206 00207 00211 template <class T> 00212 inline 00213 void RCArray<T>::init( T initialVal ) 00214 { 00215 size_t len = value->data.length(); 00216 for (size_t i = 0; i < len; i++) { 00217 value->data[i] = initialVal; 00218 } 00219 } 00220 00224 template <class T> 00225 inline 00226 RCArray<T>::RCArray() : value( new SharedData() ) {} 00227 00228 00233 template <class T> 00234 inline 00235 RCArray<T>::RCArray( size_t initialSize ) : 00236 value( new SharedData(initialSize) ) {} 00237 00238 00243 template <class T> 00244 inline 00245 RCArray<T>::RCArray( size_t initialSize, T initialVal ) : 00246 value( new SharedData(initialSize) ) 00247 { 00248 init( initialVal ); 00249 } 00250 00251 00256 template <class T> 00257 inline 00258 void RCArray<T>::append( T val ) 00259 { 00260 value->data.append( val ); 00261 } 00262 00266 template <class T> 00267 inline 00268 size_t RCArray<T>::length() const 00269 { 00270 return value->data.length(); 00271 } 00272 00273 00277 template <class T> 00278 inline 00279 size_t RCArray<T>::getRefCnt() 00280 { 00281 return value->getRefCnt(); 00282 } 00283 00284 00285 00286 template <class T> 00287 inline 00288 T RCArray<T>::operator[](const int ix) const 00289 { 00290 return value->data[ix]; 00291 } 00292 00293 00294 00295 template <class T> 00296 inline 00297 RCArray<T>::ValRef RCArray<T>::operator[](const int ix) 00298 throw(std::out_of_range) 00299 { 00300 if (ix < 0 || ix >= value->data.length()) { 00301 const char *errMsg = "operator[] - index out of bounds"; 00302 throw std::out_of_range( errMsg ); 00303 } 00304 return ValRef( *this, ix ); 00305 } 00306 00307 00308 template <class T> 00309 inline 00310 T RCArray<T>::operator[](const size_t ix) const 00311 { 00312 return value->data[ix]; 00313 } 00314 00315 template <class T> 00316 inline 00317 RCArray<T>::ValRef RCArray<T>::operator[](const size_t ix) 00318 throw(std::out_of_range) 00319 { 00320 if (ix >= value->data.length()) { 00321 const char *errMsg = "operator[] - index out of bounds"; 00322 throw std::out_of_range( errMsg ); 00323 } 00324 return ValRef( *this, ix ); 00325 } 00326 00327 00331 template <class T> 00332 inline 00333 T RCArray<T>::read(const int i) const 00334 { 00335 return value->data[i]; 00336 } 00337 00338 00342 template <class T> 00343 inline 00344 void RCArray<T>::write(const int i, const T v) 00345 { 00346 if (value->isShared()) { 00347 value = new SharedData( value->data ); 00348 } 00349 value->data[i] = v; 00350 } 00351 00352 #endif