AbstractLinAlgPack: C++ Interfaces For Vectors, Matrices And Related Linear Algebra Objects Version of the Day
AbstractLinAlgPack_GenPermMatrixSliceIterator.hpp
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00005 //                  Copyright (2003) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #ifndef GEN_PERM_MATRIX_SLICE_ITERATOR_H
00030 #define GEN_PERM_MATRIX_SLICE_ITERATOR_H
00031 
00032 #include <assert.h>
00033 
00034 #include <iterator>
00035 
00036 #include "AbstractLinAlgPack_Types.hpp"
00037 
00038 namespace AbstractLinAlgPack {
00039 
00040 namespace GenPermMatrixSliceIteratorPack {
00041 
00043 enum EOrderedBy { BY_ROW, BY_COL, BY_ROW_AND_COL, UNORDERED };
00044 
00049 template< class T >
00050 class external_row_col_value_type {
00051 public:
00053   typedef T     index_type;
00055   typedef ptrdiff_t difference_type;
00057   external_row_col_value_type(
00058       difference_type row_off
00059     , difference_type col_off
00060     , index_type    row_i
00061     , index_type    col_j
00062     )
00063   :
00064     row_off_(row_off), col_off_(col_off), row_i_(row_i), col_j_(col_j)
00065   {}
00066   difference_type row_off_;
00067   difference_type col_off_;
00068   index_type    row_i_;
00069   index_type    col_j_;
00070 };
00071 
00075 template< class T >
00076 class row_col_value_type {
00077 public:
00079   typedef T     index_type;
00081   typedef ptrdiff_t difference_type;
00083   row_col_value_type( 
00084       difference_type row_off
00085     , difference_type col_off
00086     , index_type    row_i[]
00087     , index_type    col_j[]
00088     , size_type     nz
00089     );
00091   void bind_view( const row_col_value_type<T>& val );
00093   void increment(difference_type);
00095   index_type  row_i() const;
00097   index_type  col_j() const;
00099   index_type* row_i_ptr() const;
00101   row_col_value_type<T>& operator=( const row_col_value_type<T>& val );
00103   operator const external_row_col_value_type<T>() const
00104   {
00105     return external_row_col_value_type<T>(row_off_,col_off_,*row_i_,*col_j_);
00106   }
00108   row_col_value_type<T>& operator=( const external_row_col_value_type<T>& val )
00109   {
00110     TEST_FOR_EXCEPT( !(  row_off_ == val.row_off_  ) );
00111     TEST_FOR_EXCEPT( !(  col_off_ == val.col_off_  ) );
00112     *row_i_ = val.row_i_;
00113     *col_j_ = val.col_j_;
00114     return *this;
00115   }
00116   
00117 private:
00118   difference_type row_off_;
00119   difference_type col_off_;
00120   index_type    *row_i_;
00121   index_type    *col_j_;
00122   size_type   nz_;
00123   int       k_; // zero based
00125   void assert_in_range() const;
00127   row_col_value_type();
00128 
00129 };  // end class row_col_value_type
00130 
00132 template< class T >
00133 inline
00134 void swap( row_col_value_type<T>& v1, row_col_value_type<T>& v2 )
00135 {
00136   row_col_value_type<T> tmp = v1;
00137   v1 = v2;
00138   v2 = tmp;
00139 }
00140 
00144 template< class T >
00145 class row_col_iterator
00146 #if defined(_WINDOWS) || defined(_INTEL_CXX) || defined(_PG_CXX) 
00147   : public std::iterator< std::random_access_iterator_tag, external_row_col_value_type<T>, ptrdiff_t >
00148 #endif
00149 {
00150 public:
00152   typedef T               index_type;
00154   typedef std::random_access_iterator_tag iterator_category;
00156   typedef external_row_col_value_type<T>  value_type;
00158   typedef row_col_value_type<T>&      reference;
00160   typedef row_col_value_type<T>*      pointer;
00162   typedef ptrdiff_t           difference_type;
00164   row_col_iterator();
00166   row_col_iterator(
00167      difference_type  row_off
00168     ,difference_type  col_off
00169     ,index_type   row_i[]
00170     ,index_type   col_j[]
00171     ,size_type      nz      // Number of elements in row_i[] and col_j[]
00172     );
00174   row_col_iterator<T>& operator=( const row_col_iterator<T>& itr );
00176   reference operator*();
00178   reference operator*() const;
00180   pointer operator->() const;
00182   row_col_iterator<T> operator+(difference_type);
00184   row_col_iterator<T> operator-(difference_type);
00186   row_col_iterator<T>&  operator+=(difference_type);
00188   row_col_iterator<T>&  operator-=(difference_type);
00190   row_col_iterator<T>&  operator++();
00192   const row_col_iterator<T> operator++(int);
00194   row_col_iterator<T>&  operator--();
00196   const row_col_iterator<T> operator--(int);
00198   difference_type operator-(const row_col_iterator<T>& itr) const;
00200   bool operator<( const row_col_iterator<T>& itr) const;
00202   bool operator<=( const row_col_iterator<T>& itr) const;
00204   bool operator>( const row_col_iterator<T>& itr) const;
00206   bool operator>=( const row_col_iterator<T>& itr) const;
00208   bool operator==( const row_col_iterator<T>& itr) const;
00210   bool operator!=( const row_col_iterator<T>& itr) const;
00212   bool operator!() const;
00213   
00214 private:
00215   mutable row_col_value_type<T> value_;
00216   
00217 };  // end class row_col_iterator<T>
00218 
00219 // //////////////////////////////////////////////////////////
00220 // Inline members for row_col_value_type<T>
00221 
00222 template<class T>
00223 inline
00224 row_col_value_type<T>::row_col_value_type( 
00225       difference_type row_off
00226     , difference_type col_off
00227     , index_type    row_i[]
00228     , index_type    col_j[]
00229     , size_type     nz
00230     )
00231   :
00232     row_off_(row_off)
00233     ,col_off_(col_off)
00234     ,row_i_(row_i)
00235     ,col_j_(col_j)
00236     ,nz_(nz)
00237     ,k_(0)
00238 {}
00239 
00240 template<class T>
00241 inline
00242 void row_col_value_type<T>::bind_view( const row_col_value_type<T>& val )
00243 {
00244     row_off_  = val.row_off_;
00245     col_off_  = val.col_off_;
00246     row_i_    = val.row_i_;
00247     col_j_    = val.col_j_;
00248     nz_     = val.nz_;
00249     k_      = val.k_;
00250 }
00251 
00252 template< class T >
00253 inline
00254 void row_col_value_type<T>::increment(difference_type d)
00255 {
00256   row_i_  += d;
00257   col_j_  += d;
00258   k_    += d;
00259 }
00260 
00261 template< class T >
00262 inline
00263 typename row_col_value_type<T>::index_type row_col_value_type<T>::row_i() const
00264 {
00265   assert_in_range();
00266   return *row_i_ + row_off_;
00267 }
00268 
00269 template< class T >
00270 inline
00271 typename row_col_value_type<T>::index_type row_col_value_type<T>::col_j() const
00272 {
00273   assert_in_range();
00274   return *col_j_ + col_off_;
00275 }
00276 
00277 template< class T >
00278 inline
00279 typename row_col_value_type<T>::index_type* row_col_value_type<T>::row_i_ptr() const
00280 {
00281   return row_i_;
00282 }
00283 
00284 template< class T >
00285 inline
00286 row_col_value_type<T>& row_col_value_type<T>::operator=(
00287   const row_col_value_type<T>& val )
00288 {
00289   *row_i_ = *val.row_i_;
00290   *col_j_ = *val.col_j_;
00291   return *this;
00292 }
00293 
00294 template< class T >
00295 inline
00296 void row_col_value_type<T>::assert_in_range() const
00297 {
00298   // ToDo: Finish this!
00299   TEST_FOR_EXCEPT( !(  0 <= k_ && k_ < nz_  ) );
00300 }
00301 
00303 void GPMS_row_col_iterator_assert_not_null(const void* p);
00304 
00305 // //////////////////////////////////////////////////////////
00306 // Inline members for row_col_iterator<T>
00307 
00308 template< class T >
00309 inline
00310 row_col_iterator<T>::row_col_iterator()
00311   :
00312     value_(0,0,NULL,NULL,0)
00313 {}
00314 
00315 template< class T >
00316 inline
00317 row_col_iterator<T>::row_col_iterator(
00318      difference_type  row_off
00319     ,difference_type  col_off
00320     ,index_type         row_i[]
00321     ,index_type         col_j[]
00322     ,size_type      nz
00323     )
00324   :
00325     value_(row_off,col_off,row_i,col_j,nz)
00326 {}
00327 
00328 template< class T >
00329 inline
00330 row_col_iterator<T>& row_col_iterator<T>::operator=( const row_col_iterator<T>& itr )
00331 {
00332   value_.bind_view( itr.value_ );
00333   return *this;
00334 }
00335 
00336 template< class T >
00337 inline
00338 typename row_col_iterator<T>::reference
00339 row_col_iterator<T>::operator*()
00340 {
00341   GPMS_row_col_iterator_assert_not_null(value_.row_i_ptr());
00342   return value_;
00343 }
00344 
00345 
00346 template< class T >
00347 inline
00348 typename row_col_iterator<T>::reference
00349 row_col_iterator<T>::operator*() const
00350 {
00351   GPMS_row_col_iterator_assert_not_null(value_.row_i_ptr());
00352   return value_;
00353 }
00354 
00355 template< class T >
00356 inline
00357 typename row_col_iterator<T>::pointer
00358 row_col_iterator<T>::operator->() const
00359 {
00360   GPMS_row_col_iterator_assert_not_null(value_.row_i_ptr());
00361   return &value_;
00362 }
00363 
00364 template< class T >
00365 inline
00366 row_col_iterator<T>
00367 row_col_iterator<T>::operator+(difference_type d)
00368 {
00369   row_col_iterator<T> itr = *this;
00370   itr.value_.increment(d);
00371   return itr;
00372 }
00373 
00374 template< class T >
00375 inline
00376 row_col_iterator<T>
00377 row_col_iterator<T>::operator-(difference_type d)
00378 {
00379   row_col_iterator<T> itr = *this;
00380   itr.value_.increment(-d);
00381   return itr;
00382 }
00383 
00384 template< class T >
00385 inline
00386 row_col_iterator<T>&
00387 row_col_iterator<T>::operator+=(difference_type d)
00388 {
00389   value_.increment(d);
00390   return *this;
00391 }
00392 
00393 template< class T >
00394 inline
00395 row_col_iterator<T>&
00396 row_col_iterator<T>::operator-=(difference_type d)
00397 {
00398   value_.increment(-d);
00399   return *this;
00400 }
00401 
00402 template< class T >
00403 inline
00404 row_col_iterator<T>&
00405 row_col_iterator<T>::operator++()
00406 {
00407   value_.increment(1);
00408   return *this;
00409 }
00410 
00411 template< class T >
00412 inline
00413 const row_col_iterator<T>
00414 row_col_iterator<T>::operator++(int)
00415 {
00416   row_col_iterator<T> itr = *this;
00417   value_.increment(1);
00418   return itr;
00419 }
00420 
00421 template< class T >
00422 inline
00423 row_col_iterator<T>&
00424 row_col_iterator<T>::operator--()
00425 {
00426   value_.increment(-1);
00427   return *this;
00428 }
00429 
00430 template< class T >
00431 inline
00432 const row_col_iterator<T>
00433 row_col_iterator<T>::operator--(int)
00434 {
00435   row_col_iterator<T> itr = *this;
00436   value_.increment(-1);
00437   return itr;
00438 }
00439 
00440 template< class T >
00441 inline
00442 typename row_col_iterator<T>::difference_type
00443 row_col_iterator<T>::operator-(const row_col_iterator<T>& itr) const
00444 {
00445   return value_.row_i_ptr() - itr.value_.row_i_ptr();
00446 }
00447 
00448 template< class T >
00449 inline
00450 bool row_col_iterator<T>::operator<( const row_col_iterator<T>& itr) const
00451 {
00452   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00453       &&  ( value_.row_i_ptr() < itr.value_.row_i_ptr() );
00454 }
00455 
00456 template< class T >
00457 inline
00458 bool row_col_iterator<T>::operator<=( const row_col_iterator<T>& itr) const
00459 {
00460   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00461       &&  ( value_.row_i_ptr() <= itr.value_.row_i_ptr() );
00462 }
00463 
00464 template< class T >
00465 inline
00466 bool row_col_iterator<T>::operator>( const row_col_iterator<T>& itr) const
00467 {
00468   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00469       &&  ( value_.row_i_ptr() > itr.value_.row_i_ptr() );
00470 }
00471 
00472 template< class T >
00473 inline
00474 bool row_col_iterator<T>::operator>=( const row_col_iterator<T>& itr) const
00475 {
00476   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00477       &&  ( value_.row_i_ptr() >= itr.value_.row_i_ptr() );
00478 }
00479 
00480 template< class T >
00481 inline
00482 bool row_col_iterator<T>::operator==( const row_col_iterator<T>& itr) const
00483 {
00484   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00485       &&  ( value_.row_i_ptr() == itr.value_.row_i_ptr() );
00486 }
00487 
00488 template< class T >
00489 inline
00490 bool row_col_iterator<T>::operator!=( const row_col_iterator<T>& itr) const
00491 {
00492   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00493       &&  ( value_.row_i_ptr() != itr.value_.row_i_ptr() );
00494 }
00495 
00496 template< class T >
00497 inline
00498 bool row_col_iterator<T>::operator!() const
00499 {
00500   return  value_.row_i_ptr() == NULL;
00501 }
00502 
00503 } // end namespace GenPermMatrixSliceIteratorPack
00504 
00505 } // end namespace AbstractLinAlgPack
00506 
00507 #endif   // GEN_PERM_MATRIX_SLICE_ITERATOR_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends