annotate DEPENDENCIES/generic/include/boost/range/adaptor/strided.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
rev   line source
Chris@16 1 // Boost.Range library
Chris@16 2 //
Chris@16 3 // Copyright Neil Groves 2007. Use, modification and
Chris@16 4 // distribution is subject to the Boost Software License, Version
Chris@16 5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7 //
Chris@16 8 //
Chris@16 9 // For more information, see http://www.boost.org/libs/range/
Chris@16 10 //
Chris@16 11 #ifndef BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
Chris@16 12 #define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
Chris@16 13
Chris@16 14 #include <boost/range/adaptor/argument_fwd.hpp>
Chris@16 15 #include <boost/range/iterator_range.hpp>
Chris@16 16 #include <boost/iterator/iterator_adaptor.hpp>
Chris@16 17 #include <iterator>
Chris@16 18
Chris@16 19 namespace boost
Chris@16 20 {
Chris@16 21 namespace range_detail
Chris@16 22 {
Chris@16 23 // strided_iterator for wrapping a forward traversal iterator
Chris@16 24 template<class BaseIterator, class Category>
Chris@16 25 class strided_iterator
Chris@16 26 : public iterator_adaptor<
Chris@16 27 strided_iterator<BaseIterator, Category>
Chris@16 28 , BaseIterator
Chris@16 29 , use_default
Chris@16 30 , boost::forward_traversal_tag
Chris@16 31 >
Chris@16 32 {
Chris@16 33 friend class ::boost::iterator_core_access;
Chris@16 34
Chris@16 35 typedef iterator_adaptor<
Chris@16 36 strided_iterator<BaseIterator, Category>
Chris@16 37 , BaseIterator
Chris@16 38 , use_default
Chris@16 39 , boost::forward_traversal_tag
Chris@16 40 > super_t;
Chris@16 41
Chris@16 42 public:
Chris@16 43 typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
Chris@16 44 typedef BaseIterator base_iterator;
Chris@16 45
Chris@16 46 strided_iterator()
Chris@16 47 : m_last()
Chris@16 48 , m_stride()
Chris@16 49 {
Chris@16 50 }
Chris@16 51
Chris@16 52 strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride)
Chris@16 53 : super_t(it)
Chris@16 54 , m_last(last)
Chris@16 55 , m_stride(stride)
Chris@16 56 {
Chris@16 57 }
Chris@16 58
Chris@16 59 template<class OtherIterator>
Chris@16 60 strided_iterator(const strided_iterator<OtherIterator, Category>& other,
Chris@16 61 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0)
Chris@16 62 : super_t(other)
Chris@16 63 , m_last(other.base_end())
Chris@16 64 , m_stride(other.get_stride())
Chris@16 65 {
Chris@16 66 }
Chris@16 67
Chris@16 68 base_iterator base_end() const { return m_last; }
Chris@16 69 difference_type get_stride() const { return m_stride; }
Chris@16 70
Chris@16 71 private:
Chris@16 72 void increment()
Chris@16 73 {
Chris@16 74 base_iterator& it = this->base_reference();
Chris@16 75 for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i)
Chris@16 76 ++it;
Chris@16 77 }
Chris@16 78
Chris@16 79 base_iterator m_last;
Chris@16 80 difference_type m_stride;
Chris@16 81 };
Chris@16 82
Chris@16 83 // strided_iterator for wrapping a bidirectional iterator
Chris@16 84 template<class BaseIterator>
Chris@16 85 class strided_iterator<BaseIterator, bidirectional_traversal_tag>
Chris@16 86 : public iterator_adaptor<
Chris@16 87 strided_iterator<BaseIterator, bidirectional_traversal_tag>
Chris@16 88 , BaseIterator
Chris@16 89 , use_default
Chris@16 90 , bidirectional_traversal_tag
Chris@16 91 >
Chris@16 92 {
Chris@16 93 friend class ::boost::iterator_core_access;
Chris@16 94
Chris@16 95 typedef iterator_adaptor<
Chris@16 96 strided_iterator<BaseIterator, bidirectional_traversal_tag>
Chris@16 97 , BaseIterator
Chris@16 98 , use_default
Chris@16 99 , bidirectional_traversal_tag
Chris@16 100 > super_t;
Chris@16 101 public:
Chris@16 102 typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
Chris@16 103 typedef BaseIterator base_iterator;
Chris@16 104
Chris@16 105 strided_iterator()
Chris@16 106 : m_first()
Chris@16 107 , m_last()
Chris@16 108 , m_stride()
Chris@16 109 {
Chris@16 110 }
Chris@16 111
Chris@16 112 strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride)
Chris@16 113 : super_t(it)
Chris@16 114 , m_first(first)
Chris@16 115 , m_last(last)
Chris@16 116 , m_stride(stride)
Chris@16 117 {
Chris@16 118 }
Chris@16 119
Chris@16 120 template<class OtherIterator>
Chris@16 121 strided_iterator(const strided_iterator<OtherIterator, bidirectional_traversal_tag>& other,
Chris@16 122 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0)
Chris@16 123 : super_t(other.base())
Chris@16 124 , m_first(other.base_begin())
Chris@16 125 , m_last(other.base_end())
Chris@16 126 , m_stride(other.get_stride())
Chris@16 127 {
Chris@16 128 }
Chris@16 129
Chris@16 130 base_iterator base_begin() const { return m_first; }
Chris@16 131 base_iterator base_end() const { return m_last; }
Chris@16 132 difference_type get_stride() const { return m_stride; }
Chris@16 133
Chris@16 134 private:
Chris@16 135 void increment()
Chris@16 136 {
Chris@16 137 base_iterator& it = this->base_reference();
Chris@16 138 for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i)
Chris@16 139 ++it;
Chris@16 140 }
Chris@16 141
Chris@16 142 void decrement()
Chris@16 143 {
Chris@16 144 base_iterator& it = this->base_reference();
Chris@16 145 for (difference_type i = 0; (it != m_first) && (i < m_stride); ++i)
Chris@16 146 --it;
Chris@16 147 }
Chris@16 148
Chris@16 149 base_iterator m_first;
Chris@16 150 base_iterator m_last;
Chris@16 151 difference_type m_stride;
Chris@16 152 };
Chris@16 153
Chris@16 154 // strided_iterator implementation for wrapping a random access iterator
Chris@16 155 template<class BaseIterator>
Chris@16 156 class strided_iterator<BaseIterator, random_access_traversal_tag>
Chris@16 157 : public iterator_adaptor<
Chris@16 158 strided_iterator<BaseIterator, random_access_traversal_tag>
Chris@16 159 , BaseIterator
Chris@16 160 , use_default
Chris@16 161 , random_access_traversal_tag
Chris@16 162 >
Chris@16 163 {
Chris@16 164 friend class ::boost::iterator_core_access;
Chris@16 165
Chris@16 166 typedef iterator_adaptor<
Chris@16 167 strided_iterator<BaseIterator, random_access_traversal_tag>
Chris@16 168 , BaseIterator
Chris@16 169 , use_default
Chris@16 170 , random_access_traversal_tag
Chris@16 171 > super_t;
Chris@16 172 public:
Chris@16 173 typedef BOOST_DEDUCED_TYPENAME super_t::difference_type difference_type;
Chris@16 174 typedef BaseIterator base_iterator;
Chris@16 175
Chris@16 176 strided_iterator()
Chris@16 177 : m_first()
Chris@16 178 , m_last()
Chris@16 179 , m_index(0)
Chris@16 180 , m_stride()
Chris@16 181 {
Chris@16 182 }
Chris@16 183
Chris@16 184 strided_iterator(BaseIterator first, BaseIterator it, BaseIterator last, difference_type stride)
Chris@16 185 : super_t(it)
Chris@16 186 , m_first(first)
Chris@16 187 , m_last(last)
Chris@16 188 , m_index(stride ? (it - first) / stride : 0)
Chris@16 189 , m_stride(stride)
Chris@16 190 {
Chris@16 191 }
Chris@16 192
Chris@16 193 template<class OtherIterator>
Chris@16 194 strided_iterator(const strided_iterator<OtherIterator, random_access_traversal_tag>& other,
Chris@16 195 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0)
Chris@16 196 : super_t(other.base())
Chris@16 197 , m_first(other.base_begin())
Chris@16 198 , m_last(other.base_end())
Chris@16 199 , m_index(other.get_index())
Chris@16 200 , m_stride(other.get_stride())
Chris@16 201 {
Chris@16 202 }
Chris@16 203
Chris@16 204 base_iterator base_begin() const { return m_first; }
Chris@16 205 base_iterator base_end() const { return m_last; }
Chris@16 206 difference_type get_stride() const { return m_stride; }
Chris@16 207 difference_type get_index() const { return m_index; }
Chris@16 208
Chris@16 209 private:
Chris@16 210 void increment()
Chris@16 211 {
Chris@16 212 m_index += m_stride;
Chris@16 213 if (m_index < (m_last - m_first))
Chris@16 214 this->base_reference() = m_first + m_index;
Chris@16 215 else
Chris@16 216 this->base_reference() = m_last;
Chris@16 217 }
Chris@16 218
Chris@16 219 void decrement()
Chris@16 220 {
Chris@16 221 m_index -= m_stride;
Chris@16 222 if (m_index >= 0)
Chris@16 223 this->base_reference() = m_first + m_index;
Chris@16 224 else
Chris@16 225 this->base_reference() = m_first;
Chris@16 226 }
Chris@16 227
Chris@16 228 void advance(difference_type offset)
Chris@16 229 {
Chris@16 230 offset *= m_stride;
Chris@16 231 m_index += offset;
Chris@16 232 if (m_index < 0)
Chris@16 233 this->base_reference() = m_first;
Chris@16 234 else if (m_index > (m_last - m_first))
Chris@16 235 this->base_reference() = m_last;
Chris@16 236 else
Chris@16 237 this->base_reference() = m_first + m_index;
Chris@16 238 }
Chris@16 239
Chris@16 240 template<class OtherIterator>
Chris@16 241 difference_type distance_to(const strided_iterator<OtherIterator, random_access_traversal_tag>& other,
Chris@16 242 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) const
Chris@16 243 {
Chris@16 244 if (other.base() >= this->base())
Chris@16 245 return (other.base() - this->base() + (m_stride - 1)) / m_stride;
Chris@16 246 return (other.base() - this->base() - (m_stride - 1)) / m_stride;
Chris@16 247 }
Chris@16 248
Chris@16 249 bool equal(const strided_iterator& other) const
Chris@16 250 {
Chris@16 251 return this->base() == other.base();
Chris@16 252 }
Chris@16 253
Chris@16 254 private:
Chris@16 255 base_iterator m_first;
Chris@16 256 base_iterator m_last;
Chris@16 257 difference_type m_index;
Chris@16 258 difference_type m_stride;
Chris@16 259 };
Chris@16 260
Chris@16 261 template<class BaseIterator, class Difference> inline
Chris@16 262 strided_iterator<BaseIterator, BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type>
Chris@16 263 make_strided_iterator(BaseIterator first, BaseIterator it,
Chris@16 264 BaseIterator last, Difference stride)
Chris@16 265 {
Chris@16 266 BOOST_ASSERT( stride >= 0 );
Chris@16 267 typedef BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type traversal_tag;
Chris@16 268 return strided_iterator<BaseIterator, traversal_tag>(first, it, last, stride);
Chris@16 269 }
Chris@16 270
Chris@16 271 template< class Rng
Chris@16 272 , class Category = BOOST_DEDUCED_TYPENAME iterator_traversal<
Chris@16 273 BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type
Chris@16 274 >::type
Chris@16 275 >
Chris@16 276 class strided_range
Chris@16 277 : public iterator_range<
Chris@16 278 range_detail::strided_iterator<
Chris@16 279 BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type,
Chris@16 280 Category
Chris@16 281 >
Chris@16 282 >
Chris@16 283 {
Chris@16 284 typedef range_detail::strided_iterator<
Chris@16 285 BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type,
Chris@16 286 Category
Chris@16 287 > iter_type;
Chris@16 288 typedef iterator_range<iter_type> super_t;
Chris@16 289 public:
Chris@16 290 template<class Difference>
Chris@16 291 strided_range(Difference stride, Rng& rng)
Chris@16 292 : super_t(make_strided_iterator(boost::begin(rng), boost::begin(rng), boost::end(rng), stride),
Chris@16 293 make_strided_iterator(boost::begin(rng), boost::end(rng), boost::end(rng), stride))
Chris@16 294 {
Chris@16 295 BOOST_ASSERT( stride >= 0 );
Chris@16 296 }
Chris@16 297 };
Chris@16 298
Chris@16 299 template<class Difference>
Chris@16 300 class strided_holder : public holder<Difference>
Chris@16 301 {
Chris@16 302 public:
Chris@16 303 explicit strided_holder(Difference value) : holder<Difference>(value) {}
Chris@16 304 };
Chris@16 305
Chris@16 306 template<class Rng, class Difference>
Chris@16 307 inline strided_range<Rng>
Chris@16 308 operator|(Rng& rng, const strided_holder<Difference>& stride)
Chris@16 309 {
Chris@16 310 return strided_range<Rng>(stride.val, rng);
Chris@16 311 }
Chris@16 312
Chris@16 313 template<class Rng, class Difference>
Chris@16 314 inline strided_range<const Rng>
Chris@16 315 operator|(const Rng& rng, const strided_holder<Difference>& stride)
Chris@16 316 {
Chris@16 317 return strided_range<const Rng>(stride.val, rng);
Chris@16 318 }
Chris@16 319
Chris@16 320 } // namespace range_detail
Chris@16 321
Chris@16 322 using range_detail::strided_range;
Chris@16 323
Chris@16 324 namespace adaptors
Chris@16 325 {
Chris@16 326
Chris@16 327 namespace
Chris@16 328 {
Chris@16 329 const range_detail::forwarder<range_detail::strided_holder>
Chris@16 330 strided = range_detail::forwarder<range_detail::strided_holder>();
Chris@16 331 }
Chris@16 332
Chris@16 333 template<class Range, class Difference>
Chris@16 334 inline strided_range<Range>
Chris@16 335 stride(Range& rng, Difference step)
Chris@16 336 {
Chris@16 337 return strided_range<Range>(step, rng);
Chris@16 338 }
Chris@16 339
Chris@16 340 template<class Range, class Difference>
Chris@16 341 inline strided_range<const Range>
Chris@16 342 stride(const Range& rng, Difference step)
Chris@16 343 {
Chris@16 344 return strided_range<const Range>(step, rng);
Chris@16 345 }
Chris@16 346
Chris@16 347 } // namespace 'adaptors'
Chris@16 348 } // namespace 'boost'
Chris@16 349
Chris@16 350 #endif