PageRenderTime 68ms CodeModel.GetById 18ms app.highlight 45ms RepoModel.GetById 2ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/range/adaptor/strided.hpp

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