Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/range/irange.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Boost.Range library | |
2 // | |
3 // Copyright Neil Groves 2010. 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_IRANGE_HPP_INCLUDED | |
12 #define BOOST_RANGE_IRANGE_HPP_INCLUDED | |
13 | |
14 #include <boost/assert.hpp> | |
15 #include <boost/iterator/iterator_facade.hpp> | |
16 #include <boost/range/iterator_range.hpp> | |
17 | |
18 namespace boost | |
19 { | |
20 namespace range_detail | |
21 { | |
22 // integer_iterator is an iterator over an integer sequence that | |
23 // is bounded only by the limits of the underlying integer | |
24 // representation. | |
25 // | |
26 // This is useful for implementing the irange(first, last) | |
27 // function. | |
28 // | |
29 // Note: | |
30 // This use of this iterator and irange is appreciably less | |
31 // performant than the corresponding hand-written integer | |
32 // loop on many compilers. | |
33 template<typename Integer> | |
34 class integer_iterator | |
35 : public boost::iterator_facade< | |
36 integer_iterator<Integer>, | |
37 Integer, | |
38 boost::random_access_traversal_tag, | |
39 Integer, | |
40 std::ptrdiff_t | |
41 > | |
42 { | |
43 typedef boost::iterator_facade< | |
44 integer_iterator<Integer>, | |
45 Integer, | |
46 boost::random_access_traversal_tag, | |
47 Integer, | |
48 std::ptrdiff_t | |
49 > base_t; | |
50 public: | |
51 typedef typename base_t::value_type value_type; | |
52 typedef typename base_t::difference_type difference_type; | |
53 typedef typename base_t::reference reference; | |
54 | |
55 integer_iterator() : m_value() {} | |
56 explicit integer_iterator(value_type x) : m_value(x) {} | |
57 | |
58 private: | |
59 void increment() | |
60 { | |
61 ++m_value; | |
62 } | |
63 | |
64 void decrement() | |
65 { | |
66 --m_value; | |
67 } | |
68 | |
69 void advance(difference_type offset) | |
70 { | |
71 m_value += offset; | |
72 } | |
73 | |
74 difference_type distance_to(const integer_iterator& other) const | |
75 { | |
76 return other.m_value - m_value; | |
77 } | |
78 | |
79 bool equal(const integer_iterator& other) const | |
80 { | |
81 return m_value == other.m_value; | |
82 } | |
83 | |
84 reference dereference() const | |
85 { | |
86 return m_value; | |
87 } | |
88 | |
89 friend class ::boost::iterator_core_access; | |
90 value_type m_value; | |
91 }; | |
92 | |
93 // integer_iterator_with_step is similar in nature to the | |
94 // integer_iterator but provides the ability to 'move' in | |
95 // a number of steps specified at construction time. | |
96 // | |
97 // The three variable implementation provides the best guarantees | |
98 // of loop termination upon various combinations of input. | |
99 // | |
100 // While this design is less performant than some less | |
101 // safe alternatives, the use of ranges and iterators to | |
102 // perform counting will never be optimal anyhow, hence | |
103 // if optimal performance is desired a hand-coded loop | |
104 // is the solution. | |
105 template<typename Integer> | |
106 class integer_iterator_with_step | |
107 : public boost::iterator_facade< | |
108 integer_iterator_with_step<Integer>, | |
109 Integer, | |
110 boost::random_access_traversal_tag, | |
111 Integer, | |
112 std::ptrdiff_t | |
113 > | |
114 { | |
115 typedef boost::iterator_facade< | |
116 integer_iterator_with_step<Integer>, | |
117 Integer, | |
118 boost::random_access_traversal_tag, | |
119 Integer, | |
120 std::ptrdiff_t | |
121 > base_t; | |
122 public: | |
123 typedef typename base_t::value_type value_type; | |
124 typedef typename base_t::difference_type difference_type; | |
125 typedef typename base_t::reference reference; | |
126 | |
127 integer_iterator_with_step(value_type first, difference_type step, value_type step_size) | |
128 : m_first(first) | |
129 , m_step(step) | |
130 , m_step_size(step_size) | |
131 { | |
132 } | |
133 | |
134 private: | |
135 void increment() | |
136 { | |
137 ++m_step; | |
138 } | |
139 | |
140 void decrement() | |
141 { | |
142 --m_step; | |
143 } | |
144 | |
145 void advance(difference_type offset) | |
146 { | |
147 m_step += offset; | |
148 } | |
149 | |
150 difference_type distance_to(const integer_iterator_with_step& other) const | |
151 { | |
152 return other.m_step - m_step; | |
153 } | |
154 | |
155 bool equal(const integer_iterator_with_step& other) const | |
156 { | |
157 return m_step == other.m_step; | |
158 } | |
159 | |
160 reference dereference() const | |
161 { | |
162 return m_first + (m_step * m_step_size); | |
163 } | |
164 | |
165 friend class ::boost::iterator_core_access; | |
166 value_type m_first; | |
167 value_type m_step; | |
168 difference_type m_step_size; | |
169 }; | |
170 | |
171 } // namespace range_detail | |
172 | |
173 template<typename Integer> | |
174 class integer_range | |
175 : public iterator_range< range_detail::integer_iterator<Integer> > | |
176 { | |
177 typedef range_detail::integer_iterator<Integer> iterator_t; | |
178 typedef iterator_range<iterator_t> base_t; | |
179 public: | |
180 integer_range(Integer first, Integer last) | |
181 : base_t(iterator_t(first), iterator_t(last)) | |
182 { | |
183 } | |
184 }; | |
185 | |
186 template<typename Integer> | |
187 class strided_integer_range | |
188 : public iterator_range< range_detail::integer_iterator_with_step<Integer> > | |
189 { | |
190 typedef range_detail::integer_iterator_with_step<Integer> iterator_t; | |
191 typedef iterator_range<iterator_t> base_t; | |
192 public: | |
193 template<typename Iterator> | |
194 strided_integer_range(Iterator first, Iterator last) | |
195 : base_t(first, last) | |
196 { | |
197 } | |
198 }; | |
199 | |
200 template<typename Integer> | |
201 integer_range<Integer> | |
202 irange(Integer first, Integer last) | |
203 { | |
204 BOOST_ASSERT( first <= last ); | |
205 return integer_range<Integer>(first, last); | |
206 } | |
207 | |
208 template<typename Integer, typename StepSize> | |
209 strided_integer_range<Integer> | |
210 irange(Integer first, Integer last, StepSize step_size) | |
211 { | |
212 BOOST_ASSERT( step_size != 0 ); | |
213 BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) ); | |
214 | |
215 typedef typename range_detail::integer_iterator_with_step<Integer> iterator_t; | |
216 | |
217 const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(step_size >= 0 ? step_size : -step_size); | |
218 const Integer l = step_size >= 0 ? last : first; | |
219 const Integer f = step_size >= 0 ? first : last; | |
220 const std::ptrdiff_t num_steps = (l - f) / sz + ((l - f) % sz ? 1 : 0); | |
221 BOOST_ASSERT(num_steps >= 0); | |
222 | |
223 return strided_integer_range<Integer>( | |
224 iterator_t(first, 0, step_size), | |
225 iterator_t(first, num_steps, step_size)); | |
226 } | |
227 | |
228 } // namespace boost | |
229 | |
230 #endif // include guard |