|
STK++ 1.0
|
00001 /*--------------------------------------------------------------------*/ 00002 /* Copyright (C) 2004-2011 Serge Iovleff 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as 00006 published by the Free Software Foundation; either version 2 of the 00007 License, or (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public 00015 License along with this program; if not, write to the 00016 Free Software Foundation, Inc., 00017 59 Temple Place, 00018 Suite 330, 00019 Boston, MA 02111-1307 00020 USA 00021 00022 Contact : Serge.Iovleff@stkpp.org 00023 */ 00024 00025 /* 00026 * Project: stkpp::Sdk::TContainer 00027 * created on: 26 nov. 2011 00028 * Author: Serge Iovleff, serge.iovleff@stkpp.org 00029 **/ 00030 00039 #ifndef STK_ITCONTAINER2D_H 00040 #define STK_ITCONTAINER2D_H 00041 00042 #include "STK_IContainer2D.h" 00043 #include "STK_ITContainer1D.h" 00044 #include "../../STKernel/include/STK_Exceptions.h" 00045 00046 namespace STK 00047 { 00048 template <class TYPE, class TContainer2D> 00049 class ContainerTraits; 00050 00100 template <class TYPE, class TContainer2D> 00101 class ITContainer2D : public IContainerBase<TContainer2D>, public IContainer2D 00102 { 00103 protected: 00108 ITContainer2D( Range const& I = Range(), Range const& J = Range()) 00109 : IContainerBase<TContainer2D>(IContainerBase<TContainer2D>::_2D_) 00110 , IContainer2D(I, J) 00111 { this->ranges_.push_back(&rangeVe_); this->ranges_.push_back(&rangeHo_);} 00112 00116 ITContainer2D( const ITContainer2D &T) 00117 : IContainerBase<TContainer2D>(IContainerBase<TContainer2D>::_2D_) 00118 , IContainer2D(T) 00119 { this->ranges_.push_back(&rangeVe_); this->ranges_.push_back(&rangeHo_);} 00120 00121 public: 00123 typedef TYPE Type; 00126 typedef typename ContainerTraits<TYPE, TContainer2D>::TContainerVe TContainerVe; 00129 typedef typename ContainerTraits<TYPE, TContainer2D>::TContainerHo TContainerHo; 00130 00132 virtual ~ITContainer2D() { ;} 00133 00139 inline TYPE& elt(Integer const& i, Integer const& j) 00140 { return this->asLeaf().elt(i,j);} 00141 00147 inline TYPE const& elt(Integer const& i, Integer const& j) const 00148 { return this->asLeaf().elt(i,j);} 00149 00155 inline TYPE& operator()(Integer const& i, Integer const& j) 00156 { return this->asLeaf().elt(i,j);} 00157 00163 inline TYPE const& operator()(Integer const& i, Integer const& j) const 00164 { return this->asLeaf().elt(i,j);} 00165 00170 inline TContainerVe operator[](Integer const& j) const 00171 { return this->asLeaf().col(j);} 00172 00177 inline TContainerVe col(Integer const& j) const 00178 { return this->asLeaf().col(j);} 00179 00186 inline TContainerVe operator()(Range const& I, Integer const& j) const 00187 { return this->asLeaf().col(I, j);} 00188 00193 inline TContainerHo operator()(Integer const& i) const 00194 { return this->asLeaf().row(i);} 00195 00200 inline TContainerHo row(Integer const& i) const 00201 { return this->asLeaf().row(i);} 00202 00209 inline TContainerHo operator()(Integer const& i, Range const& J) const 00210 { return this->asLeaf().row(i, J);} 00211 00217 inline TContainer2D operator()(Range const& I, Range const& J) const 00218 { return this->asLeaf().sub(I, J);} 00219 00225 inline TContainer2D operator()(Range const& I) const 00226 { return this->asLeaf().sub(I, this->rangeHo());} 00227 00233 inline TContainer2D operator[](Range const& J) const 00234 { return this->asLeaf().sub(this->rangeVe(), J);} 00235 00241 TYPE& at(Integer const& i, Integer const& j) 00242 { 00243 if (this->firstRow() > i) 00244 { throw out_of_range("ITContainer2DBase::at(i, j) " 00245 "this->firstRow() > i"); 00246 } 00247 if (this->lastRow() < i) 00248 { throw out_of_range("ITContainer2DBase::at(i, j) " 00249 "this->lastRow() < i"); 00250 } 00251 if (this->firstCol() > j) 00252 { throw out_of_range("ITContainer2DBase::at(i, j) " 00253 "this->firstCol() > j"); 00254 } 00255 if (this->lastCol() < j) 00256 { throw out_of_range("ITContainer2DBase::at(i, j) " 00257 "this->lastCol() < j"); 00258 } 00259 return this->asLeaf().elt(i, j); 00260 } 00261 00267 TYPE const& at(Integer const& i, Integer const& j) const 00268 { 00269 // check bounds 00270 if (this->firstRow() > i) 00271 { throw out_of_range("ITContainer2DBase::at(i, j) " 00272 "this->firstRow() > i"); 00273 } 00274 if (this->lastRow() < i) 00275 { throw out_of_range("ITContainer2DBase::at(i, j) " 00276 "this->lastRow() < i"); 00277 } 00278 if (this->firstCol() > j) 00279 { throw out_of_range("ITContainer2DBase::at(i, j) " 00280 "this->firstCol() > j"); 00281 } 00282 if (this->lastCol() < j) 00283 { throw out_of_range("ITContainer2DBase::at(i, j) " 00284 "this->lastCol() < j"); 00285 } 00286 // return element 00287 return this->asLeaf().elt(i, j); 00288 } 00289 00294 inline TContainer2D at(Range const& I, Range const& J) const 00295 { 00296 if (this->firstRow() > I.first()) 00297 { throw out_of_range("ITContainer2D::at(I, J) " 00298 "this->firstRow() > I.first()"); 00299 } 00300 if (this->lastRow() < I.last()) 00301 { throw out_of_range("ITContainer2D::at(I, J) " 00302 "this->lastRow() < I.last()"); 00303 } 00304 if (this->firstCol() > J.first()) 00305 { throw out_of_range("ITContainer2D::at(I, J) " 00306 "this->firstCol() > J.first()"); 00307 } 00308 if (this->lastCol() < J.last()) 00309 { throw out_of_range("ITContainer2D::at(I, J) " 00310 "this->lastCol() < J.last()"); 00311 } 00312 return this->asLeaf().sub(I, J); 00313 } 00314 00319 inline TContainerVe at(Range const& I, Integer const& j) const 00320 { 00321 if (this->firstRow() > I.first()) 00322 { throw out_of_range("TContainer2D::at(I, j) " 00323 "this->firstRow() > I.first()"); 00324 } 00325 if (this->lastRow() < I.last()) 00326 { throw out_of_range("TContainer2D::at(I, j) " 00327 "this->lastRow() < I.last()"); 00328 } 00329 if (this->firstCol() > j) 00330 { throw out_of_range("TContainer2D::at(I, j) " 00331 "this->firstCol() > j"); 00332 } 00333 if (this->lastCol() < j) 00334 { throw out_of_range("TContainer2D::at(I, j) " 00335 "this->lastCol() < j"); 00336 } 00337 return this->asLeaf().col(I, j); 00338 } 00339 00344 inline TContainerHo at(Integer const& i, Range const& J) const 00345 { 00346 if (this->firstRow() > i) 00347 { throw out_of_range("TContainer2D::at(i, J) " 00348 "this->firstRow() > i"); 00349 } 00350 if (this->lastRow() < i) 00351 { throw out_of_range("TContainer2D::at(i, J) " 00352 "this->lastRow() < i"); 00353 } 00354 if (this->firstCol() > J.first()) 00355 { throw out_of_range("TContainer2D::at(i, J) " 00356 "this->firstCol() > J.first()"); 00357 } 00358 if (this->lastCol() < J.last()) 00359 { throw out_of_range("TContainer2D::at(i, J) " 00360 "this->lastCol() < J.last()"); 00361 } 00362 return this->asLeaf().row(J, i); 00363 } 00364 00368 inline TContainerVe atCol(Integer const& j) const 00369 { 00370 if (this->firstCol() > j) 00371 { throw out_of_range("TContainer2D::atCol(j) " 00372 "this->firstCol() > j"); 00373 } 00374 if (this->lastCol() < j) 00375 { throw out_of_range("TContainer2D::atCol(j) " 00376 "this->lastCol() < j"); 00377 } 00378 return this->asLeaf().col(this->rangeVe(), j); 00379 } 00380 00384 inline TContainer2D atCol(Range const& J) const 00385 { 00386 if (this->firstCol() > J.first()) 00387 { throw out_of_range("TContainer2D::atCol(J) " 00388 "this->firstCol() > J.first()"); 00389 } 00390 if (this->lastCol() < J.last()) 00391 { throw out_of_range("TContainer2D::atCol(J) " 00392 "this->lastCol() < J.last()"); 00393 } 00394 return this->asLeaf().sub(this->rangeVe(), J); 00395 } 00396 00400 inline TContainerHo atRow(Integer const& i) const 00401 { 00402 if (this->firstRow() > i) 00403 { throw out_of_range("TContainer2D::atRow(i) " 00404 "this->firstRow() > i"); 00405 } 00406 if (this->lastRow() < i) 00407 { throw out_of_range("TContainer2D::atRow(i) " 00408 "this->lastRow() < i"); 00409 } 00410 return this->asLeaf().row(i, this->rangeHo()); 00411 } 00412 00416 inline TContainer2D atRow(Range const& I) const 00417 { 00418 if (this->firstRow() > I.first()) 00419 { throw out_of_range("TContainer2D::atRow(I) " 00420 "this->firstRow() > I.first()"); 00421 } 00422 if (this->lastRow() < I.last()) 00423 { throw out_of_range("TContainer2D::atRow(I) " 00424 "this->lastRow() < I.last()"); 00425 } 00426 return this->asLeaf().sub(I, this->rangeHo()); 00427 } 00428 00432 template<class Container1D> 00433 inline void pushBackCol(ITContainer1D<TYPE, Container1D> const& V) 00434 { 00435 const Integer firstRow = V.first(), lastRow = V.last(); 00436 // check if the container is empty 00437 if (this->empty()) 00438 { 00439 this->resize(V.range(), Range(1)); 00440 for (Integer i=firstRow; i<=lastRow; i++) 00441 (*this)(i, 1) = V[i]; 00442 return; 00443 } 00444 #ifdef STK_BOUNDS_CHECK 00445 if (V.range() != this->rangeVe()) 00446 { throw runtime_error("TContainer2D::pushBackCol(V) " 00447 "V.range() != this->rangeVe()"); 00448 } 00449 #endif 00450 // if the container is not empty we add a column and copy V inside 00451 this->asLeaf().pushBackCols(); 00452 const Integer lastCol = this->lastCol(); 00453 for (Integer i=firstRow; i<=lastRow; i++) 00454 (*this)(i, lastCol) = V[i]; 00455 } 00456 }; 00457 00458 } // namespace STK 00459 00460 #endif 00461 // STK_ITCONTAINER2D_H