1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2014, Oracle and/or its affiliates.
5
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10
11 #ifndef BOOST_TEST_MODULE
12 #define BOOST_TEST_MODULE test_concatenate_iterator
13 #endif
14
15 #include <boost/test/included/unit_test.hpp>
16
17 #include <cstddef>
18 #include <iostream>
19 #include <sstream>
20 #include <string>
21 #include <algorithm>
22 #include <iterator>
23
24 #include <vector>
25 #include <list>
26
27 #include <boost/assign/std/vector.hpp>
28 #include <boost/assign/std/list.hpp>
29
30 #include <boost/core/ignore_unused.hpp>
31
32 #include "test_iterator_common.hpp"
33
34 #include <boost/geometry/iterators/concatenate_iterator.hpp>
35
36 using namespace boost::assign;
37
38
39 struct test_concatenate_iterator
40 {
41 template
42 <
43 typename ConcatenateIterator,
44 typename ConstConcatenateIterator,
45 typename Container
46 >
47 static inline
test_using_max_elementtest_concatenate_iterator48 void test_using_max_element(ConcatenateIterator first,
49 ConcatenateIterator beyond,
50 ConstConcatenateIterator const_first,
51 ConstConcatenateIterator const_beyond,
52 Container const& c,
53 std::size_t other_size,
54 bool second_container)
55 {
56 typedef typename std::iterator_traits
57 <
58 ConcatenateIterator
59 >::value_type value_type;
60
61 if ( c.size() == 0 )
62 {
63 return;
64 }
65
66 ConcatenateIterator c_first = first;
67 if ( second_container )
68 {
69 std::size_t counter(0);
70 while ( counter != other_size )
71 {
72 ++counter;
73 c_first++;
74 }
75 }
76
77 ConcatenateIterator it_max = std::max_element(first, beyond);
78 ConstConcatenateIterator const_it_max =
79 std::max_element(const_first, const_beyond);
80
81 BOOST_CHECK( it_max == const_it_max );
82 BOOST_CHECK( *it_max == *const_it_max );
83
84 value_type old_value = *c_first;
85 value_type new_value = *it_max + 1;
86
87 *c_first = *it_max + 1;
88 BOOST_CHECK( *c.begin() == new_value );
89
90 #ifdef BOOST_GEOMETRY_TEST_DEBUG
91 std::cout << std::endl;
92 std::cout << "modified element of ";
93 std::cout << (second_container ? "2nd" : "1st");
94 std::cout << " container:" << std::endl;
95 print_container(std::cout, c.begin(), c.end(),
96 (second_container ? "second :" : "first :"))
97 << std::endl;
98 print_container(std::cout, first, beyond, "combined:") << std::endl;
99 #endif
100
101 *c_first = old_value;
102 BOOST_CHECK( *c.begin() == old_value );
103 }
104
105
106 template <typename Container1, typename Container2>
applytest_concatenate_iterator107 static inline void apply(Container1& c1, Container2& c2,
108 std::string const& case_id,
109 std::string const& containers_id)
110 {
111 boost::ignore_unused(case_id, containers_id);
112
113 #ifdef BOOST_GEOMETRY_TEST_DEBUG
114 std::stringstream sstream;
115 sstream << case_id << " [" << containers_id << "]";
116
117 std::cout << "case id: " << sstream.str() << std::endl;
118 #endif
119 typedef typename Container1::const_iterator const_iterator1;
120 typedef typename Container2::const_iterator const_iterator2;
121 typedef typename Container1::iterator iterator1;
122 typedef typename Container2::iterator iterator2;
123
124 typedef boost::geometry::concatenate_iterator
125 <
126 const_iterator1, const_iterator2,
127 typename Container1::value_type const
128 > const_concat_iterator;
129
130 typedef boost::geometry::concatenate_iterator
131 <
132 iterator1, iterator2, typename Container1::value_type
133 > concat_iterator;
134
135 typedef typename std::iterator_traits
136 <
137 concat_iterator
138 >::value_type value_type;
139
140 // test constructors/assignment operators
141 concat_iterator begin(c1.begin(), c1.end(), c2.begin(), c2.begin());
142 concat_iterator end(c1.end(), c2.begin(), c2.end());
143 const_concat_iterator const_begin(begin);
144 const_concat_iterator const_end(end);
145 const_begin = begin;
146 const_end = end;
147
148 concat_iterator begin2(c1.end(), c1.end(), c2.begin(), c2.begin());
149 const_concat_iterator const_begin2(c1.end(), c1.end(),
150 c2.begin(), c2.begin());
151
152 BOOST_CHECK( c1.empty() || *begin == *c1.begin() );
153 BOOST_CHECK( c1.empty() || *const_begin == *c1.begin() );
154
155 BOOST_CHECK( c2.empty() || *begin2 == *c2.begin() );
156 BOOST_CHECK( c2.empty() || *const_begin2 == *c2.begin() );
157
158
159 // test copying, dereferencing and element equality
160 std::vector<value_type> combined;
161 std::copy(c1.begin(), c1.end(), std::back_inserter(combined));
162 std::copy(c2.begin(), c2.end(), std::back_inserter(combined));
163 test_equality(begin, end, combined);
164
165 combined.clear();
166 std::copy(begin, end, std::back_inserter(combined));
167 test_equality(begin, end, combined);
168 test_equality(const_begin, const_end, combined);
169
170 combined.clear();
171 std::copy(const_begin, const_end, std::back_inserter(combined));
172 test_equality(begin, end, combined);
173 test_equality(const_begin, const_end, combined);
174
175 // test sizes (and std::distance)
176 test_size(begin, end, combined);
177 test_size(const_begin, const_end, combined);
178
179
180 #ifdef BOOST_GEOMETRY_TEST_DEBUG
181 print_container(std::cout, c1.begin(), c1.end(), "first :")
182 << std::endl;
183 print_container(std::cout, c2.begin(), c2.end(), "second :")
184 << std::endl;
185 print_container(std::cout, begin, end, "combined:")
186 << std::endl;
187
188 if ( begin != end )
189 {
190 std::cout << "min element: "
191 << *std::min_element(begin, end)
192 << std::endl;
193 std::cout << "max element: "
194 << *std::max_element(const_begin, const_end)
195 << std::endl;
196 }
197 #endif
198
199 // perform reversals (std::reverse)
200 test_using_reverse(begin, end, combined);
201
202 // test std::max_element, dereferencing and value assigment
203 test_using_max_element(begin, end, const_begin, const_end,
204 c1, c2.size(), false);
205 test_using_max_element(begin, end, const_begin, const_end,
206 c2, c1.size(), true);
207
208 // test std::count_if / std::remove_if
209 test_using_remove_if(begin, end, combined);
210
211 #ifdef BOOST_GEOMETRY_TEST_DEBUG
212 std::cout << "====================" << std::endl << std::endl;
213 #endif
214 }
215 };
216
217
218 template <typename Container1, typename Container2>
test_concatenation_of_containers(Container1 & c1,Container2 & c2,std::string const & containers_id)219 inline void test_concatenation_of_containers(Container1& c1, Container2& c2,
220 std::string const& containers_id)
221 {
222 #ifdef BOOST_GEOMETRY_TEST_DEBUG
223 std::cout << std::endl << std::endl;
224 std::cout << "************************************" << std::endl
225 << " TESTING CONTAINERS COMBINATION: "
226 << containers_id << std::endl
227 << "************************************" << std::endl
228 << std::endl;
229 #endif
230
231 c1.clear();
232 c2.clear();
233 test_concatenate_iterator::apply(c1, c2, "empty_both", containers_id);
234
235 c2 += 10,11,12,13,14,15,16,17,18,19,20;
236 test_concatenate_iterator::apply(c1, c2, "empty_first", containers_id);
237
238 c2.clear();
239 c1 += 0,1,2,3,4,5,6;
240 test_concatenate_iterator::apply(c1, c2, "empty_second", containers_id);
241
242 c1.clear();
243 c2.clear();
244 c1 += 0,1,2,3,4,5,6;
245 c2 += 10,11,12,13,14,15,16,17,18,19,20;
246 test_concatenate_iterator::apply(c1, c2, "non_empty", containers_id);
247 }
248
249
BOOST_AUTO_TEST_CASE(test_concatenate_iterator_all)250 BOOST_AUTO_TEST_CASE( test_concatenate_iterator_all )
251 {
252 std::vector<int> v, vv;
253 std::list<int> l, ll;
254
255 test_concatenation_of_containers(v, vv, "VV");
256 test_concatenation_of_containers(v, l, "VL");
257 test_concatenation_of_containers(l, v, "LV");
258 test_concatenation_of_containers(l, ll, "LL");
259 }
260