00001
00015 #ifndef SIMPLEARRAY_H
00016 #define SIMPLEARRAY_H
00017
00018 #include <string>
00019 #include <cassert>
00020 #include <iostream>
00021 #include <Vector.H>
00022 #include <arglst.H>
00023 #include <Exception.H>
00024
00025 using namespace std;
00026
00027 namespace xchen
00028 {
00029 template<typename T, int dims>
00030 class SimpleArrayIterator;
00031
00033 template<typename T, int dims>
00034 class SimpleArray
00035 {
00036 typedef SimpleArray<T, dims-1> SubArrayType;
00037 typedef SimpleArray<T, dims+1> SuperArrayType;
00038 friend class SuperArrayType;
00039 friend class SimpleArrayIterator<T, dims+1>;
00040 template <typename t1, typename t2> friend class vector;
00041
00042 vector< SubArrayType > data;
00043 int idx_bgn;
00044
00045 public:
00046 typedef SimpleArrayIterator<T,dims> iterator;
00047
00048 SimpleArray(int sz, ...);
00049 SimpleArray(int* sz);
00050 ListAssignmentCheckSzRt<T, iterator> operator=(T const& x);
00051
00052 void SetIndexStartAt(int arg1, ...) { int bgn[dims]; get_reverse_ints_va(bgn,dims); set_idx_bgn(bgn); }
00053 int GetIndexStart() const { return idx_bgn; }
00054 int GetSize() const { return data.size(); }
00055
00056 SubArrayType& operator[](int i) { throwError(i); return data[i-idx_bgn]; }
00057 T& operator[](Vector<int, dims>const& i) { throwError(i[dims-1]); return (*this)[i[dims-1]][Vector<int, dims-1>(i)]; }
00058 iterator Iterate() { return iterator(data); }
00059 private:
00060 SimpleArray() : idx_bgn(0) { }
00061 void throwError(int idx) const;
00062
00063 void set_idx_bgn(int bgn[dims])
00064 {
00065 idx_bgn = bgn[dims-1];
00066 for(typename vector< SubArrayType >::iterator itr = data.begin(); itr != data.end(); ++itr)
00067 {
00068 itr->set_idx_bgn(bgn);
00069 }
00070 }
00071 void resize(int sz[dims])
00072 {
00073 data.resize(sz[dims-1]);
00074 for(typename vector< SubArrayType >::iterator itr = data.begin(); itr != data.end(); ++itr)
00075 {
00076 itr->resize(sz);
00077 }
00078 }
00079 int getTotalSz() { return data.size() * data.front().getTotalSz(); }
00080
00081 friend ostream& operator<< <>(ostream& os, const SimpleArray&);
00082 };
00083
00085 template<typename T>
00086 class SimpleArray<T,1>
00087 {
00088 friend class SimpleArray<T, 2>;
00089 friend class SimpleArrayIterator<T, 2>;
00090 template <typename t1, typename t2> friend class vector;
00091
00092 vector<T> data;
00093 int idx_bgn;
00094
00095 public:
00096 SimpleArray(int sz) : idx_bgn(0) { data.resize(sz); }
00097
00098 ListAssignmentCheckSzRt<T, SimpleArrayIterator<T,1> > operator=(T const& x);
00099
00100 void SetIndexStartAt(int bgn) { idx_bgn = bgn; }
00101 int GetIndexStart() const { return idx_bgn; }
00102 int GetSize() const { return data.size(); }
00103
00104 T& operator[](int i) { throwError(i); return data[i-idx_bgn]; }
00105 T& operator[](Vector<int, 1>const& i) { throwError(i[0]); return data[i[0]-idx_bgn]; }
00106
00107 private:
00108 SimpleArray() : idx_bgn(0) { }
00109 void throwError(int idx) const;
00110 void set_idx_bgn(int* bgn) { idx_bgn = bgn[0]; }
00111 void resize(int* sz) { data.resize(sz[0]); }
00112 int getTotalSz() { return data.size(); }
00113
00114 friend ostream& operator<< <>(ostream& os, const SimpleArray&);
00115 };
00116
00117
00119 template<typename T, int dims>
00120 class SimpleArrayIterator
00121 {
00122 friend class SimpleArray<T,dims>;
00123 friend class SimpleArrayIterator<T,dims+1>;
00124
00125 typedef SimpleArray<T, dims-1> SubArrayType;
00126 typedef SimpleArrayIterator<T,dims-1> SubIterator;
00127
00128 vector<SubArrayType>* data;
00129 bool pastend;
00130 typename vector<SubArrayType>::iterator itr;
00131
00132 SubIterator rec_itr;
00133
00134 SimpleArrayIterator(vector<SubArrayType>& d) : data(&d), itr(d.begin()), rec_itr(d.front().data), pastend(false) { SubIterator( itr->data ); }
00135
00136 public:
00137 SimpleArrayIterator& operator++()
00138 {
00139 if((++rec_itr).PastEnd())
00140 {
00141 if( ++itr == data->end() )
00142 pastend = true;
00143 else
00144 rec_itr = SubIterator( itr->data );
00145 }
00146 return *this;
00147 }
00148 bool PastEnd() { return pastend; }
00149 T& operator*() { return *rec_itr; }
00150 };
00151
00152
00154 template<typename T>
00155 class SimpleArrayIterator<T,1>
00156 {
00157 friend class SimpleArrayIterator<T,2>;
00158
00159 template<typename t, int dims> friend class SimpleArray;
00160
00161 vector<T>* data;
00162 bool pastend;
00163 typename vector<T>::iterator itr;
00164
00165 SimpleArrayIterator(vector<T>& d) : data(&d), itr(d.begin()), pastend(false) { }
00166
00167 public:
00168 SimpleArrayIterator& operator++()
00169 {
00170 if( ++itr == data->end() )
00171 pastend = true;
00172 return *this;
00173 }
00174 bool PastEnd() { return pastend; }
00175 T& operator*() { return *itr; }
00176 };
00177
00178
00179 template<typename T, int dims>
00180 inline SimpleArray<T,dims>:: SimpleArray(int arg1, ...) : idx_bgn(0)
00181 {
00182 int sz[dims];
00183 get_reverse_ints_va(sz,dims);
00184 resize(sz);
00185 }
00186
00187 template<typename T, int dims>
00188 inline SimpleArray<T,dims>:: SimpleArray(int* sz) : idx_bgn(0)
00189 {
00190 resize(sz);
00191 }
00192
00193 template<typename T, int dims>
00194 inline ListAssignmentCheckSzRt<T, SimpleArrayIterator<T,dims> > SimpleArray<T,dims> :: operator=(T const& x)
00195 {
00196 SimpleArrayIterator<T,dims> itr(data);
00197 *itr = x;
00198 return ListAssignmentCheckSzRt<T, SimpleArrayIterator<T,dims> >(++itr, getTotalSz()-1);
00199 }
00200
00201 template<typename T>
00202 inline ListAssignmentCheckSzRt<T, SimpleArrayIterator<T,1> > SimpleArray<T,1> :: operator=(T const& x)
00203 {
00204 SimpleArrayIterator<T,1> itr(data);
00205 *itr = x;
00206 return ListAssignmentCheckSzRt<T, SimpleArrayIterator<T,1> >(++itr, getTotalSz()-1);
00207 }
00208
00209
00210 template<typename T, int dims>
00211 inline void SimpleArray<T,dims> :: throwError(int idx) const
00212 {
00213 int sz = data.size();
00214
00215 if(idx < idx_bgn)
00216 {
00217 throw ArrayError(Error::UNDER_FLOW, idx);
00218 }
00219
00220 else if( idx >= idx_bgn + sz )
00221 {
00222 throw ArrayError(Error::OVER_FLOW, idx);
00223 }
00224 return;
00225 }
00226
00227 template<typename T>
00228 inline void SimpleArray<T,1> :: throwError(int idx) const
00229 {
00230 if(idx < idx_bgn)
00231 {
00232 throw ArrayError(Error::UNDER_FLOW, idx);
00233 }
00234 else if(idx >= idx_bgn + data.size())
00235 {
00236 throw ArrayError(Error::OVER_FLOW, idx);
00237 }
00238 }
00239
00240
00241 template<typename T, int dims>
00242 ostream& operator<<(ostream& os, SimpleArray<T, dims> const & ar)
00243 {
00244 copy(ar.data.begin(), ar.data.end(), ostream_iterator< SimpleArray<T, dims-1> >(os, "\n"));
00245 return os;
00246 }
00247
00248
00249 template<typename T>
00250 ostream& operator<<(ostream& os, SimpleArray<T, 1> const & ar)
00251 {
00252 copy(ar.data.begin(), ar.data.end(), ostream_iterator<T>(os, " "));
00253 return os;
00254 }
00255
00256
00257 }
00258
00259
00260 #endif