yat
0.8.3pre
|
00001 #ifndef _theplu_yat_utility_stride_iterator_ 00002 #define _theplu_yat_utility_stride_iterator_ 00003 00004 // $Id: StrideIterator.h 2365 2010-12-06 00:40:13Z peter $ 00005 00006 /* 00007 Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson 00008 Copyright (C) 2010 Peter Johansson 00009 00010 This file is part of the yat library, http://dev.thep.lu.se/yat 00011 00012 The yat library is free software; you can redistribute it and/or 00013 modify it under the terms of the GNU General Public License as 00014 published by the Free Software Foundation; either version 3 of the 00015 License, or (at your option) any later version. 00016 00017 The yat library is distributed in the hope that it will be useful, 00018 but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 General Public License for more details. 00021 00022 You should have received a copy of the GNU General Public License 00023 along with yat. If not, see <http://www.gnu.org/licenses/>. 00024 */ 00025 00026 #include <boost/concept_check.hpp> 00027 #include <boost/iterator/iterator_adaptor.hpp> 00028 00029 namespace theplu { 00030 namespace yat { 00031 namespace utility { 00032 00044 template<typename RandomAccessIterator> 00045 class StrideIterator 00046 : public boost::iterator_adaptor<StrideIterator<RandomAccessIterator> 00047 , RandomAccessIterator 00048 , boost::use_default 00049 , typename std::iterator_traits<RandomAccessIterator>::iterator_category> 00050 { 00051 typedef boost::iterator_adaptor<StrideIterator<RandomAccessIterator>, 00052 RandomAccessIterator, 00053 boost::use_default, 00054 typename std::iterator_traits<RandomAccessIterator>::iterator_category> 00055 super_t; 00056 00057 public: 00059 typedef RandomAccessIterator iterator_type; 00060 00066 explicit StrideIterator(size_t stride=1) 00067 : StrideIterator::iterator_adaptor_(), stride_(stride) 00068 { 00069 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<RandomAccessIterator>)); 00070 } 00071 00075 explicit StrideIterator(RandomAccessIterator p, size_t stride=1) 00076 : StrideIterator::iterator_adaptor_(p), stride_(stride) {} 00077 00078 00082 StrideIterator(const StrideIterator& other) 00083 : StrideIterator::iterator_adaptor_(other.base()), stride_(other.stride()) 00084 {} 00085 00094 template<typename I2> 00095 StrideIterator(StrideIterator<I2> other, 00096 typename boost::enable_if_convertible<I2 00097 , RandomAccessIterator>::type* = 0 ) 00098 : StrideIterator::iterator_adaptor_(other.base()), 00099 stride_(other.stride()) {} 00100 00104 StrideIterator& operator=(const StrideIterator& rhs) 00105 { 00106 stride_ = rhs.stride(); 00107 this->base_reference() = rhs.base(); 00108 return *this; 00109 } 00110 00114 inline size_t stride(void) const { return stride_; } 00115 00116 private: 00117 // to give base class access to private parts 00118 friend class boost::iterator_core_access; 00119 00120 size_t stride_; 00121 00122 //typedef typename StrideIterator::iterator_adaptor_::difference_type 00123 typedef typename StrideIterator::iterator_adaptor_::difference_type 00124 difference_t; 00125 00126 void advance(typename super_t::difference_type n) 00127 { this->base_reference() += stride_*n; } 00128 00129 void decrement(void) { this->base_reference()-=stride_; } 00130 00131 template <class OtherIterator> 00132 typename super_t::difference_type 00133 distance_to(const StrideIterator<OtherIterator>& other) const 00134 { 00135 // casting to int to avoid loss of sign in numerator 00136 return (other.base() - this->base() )/static_cast<int>(stride_); 00137 } 00138 00139 void increment(void) { this->base_reference()+=stride_; } 00140 }; 00141 00142 }}} // of namespace utility, yat, and theplu 00143 00144 #endif