• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
single_pass_iterator()38     single_pass_iterator() { }
39 
single_pass_iterator(iterator_t it)40     explicit single_pass_iterator(iterator_t it)
41         : m_it(it)
42     {
43     }
44 
45 private:
increment()46     void increment()
47     {
48         ++m_it;
49     }
50 
equal(single_pass_iterator other) const51     bool equal(single_pass_iterator other) const
52     {
53         return m_it == other.m_it;
54     }
55 
dereference() const56     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:
bidirectional_iterator()77     bidirectional_iterator() { }
78 
bidirectional_iterator(iterator_t it)79     explicit bidirectional_iterator(iterator_t it)
80         : m_it(it)
81     {
82     }
83 
84 private:
increment()85     void increment()
86     {
87         ++m_it;
88     }
89 
decrement()90     void decrement()
91     {
92         --m_it;
93     }
94 
equal(bidirectional_iterator other) const95     bool equal(bidirectional_iterator other) const
96     {
97         return m_it == other.m_it;
98     }
99 
dereference() const100     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>
single_pass_range(const SinglePassRange & rng)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>
bidirectional_range(const BidirectionalRange & rng)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 
test_drop_front()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(i);
134         ref_output.push_back(i);
135     }
136 
137     boost::iterator_range<single_pass_iterator> rng = single_pass_range(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(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(5);
150 
151     ref_output.erase(ref_output.begin(), ref_output.begin() + 5);
152 
153     BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
154                                   ref_output.begin(), ref_output.end());
155 }
156 
test_drop_back()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(i);
165         ref_output.push_back(i);
166     }
167 
168     boost::iterator_range<bidirectional_iterator> rng = bidirectional_range(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(5);
181 
182     ref_output.erase(ref_output.end() - 5, 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 
init_unit_test_suite(int argc,char * argv[])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