|
Teuchos - Trilinos Tools Package
Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) 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 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #ifndef TEUCHOS_FILTERED_ITERATOR_HPP 00043 #define TEUCHOS_FILTERED_ITERATOR_HPP 00044 00045 00046 #include "Teuchos_Assert.hpp" 00047 #include "Teuchos_TypeNameTraits.hpp" 00048 #include "Teuchos_Exceptions.hpp" 00049 00050 00051 namespace Teuchos { 00052 00053 00059 template<class IteratorType, class Predicate> 00060 class FilteredIterator { 00061 public: 00062 00065 00067 typedef std::bidirectional_iterator_tag iterator_category; 00069 typedef typename std::iterator_traits<IteratorType>::value_type value_type; 00071 typedef typename std::iterator_traits<IteratorType>::reference reference; 00073 typedef typename std::iterator_traits<IteratorType>::pointer pointer; 00075 typedef typename std::iterator_traits<IteratorType>::difference_type difference_type; 00076 00078 00081 00083 FilteredIterator() 00084 {} 00088 FilteredIterator(IteratorType current_in, IteratorType begin_in, IteratorType end_in, 00089 Predicate pred_in = Predicate() 00090 ) 00091 :current_(current_in), begin_(begin_in), end_(end_in), pred_(pred_in) 00092 { advanceForwardToValid(); } 00094 template<class IteratorType2, class Predicate2> 00095 FilteredIterator(const FilteredIterator<IteratorType2,Predicate2>& rhs) 00096 :current_(rhs.current()), begin_(rhs.begin()), end_(rhs.end()), pred_(rhs.pred()) 00097 {} 00099 template<class IteratorType2, class Predicate2> 00100 FilteredIterator & operator=(const FilteredIterator<IteratorType2,Predicate2>& rhs) 00101 { 00102 current_ = rhs.current(); 00103 begin_ = rhs.begin(); 00104 end_ = rhs.end(); 00105 pred_ = rhs.pred(); 00106 return *this; 00107 } 00108 00110 00113 00115 reference operator*() const 00116 { return *current_; } 00118 pointer operator->() const 00119 { return current_.operator->(); } 00120 00122 00125 00127 FilteredIterator& operator++() 00128 { 00129 assertNotIterateForwardPastEnd(); 00130 ++current_; 00131 advanceForwardToValid(); 00132 return *this; 00133 } 00135 const FilteredIterator operator++(int) 00136 { 00137 FilteredIterator tmp = *this; 00138 ++*this; 00139 return tmp; 00140 } 00142 FilteredIterator& operator--() 00143 { 00144 assertNotIterateBackwardPastBegin(); 00145 --current_; 00146 advanceBackwardToValid(); 00147 return *this; 00148 } 00150 const FilteredIterator operator--(int) 00151 { 00152 FilteredIterator tmp = *this; 00153 --*this; 00154 return tmp; 00155 } 00156 00158 00161 00163 IteratorType current() const { return current_; } 00165 IteratorType begin() const { return begin_; } 00167 IteratorType end() const { return end_; } 00169 Predicate pred() const{ return pred_; } 00170 00172 00173 private: // Data members 00174 00176 IteratorType current_; 00178 IteratorType begin_; 00180 IteratorType end_; 00182 Predicate pred_; 00183 00184 private: // Functions 00185 00187 void advanceForwardToValid(); 00189 void advanceBackwardToValid(); 00191 void assertNotIterateForwardPastEnd() 00192 #ifndef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00193 {} 00194 #else 00195 ; 00196 #endif 00197 00198 void assertNotIterateBackwardPastBegin() 00199 #ifndef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00200 {} 00201 #else 00202 ; 00203 #endif 00204 00205 }; 00206 00207 00211 template<class IteratorType, class Predicate> 00212 inline bool operator==(const FilteredIterator<IteratorType,Predicate>& itr1, 00213 const FilteredIterator<IteratorType,Predicate>& itr2) 00214 { 00215 return itr1.current() == itr2.current(); 00216 } 00217 00218 00222 template<class IteratorType, class Predicate> 00223 inline bool operator!=(const FilteredIterator<IteratorType,Predicate>& itr1, 00224 const FilteredIterator<IteratorType,Predicate>& itr2) 00225 { 00226 return itr1.current() != itr2.current(); 00227 } 00228 00229 00236 template<class IteratorType, class Predicate> 00237 std::ostream& operator<<(std::ostream &out, const FilteredIterator<IteratorType,Predicate>& itr) 00238 { 00239 out << "FilteredIterator{current=???, end=???, pred="<<TypeNameTraits<Predicate>::name()<<"}"; 00240 return out; 00241 } 00242 00243 // 00244 // Template definitions 00245 // 00246 00247 00248 template<class IteratorType, class Predicate> 00249 void FilteredIterator<IteratorType,Predicate>::advanceForwardToValid() 00250 { 00251 while (current_ != end_ && !pred_(*current_)) { 00252 ++current_; 00253 } 00254 } 00255 00256 00257 template<class IteratorType, class Predicate> 00258 void FilteredIterator<IteratorType,Predicate>::advanceBackwardToValid() 00259 { 00260 while (current_ != begin_ && !pred_(*current_)) { 00261 --current_; 00262 } 00263 } 00264 00265 00266 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00267 00268 00269 template<class IteratorType, class Predicate> 00270 void FilteredIterator<IteratorType,Predicate>::assertNotIterateForwardPastEnd() 00271 { 00272 const bool current_is_at_end = (current_ == end_); 00273 TEUCHOS_TEST_FOR_EXCEPTION( current_is_at_end, RangeError, 00274 "Error, trying to iterate " << *this << " forward ++ past end!"); 00275 } 00276 00277 00278 template<class IteratorType, class Predicate> 00279 void FilteredIterator<IteratorType,Predicate>::assertNotIterateBackwardPastBegin() 00280 { 00281 const bool current_is_at_begin = (current_ == begin_); 00282 TEUCHOS_TEST_FOR_EXCEPTION( current_is_at_begin, RangeError, 00283 "Error, trying to iterate " << *this << " backward -- past begin!"); 00284 } 00285 00286 00287 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00288 00289 00290 } // end namespace Teuchos 00291 00292 00293 #endif // TEUCHOS_FILTERED_ITERATOR_HPP
1.7.6.1