1 | // Boost.Range library |
2 | // |
3 | // Copyright Neil Groves 2014. 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 | // For more information, see http://www.boost.org/libs/range/ |
9 | // |
10 | |
11 | #include <boost/detail/workaround.hpp> |
12 | #include <boost/range/iterator_range_core.hpp> |
13 | #include <boost/cstdint.hpp> |
14 | |
15 | #include <boost/test/test_tools.hpp> |
16 | #include <boost/test/unit_test.hpp> |
17 | |
18 | #include <vector> |
19 | |
20 | namespace boost_range_test |
21 | { |
22 | namespace |
23 | { |
24 | |
25 | class single_pass_iterator |
26 | : public boost::iterator_facade< |
27 | single_pass_iterator, |
28 | boost::int32_t, |
29 | boost::single_pass_traversal_tag, |
30 | const boost::int32_t& |
31 | > |
32 | { |
33 | friend class boost::iterator_core_access; |
34 | |
35 | typedef std::vector<boost::int32_t>::const_iterator iterator_t; |
36 | |
37 | public: |
38 | single_pass_iterator() { } |
39 | |
40 | explicit single_pass_iterator(iterator_t it) |
41 | : m_it(it) |
42 | { |
43 | } |
44 | |
45 | private: |
46 | void increment() |
47 | { |
48 | ++m_it; |
49 | } |
50 | |
51 | bool equal(single_pass_iterator other) const |
52 | { |
53 | return m_it == other.m_it; |
54 | } |
55 | |
56 | reference dereference() const |
57 | { |
58 | return *m_it; |
59 | } |
60 | |
61 | iterator_t m_it; |
62 | }; |
63 | |
64 | class bidirectional_iterator |
65 | : public boost::iterator_facade< |
66 | bidirectional_iterator, |
67 | boost::int32_t, |
68 | boost::bidirectional_traversal_tag, |
69 | const boost::int32_t& |
70 | > |
71 | { |
72 | friend class boost::iterator_core_access; |
73 | |
74 | typedef std::vector<boost::int32_t>::const_iterator iterator_t; |
75 | |
76 | public: |
77 | bidirectional_iterator() { } |
78 | |
79 | explicit bidirectional_iterator(iterator_t it) |
80 | : m_it(it) |
81 | { |
82 | } |
83 | |
84 | private: |
85 | void increment() |
86 | { |
87 | ++m_it; |
88 | } |
89 | |
90 | void decrement() |
91 | { |
92 | --m_it; |
93 | } |
94 | |
95 | bool equal(bidirectional_iterator other) const |
96 | { |
97 | return m_it == other.m_it; |
98 | } |
99 | |
100 | reference dereference() const |
101 | { |
102 | return *m_it; |
103 | } |
104 | |
105 | iterator_t m_it; |
106 | }; |
107 | |
108 | template<typename SinglePassRange> |
109 | boost::iterator_range<single_pass_iterator> |
110 | single_pass_range(const SinglePassRange& rng) |
111 | { |
112 | return boost::iterator_range<single_pass_iterator>( |
113 | single_pass_iterator(boost::begin(rng)), |
114 | single_pass_iterator(boost::end(rng))); |
115 | } |
116 | |
117 | template<typename BidirectionalRange> |
118 | boost::iterator_range<bidirectional_iterator> |
119 | bidirectional_range(const BidirectionalRange& rng) |
120 | { |
121 | return boost::iterator_range<bidirectional_iterator>( |
122 | bidirectional_iterator(boost::begin(rng)), |
123 | bidirectional_iterator(boost::end(rng))); |
124 | } |
125 | |
126 | void test_drop_front() |
127 | { |
128 | std::vector<boost::int32_t> v; |
129 | std::vector<boost::int32_t> ref_output; |
130 | |
131 | for (boost::int32_t i = 0; i < 10; ++i) |
132 | { |
133 | v.push_back(x: i); |
134 | ref_output.push_back(x: i); |
135 | } |
136 | |
137 | boost::iterator_range<single_pass_iterator> rng = single_pass_range(rng: v); |
138 | |
139 | BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), |
140 | ref_output.begin(), ref_output.end()); |
141 | |
142 | rng.drop_front(); |
143 | |
144 | ref_output.erase(position: ref_output.begin()); |
145 | |
146 | BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), |
147 | ref_output.begin(), ref_output.end()); |
148 | |
149 | rng.drop_front(n: 5); |
150 | |
151 | ref_output.erase(first: ref_output.begin(), last: ref_output.begin() + 5); |
152 | |
153 | BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), |
154 | ref_output.begin(), ref_output.end()); |
155 | } |
156 | |
157 | void test_drop_back() |
158 | { |
159 | std::vector<boost::int32_t> v; |
160 | std::vector<boost::int32_t> ref_output; |
161 | |
162 | for (boost::int32_t i = 0; i < 10; ++i) |
163 | { |
164 | v.push_back(x: i); |
165 | ref_output.push_back(x: i); |
166 | } |
167 | |
168 | boost::iterator_range<bidirectional_iterator> rng = bidirectional_range(rng: v); |
169 | |
170 | BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), |
171 | ref_output.begin(), ref_output.end()); |
172 | |
173 | rng.drop_back(); |
174 | |
175 | ref_output.pop_back(); |
176 | |
177 | BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), |
178 | ref_output.begin(), ref_output.end()); |
179 | |
180 | rng.drop_back(n: 5); |
181 | |
182 | ref_output.erase(first: ref_output.end() - 5, last: ref_output.end()); |
183 | |
184 | BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), |
185 | ref_output.begin(), ref_output.end()); |
186 | } |
187 | |
188 | } // anonymous namespace |
189 | } // namespace boost_range_test |
190 | |
191 | boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) |
192 | { |
193 | boost::unit_test::test_suite* test = |
194 | BOOST_TEST_SUITE("Boost.Range iterator_range drop functions" ); |
195 | |
196 | test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_front)); |
197 | test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_back)); |
198 | |
199 | return test; |
200 | } |
201 | |