00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __SEAL_ARRAY_1D_H__
00030 #define __SEAL_ARRAY_1D_H__
00031
00032 #include "collection.h"
00033 #include "randaccess.h"
00034 #include "dataptr.h"
00035 #include "exception.h"
00036
00037 namespace seal
00038 {
00039
00043 template <typename T>
00044 class Array1D : public Collection<T>, public RandomAccess<T>
00045 {
00046 public:
00047
00050 class Iterator : public AbstractIterator<T>
00051 {
00052
00053 friend class Array1D<T>;
00054
00055 public:
00058 Iterator(void) : AbstractIterator<T>(), _iterIndex(-1), _size(0) {}
00059
00062 virtual T next(void) throw (OutOfBoundsException);
00063
00066 virtual bool hasNext(void);
00067
00070 virtual void reset(void);
00071
00072 private:
00073
00076 Iterator(unsigned int size, T *dataPtr)
00077 : AbstractIterator<T>(), _iterIndex(-1), _size(size), _dataPtr(dataPtr)
00078 {}
00079
00080 int _iterIndex;
00081 unsigned int _size;
00082
00083 T *_dataPtr;
00084 };
00085
00086 public:
00090 Array1D(void);
00091
00095 Array1D(unsigned int length);
00096
00099 Array1D(const Array1D<T> &v);
00100
00103 virtual ~Array1D();
00104
00107 virtual unsigned int size(void) const { return *_sizePtr; }
00108
00113 virtual AbstractIterator<T>* iteratorPtr(void) const
00114 { return (new typename Array1D::Iterator(*_sizePtr, _dataPtr->data)); }
00115
00119 typename Array1D<T>::Iterator iterator(void) const
00120 { return typename Array1D::Iterator(*_sizePtr, _dataPtr->data); }
00121
00125 virtual void purge(void)
00126 {
00127 delete [] _dataPtr->data;
00128 _dataPtr->data = NULL;
00129 *_sizePtr = 0;
00130 }
00131
00134 virtual bool isEmpty(void) const
00135 {
00136 if (*_sizePtr == 0)
00137 return true;
00138 else
00139 return false;
00140 }
00141
00144 inline virtual const T& operator[](int index) const throw (OutOfRangeException<int>);
00145
00148 inline virtual T& operator[](int index) throw (OutOfRangeException<int>);
00149
00153 void operator=(const Array1D<T> &v);
00154
00157 virtual T& first(void) throw (EmptyCollectionException);
00158
00161 virtual const T& first(void) const throw (EmptyCollectionException);
00162
00165 virtual T& last(void) throw (EmptyCollectionException);
00166
00169 virtual const T& last(void) const throw (EmptyCollectionException);
00170
00171 private:
00172 unsigned int *_refCountPtr;
00173 unsigned int *_sizePtr;
00174 DataPtr<T> *_dataPtr;
00175 };
00176
00177
00178
00182
00183 template <typename T>
00184 Array1D<T>::Array1D(void)
00185 : Collection<T>(), RandomAccess<T>()
00186 {
00187 _sizePtr = new unsigned int; *_sizePtr = 0;
00188 _refCountPtr = new unsigned int; *_refCountPtr = 1;
00189
00190 _dataPtr = new DataPtr<T>();
00191 _dataPtr->data = new T [0];
00192 }
00193
00194 template <typename T>
00195 Array1D<T>::Array1D(unsigned int length)
00196 : Collection<T>(), RandomAccess<T>()
00197 {
00198 _sizePtr = new unsigned int; *_sizePtr = length;
00199 _refCountPtr = new unsigned int; *_refCountPtr = 1;
00200
00201 _dataPtr = new DataPtr<T>();
00202 _dataPtr->data = new T [length];
00203 }
00204
00205 template <typename T>
00206 Array1D<T>::Array1D(const Array1D<T> &v)
00207 : Collection<T>(), RandomAccess<T>(),
00208 _refCountPtr(v._refCountPtr),
00209 _sizePtr(v._sizePtr),
00210 _dataPtr(v._dataPtr)
00211 {
00212 (*_refCountPtr)++;
00213 }
00214
00215 template <typename T>
00216 Array1D<T>::~Array1D()
00217 {
00218 if (*_refCountPtr <= 1)
00219 {
00220 delete _sizePtr;
00221 delete _refCountPtr;
00222
00223 delete [] _dataPtr->data;
00224 delete _dataPtr;
00225 }
00226 else
00227 (*_refCountPtr)--;
00228 }
00229
00230 template <typename T>
00231 const T& Array1D<T>::operator[](int index) const throw (OutOfRangeException<int>)
00232 {
00233 if (*_sizePtr == 0)
00234 throw OutOfRangeException<int>(-1, -1, 0);
00235 else if (index < 0 || index >= *_sizePtr)
00236 throw OutOfRangeException<int>(0, *_sizePtr-1, index);
00237 else
00238 return _dataPtr->data[index];
00239 }
00240
00241 template <typename T>
00242 T& Array1D<T>::operator[](int index) throw (OutOfRangeException<int>)
00243 {
00244 if (*_sizePtr == 0)
00245 throw OutOfRangeException<int>(-1, -1, 0);
00246 else if (index < 0 || index >= *_sizePtr)
00247 throw OutOfRangeException<int>(0, *_sizePtr-1, index);
00248 else
00249 return _dataPtr->data[index];
00250 }
00251
00252 template <typename T>
00253 void Array1D<T>::operator=(const Array1D<T> &v)
00254 {
00255 if (_refCountPtr == v._refCountPtr)
00256 return;
00257
00258 if (*_refCountPtr > 1)
00259 {
00260 (*_refCountPtr)--;
00261
00262 _refCountPtr = v._refCountPtr;
00263 _sizePtr = v._sizePtr;
00264 _dataPtr = v._dataPtr;
00265
00266 (*_refCountPtr)++;
00267 }
00268 else
00269 {
00270 delete _refCountPtr;
00271 delete _sizePtr;
00272 delete [] _dataPtr;
00273
00274 _refCountPtr = v._refCountPtr;
00275 _sizePtr = v._sizePtr;
00276 _dataPtr = v._dataPtr;
00277
00278 (*_refCountPtr)++;
00279 }
00280 }
00281
00282 template <typename T>
00283 T& Array1D<T>::first(void) throw (EmptyCollectionException)
00284 {
00285 if (*_sizePtr == 0)
00286 throw EmptyCollectionException();
00287
00288 return _dataPtr->data[0];
00289 }
00290
00291 template <typename T>
00292 const T& Array1D<T>::first(void) const throw (EmptyCollectionException)
00293 {
00294 if (*_sizePtr == 0)
00295 throw EmptyCollectionException();
00296
00297 return _dataPtr->data[0];
00298 }
00299
00300 template <typename T>
00301 T& Array1D<T>::last(void) throw (EmptyCollectionException)
00302 {
00303 if (*_sizePtr == 0)
00304 throw EmptyCollectionException();
00305
00306 return _dataPtr->data[*_sizePtr-1];
00307 }
00308
00309 template <typename T>
00310 const T& Array1D<T>::last(void) const throw (EmptyCollectionException)
00311 {
00312 if (*_sizePtr == 0)
00313 throw EmptyCollectionException();
00314
00315 return _dataPtr->data[*_sizePtr-1];
00316 }
00317
00321
00322 template <typename T>
00323 bool Array1D<T>::Iterator::hasNext()
00324 {
00325 if (_size > 0 && _iterIndex < static_cast<int>(_size-1) && _iterIndex >= -1)
00326 return true;
00327 else
00328 return false;
00329 }
00330
00331 template <typename T>
00332 T Array1D<T>::Iterator::next() throw (OutOfBoundsException)
00333 {
00334 if (_size > 0 && _iterIndex < static_cast<int>(_size-1) && _iterIndex >= -1)
00335 {
00336 _iterIndex++;
00337 return _dataPtr[_iterIndex];
00338 }
00339 else
00340 throw OutOfBoundsException();
00341 }
00342
00343 template <typename T>
00344 void Array1D<T>::Iterator::reset()
00345 {
00346 _iterIndex = -1;
00347 }
00348
00349 }
00350
00351 #endif // __SEAL_ARRAY_1D_H__
00352