00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef REGION2D_H
00013 #define REGION2D_H
00014
00015 #include "index.h"
00016
00017
00018
00019
00020
00021 template <class TNT_Array2D, class T > class const_Region2D;
00022
00023 template <class TNT_Array2D >
00024 class Region2D
00025 {
00026 protected:
00027
00028 TNT_Array2D & A_;
00029 Subscript offset_[2];
00030 Subscript dim_[2];
00031
00032 public:
00033 typedef typename TNT_Array2D::value_type T;
00034
00035 typedef Subscript size_type;
00036 typedef T value_type;
00037 typedef T element_type;
00038 typedef T* pointer;
00039 typedef T* iterator;
00040 typedef T& reference;
00041 typedef const T* const_iterator;
00042 typedef const T& const_reference;
00043
00044 TNT_Array2D & array() { return A_; }
00045 const TNT_Array2D & array() const { return A_; }
00046 Subscript lbound() const { return A_.lbound(); }
00047 Subscript num_rows() const { return dim_[0]; }
00048 Subscript num_cols() const { return dim_[1]; }
00049 Subscript offset(Subscript i) const
00050 {
00051 #ifdef TNT_BOUNDS_CHECK
00052 assert( A_.lbound() <= i);
00053 assert( i<= dim_[0] + A_.lbound()-1);
00054 #endif
00055 return offset_[i-A_.lbound()];
00056 }
00057
00058 Subscript dim(Subscript i) const
00059 {
00060 #ifdef TNT_BOUNDS_CHECK
00061 assert( A_.lbound() <= i);
00062 assert( i<= dim_[0] + A_.lbound()-1);
00063 #endif
00064 return dim_[i-A_.lbound()];
00065 }
00066
00067
00068
00069 Region2D(TNT_Array2D &A, Subscript i1, Subscript i2, Subscript j1,
00070 Subscript j2) : A_(A)
00071 {
00072 #ifdef TNT_BOUNDS_CHECK
00073 assert( i1 <= i2 );
00074 assert( j1 <= j2);
00075 assert( A.lbound() <= i1);
00076 assert( i2<= A.dim(A.lbound()) + A.lbound()-1);
00077 assert( A.lbound() <= j1);
00078 assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
00079 #endif
00080
00081
00082 offset_[0] = i1-A.lbound();
00083 offset_[1] = j1-A.lbound();
00084 dim_[0] = i2-i1+1;
00085 dim_[1] = j2-j1+1;
00086 }
00087
00088 Region2D(TNT_Array2D &A, const Index1D &I, const Index1D &J) : A_(A)
00089 {
00090 #ifdef TNT_BOUNDS_CHECK
00091 assert( I.lbound() <= I.ubound() );
00092 assert( J.lbound() <= J.ubound() );
00093 assert( A.lbound() <= I.lbound());
00094 assert( I.ubound()<= A.dim(A.lbound()) + A.lbound()-1);
00095 assert( A.lbound() <= J.lbound());
00096 assert( J.ubound() <= A.dim(A.lbound()+1) + A.lbound()-1 );
00097 #endif
00098
00099 offset_[0] = I.lbound()-A.lbound();
00100 offset_[1] = J.lbound()-A.lbound();
00101 dim_[0] = I.ubound() - I.lbound() + 1;
00102 dim_[1] = J.ubound() - J.lbound() + 1;
00103 }
00104
00105 Region2D(Region2D<TNT_Array2D> &A, Subscript i1, Subscript i2,
00106 Subscript j1, Subscript j2) : A_(A.A_)
00107 {
00108 #ifdef TNT_BOUNDS_CHECK
00109 assert( i1 <= i2 );
00110 assert( j1 <= j2);
00111 assert( A.lbound() <= i1);
00112 assert( i2<= A.dim(A.lbound()) + A.lbound()-1);
00113 assert( A.lbound() <= j1);
00114 assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
00115 #endif
00116 offset_[0] = (i1 - A.lbound()) + A.offset_[0];
00117 offset_[1] = (j1 - A.lbound()) + A.offset_[1];
00118 dim_[0] = i2-i1 + 1;
00119 dim_[1] = j2-j1+1;
00120 }
00121
00122 Region2D<TNT_Array2D> operator()(Subscript i1, Subscript i2,
00123 Subscript j1, Subscript j2)
00124 {
00125 #ifdef TNT_BOUNDS_CHECK
00126 assert( i1 <= i2 );
00127 assert( j1 <= j2);
00128 assert( A_.lbound() <= i1);
00129 assert( i2<= dim_[0] + A_.lbound()-1);
00130 assert( A_.lbound() <= j1);
00131 assert( j2<= dim_[1] + A_.lbound()-1 );
00132 #endif
00133 return Region2D<TNT_Array2D>(A_,
00134 i1+offset_[0], offset_[0] + i2,
00135 j1+offset_[1], offset_[1] + j2);
00136 }
00137
00138
00139 Region2D<TNT_Array2D> operator()(const Index1D &I,
00140 const Index1D &J)
00141 {
00142 #ifdef TNT_BOUNDS_CHECK
00143 assert( I.lbound() <= I.ubound() );
00144 assert( J.lbound() <= J.ubound() );
00145 assert( A_.lbound() <= I.lbound());
00146 assert( I.ubound()<= dim_[0] + A_.lbound()-1);
00147 assert( A_.lbound() <= J.lbound());
00148 assert( J.ubound() <= dim_[1] + A_.lbound()-1 );
00149 #endif
00150
00151 return Region2D<TNT_Array2D>(A_, I.lbound()+offset_[0],
00152 offset_[0] + I.ubound(), offset_[1]+J.lbound(),
00153 offset_[1] + J.ubound());
00154 }
00155
00156 inline T & operator()(Subscript i, Subscript j)
00157 {
00158 #ifdef TNT_BOUNDS_CHECK
00159 assert( A_.lbound() <= i);
00160 assert( i<= dim_[0] + A_.lbound()-1);
00161 assert( A_.lbound() <= j);
00162 assert( j<= dim_[1] + A_.lbound()-1 );
00163 #endif
00164 return A_(i+offset_[0], j+offset_[1]);
00165 }
00166
00167 inline const T & operator() (Subscript i, Subscript j) const
00168 {
00169 #ifdef TNT_BOUNDS_CHECK
00170 assert( A_.lbound() <= i);
00171 assert( i<= dim_[0] + A_.lbound()-1);
00172 assert( A_.lbound() <= j);
00173 assert( j<= dim_[1] + A_.lbound()-1 );
00174 #endif
00175 return A_(i+offset_[0], j+offset_[1]);
00176 }
00177
00178
00179 Region2D<TNT_Array2D> & operator=(const Region2D<TNT_Array2D> &R)
00180 {
00181 Subscript M = num_rows();
00182 Subscript N = num_cols();
00183
00184
00185 assert(M == R.num_rows());
00186 assert(N == R.num_cols());
00187
00188
00189 Subscript start = R.lbound();
00190 Subscript Mend = start + M - 1;
00191 Subscript Nend = start + N - 1;
00192 for (Subscript i=start; i<=Mend; i++)
00193 for (Subscript j=start; j<=Nend; j++)
00194 (*this)(i,j) = R(i,j);
00195
00196 return *this;
00197 }
00198
00199 Region2D<TNT_Array2D> & operator=(const const_Region2D<TNT_Array2D,T> &R)
00200 {
00201 Subscript M = num_rows();
00202 Subscript N = num_cols();
00203
00204
00205 assert(M == R.num_rows());
00206 assert(N == R.num_cols());
00207
00208
00209 Subscript start = R.lbound();
00210 Subscript Mend = start + M - 1;
00211 Subscript Nend = start + N - 1;
00212 for (Subscript i=start; i<=Mend; i++)
00213 for (Subscript j=start; j<=Nend; j++)
00214 (*this)(i,j) = R(i,j);
00215
00216 return *this;
00217 }
00218
00219 Region2D<TNT_Array2D> & operator=(const TNT_Array2D &R)
00220 {
00221 Subscript M = num_rows();
00222 Subscript N = num_cols();
00223
00224
00225 assert(M == R.num_rows());
00226 assert(N == R.num_cols());
00227
00228
00229 Subscript start = R.lbound();
00230 Subscript Mend = start + M - 1;
00231 Subscript Nend = start + N - 1;
00232 for (Subscript i=start; i<=Mend; i++)
00233 for (Subscript j=start; j<=Nend; j++)
00234 (*this)(i,j) = R(i,j);
00235
00236 return *this;
00237 }
00238
00239 Region2D<TNT_Array2D> & operator=(const T &scalar)
00240 {
00241 Subscript start = lbound();
00242 Subscript Mend = lbound() + num_rows() - 1;
00243 Subscript Nend = lbound() + num_cols() - 1;
00244
00245
00246 for (Subscript i=start; i<=Mend; i++)
00247 for (Subscript j=start; j<=Nend; j++)
00248 (*this)(i,j) = scalar;
00249
00250 return *this;
00251 }
00252
00253 };
00254
00255
00256
00257 template <class TNT_Array2D, class T>
00258 class const_Region2D
00259 {
00260 protected:
00261
00262 const TNT_Array2D & A_;
00263 Subscript offset_[2];
00264 Subscript dim_[2];
00265
00266 public:
00267
00268 typedef T value_type;
00269 typedef T element_type;
00270 typedef const T* const_iterator;
00271 typedef const T& const_reference;
00272
00273 const TNT_Array2D & array() const { return A_; }
00274 Subscript lbound() const { return A_.lbound(); }
00275 Subscript num_rows() const { return dim_[0]; }
00276 Subscript num_cols() const { return dim_[1]; }
00277 Subscript offset(Subscript i) const
00278 {
00279 #ifdef TNT_BOUNDS_CHECK
00280 assert( TNT_BASE_OFFSET <= i);
00281 assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
00282 #endif
00283 return offset_[i-TNT_BASE_OFFSET];
00284 }
00285
00286 Subscript dim(Subscript i) const
00287 {
00288 #ifdef TNT_BOUNDS_CHECK
00289 assert( TNT_BASE_OFFSET <= i);
00290 assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
00291 #endif
00292 return dim_[i-TNT_BASE_OFFSET];
00293 }
00294
00295
00296 const_Region2D(const TNT_Array2D &A, Subscript i1, Subscript i2,
00297 Subscript j1, Subscript j2) : A_(A)
00298 {
00299 #ifdef TNT_BOUNDS_CHECK
00300 assert( i1 <= i2 );
00301 assert( j1 <= j2);
00302 assert( TNT_BASE_OFFSET <= i1);
00303 assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
00304 assert( TNT_BASE_OFFSET <= j1);
00305 assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
00306 #endif
00307
00308 offset_[0] = i1-TNT_BASE_OFFSET;
00309 offset_[1] = j1-TNT_BASE_OFFSET;
00310 dim_[0] = i2-i1+1;
00311 dim_[1] = j2-j1+1;
00312 }
00313
00314 const_Region2D(const TNT_Array2D &A, const Index1D &I, const Index1D &J)
00315 : A_(A)
00316 {
00317 #ifdef TNT_BOUNDS_CHECK
00318 assert( I.lbound() <= I.ubound() );
00319 assert( J.lbound() <= J.ubound() );
00320 assert( TNT_BASE_OFFSET <= I.lbound());
00321 assert( I.ubound()<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
00322 assert( TNT_BASE_OFFSET <= J.lbound());
00323 assert( J.ubound() <= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
00324 #endif
00325
00326 offset_[0] = I.lbound()-TNT_BASE_OFFSET;
00327 offset_[1] = J.lbound()-TNT_BASE_OFFSET;
00328 dim_[0] = I.ubound() - I.lbound() + 1;
00329 dim_[1] = J.ubound() - J.lbound() + 1;
00330 }
00331
00332
00333 const_Region2D(const_Region2D<TNT_Array2D,T> &A, Subscript i1,
00334 Subscript i2,
00335 Subscript j1, Subscript j2) : A_(A.A_)
00336 {
00337 #ifdef TNT_BOUNDS_CHECK
00338 assert( i1 <= i2 );
00339 assert( j1 <= j2);
00340 assert( TNT_BASE_OFFSET <= i1);
00341 assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
00342 assert( TNT_BASE_OFFSET <= j1);
00343 assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
00344 #endif
00345 offset_[0] = (i1 - TNT_BASE_OFFSET) + A.offset_[0];
00346 offset_[1] = (j1 - TNT_BASE_OFFSET) + A.offset_[1];
00347 dim_[0] = i2-i1 + 1;
00348 dim_[1] = j2-j1+1;
00349 }
00350
00351 const_Region2D<TNT_Array2D,T> operator()(Subscript i1, Subscript i2,
00352 Subscript j1, Subscript j2)
00353 {
00354 #ifdef TNT_BOUNDS_CHECK
00355 assert( i1 <= i2 );
00356 assert( j1 <= j2);
00357 assert( TNT_BASE_OFFSET <= i1);
00358 assert( i2<= dim_[0] + TNT_BASE_OFFSET-1);
00359 assert( TNT_BASE_OFFSET <= j1);
00360 assert( j2<= dim_[0] + TNT_BASE_OFFSET-1 );
00361 #endif
00362 return const_Region2D<TNT_Array2D,T>(A_,
00363 i1+offset_[0], offset_[0] + i2,
00364 j1+offset_[1], offset_[1] + j2);
00365 }
00366
00367
00368 const_Region2D<TNT_Array2D,T> operator()(const Index1D &I,
00369 const Index1D &J)
00370 {
00371 #ifdef TNT_BOUNDS_CHECK
00372 assert( I.lbound() <= I.ubound() );
00373 assert( J.lbound() <= J.ubound() );
00374 assert( TNT_BASE_OFFSET <= I.lbound());
00375 assert( I.ubound()<= dim_[0] + TNT_BASE_OFFSET-1);
00376 assert( TNT_BASE_OFFSET <= J.lbound());
00377 assert( J.ubound() <= dim_[1] + TNT_BASE_OFFSET-1 );
00378 #endif
00379
00380 return const_Region2D<TNT_Array2D,T>(A_, I.lbound()+offset_[0],
00381 offset_[0] + I.ubound(), offset_[1]+J.lbound(),
00382 offset_[1] + J.ubound());
00383 }
00384
00385
00386 inline const T & operator() (Subscript i, Subscript j) const
00387 {
00388 #ifdef TNT_BOUNDS_CHECK
00389 assert( TNT_BASE_OFFSET <= i);
00390 assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
00391 assert( TNT_BASE_OFFSET <= j);
00392 assert( j<= dim_[1] + TNT_BASE_OFFSET-1 );
00393 #endif
00394 return A_(i+offset_[0], j+offset_[1]);
00395 }
00396
00397 };
00398
00399
00400
00401
00402 template <class TNT_Array2D,class T>
00403 ostream& operator<<(ostream &s, const const_Region2D<TNT_Array2D,T> &A)
00404 {
00405 Subscript start = A.lbound();
00406 Subscript Mend=A.lbound()+ A.num_rows() - 1;
00407 Subscript Nend=A.lbound() + A.num_cols() - 1;
00408
00409
00410 s << A.num_rows() << " " << A.num_cols() << endl;
00411 for (Subscript i=start; i<=Mend; i++)
00412 {
00413 for (Subscript j=start; j<=Nend; j++)
00414 {
00415 s << A(i,j) << " ";
00416 }
00417 s << endl;
00418 }
00419
00420
00421 return s;
00422 }
00423
00424 template <class TNT_Array2D>
00425 ostream& operator<<(ostream &s, const Region2D<TNT_Array2D> &A)
00426 {
00427 Subscript start = A.lbound();
00428 Subscript Mend=A.lbound()+ A.num_rows() - 1;
00429 Subscript Nend=A.lbound() + A.num_cols() - 1;
00430
00431
00432 s << A.num_rows() << " " << A.num_cols() << endl;
00433 for (Subscript i=start; i<=Mend; i++)
00434 {
00435 for (Subscript j=start; j<=Nend; j++)
00436 {
00437 s << A(i,j) << " ";
00438 }
00439 s << endl;
00440 }
00441
00442
00443 return s;
00444
00445 }
00446
00447 #endif
00448