1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2014, Oracle and/or its affiliates.
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
11 #ifndef BOOST_TEST_MODULE
12 #define BOOST_TEST_MODULE test_flatten_iterator
15 #include <boost/test/included/unit_test.hpp>
27 #include <boost/core/ignore_unused.hpp>
28 #include <boost/mpl/if.hpp>
29 #include <boost/type_traits/is_const.hpp>
30 #include <boost/assign/std/vector.hpp>
31 #include <boost/assign/std/list.hpp>
32 #include <boost/assign/std/set.hpp>
34 #include "test_iterator_common.hpp"
36 #include <boost/geometry/iterators/flatten_iterator.hpp>
38 using namespace boost::assign;
41 template <typename InnerContainer>
44 typedef typename boost::mpl::if_
46 typename boost::is_const<InnerContainer>::type,
47 typename InnerContainer::const_iterator,
48 typename InnerContainer::iterator
51 static inline return_type apply(InnerContainer& inner)
58 template <typename InnerContainer>
61 typedef typename boost::mpl::if_
63 typename boost::is_const<InnerContainer>::type,
64 typename InnerContainer::const_iterator,
65 typename InnerContainer::iterator
68 static inline return_type apply(InnerContainer& inner)
75 template <typename NestedContainer>
76 inline std::size_t number_of_elements(NestedContainer const& c)
78 std::size_t num_elements(0);
79 for (typename NestedContainer::const_iterator outer = c.begin();
80 outer != c.end(); ++outer)
82 num_elements += outer->size();
88 struct test_flatten_iterator
92 typename FlattenIterator,
93 typename ConstFlattenIterator,
94 typename NestedContainer
97 void test_using_max_element(FlattenIterator first,
98 FlattenIterator beyond,
99 ConstFlattenIterator const_first,
100 ConstFlattenIterator const_beyond,
101 NestedContainer const& c)
103 typedef typename std::iterator_traits
106 >::value_type value_type;
108 typedef typename NestedContainer::const_iterator const_outer_iterator;
109 typedef typename NestedContainer::value_type inner_container;
110 typedef typename inner_container::const_iterator const_inner_iterator;
112 if ( first == beyond )
117 FlattenIterator it_max = std::max_element(first, beyond);
118 ConstFlattenIterator const_it_max =
119 std::max_element(const_first, const_beyond);
121 BOOST_CHECK( it_max == const_it_max );
122 BOOST_CHECK( *it_max == *const_it_max );
124 value_type old_value = *const_first;
125 value_type new_value = *it_max + 1;
127 *first = *it_max + 1;
128 const_outer_iterator outer = c.begin();
129 while ( outer->begin() == outer->end() )
133 const_inner_iterator inner = outer->begin();
135 BOOST_CHECK( *inner == new_value );
137 #ifdef BOOST_GEOMETRY_TEST_DEBUG
138 std::cout << std::endl;
139 std::cout << "modified 1st element of 1st non-empty "
140 << "inner container:" << std::endl;
141 print_nested_container(std::cout, c.begin(), c.end(), "nested :")
143 print_container(std::cout, first, beyond, "flattened:") << std::endl;
147 BOOST_CHECK( *inner == old_value );
150 template <typename NestedContainer>
151 static inline void apply(NestedContainer& c,
152 std::string const& case_id,
153 std::string const& container_id)
155 boost::ignore_unused(case_id, container_id);
157 #ifdef BOOST_GEOMETRY_TEST_DEBUG
158 std::stringstream sstream;
159 sstream << case_id << " [" << container_id << "]";
161 std::cout << "case id: " << sstream.str() << std::endl;
163 typedef typename NestedContainer::const_iterator const_outer_iterator;
164 typedef typename NestedContainer::iterator outer_iterator;
165 typedef typename NestedContainer::value_type inner_container;
167 typedef typename inner_container::const_iterator const_inner_iterator;
168 typedef typename inner_container::iterator inner_iterator;
170 typedef boost::geometry::flatten_iterator
172 const_outer_iterator,
173 const_inner_iterator,
174 typename inner_container::value_type const,
175 access_begin<inner_container const>,
176 access_end<inner_container const>
177 > const_flatten_iterator;
179 typedef boost::geometry::flatten_iterator
183 typename inner_container::value_type,
184 access_begin<inner_container>,
185 access_end<inner_container>
188 typedef typename std::iterator_traits
191 >::value_type value_type;
193 flatten_iterator begin(c.begin(), c.end());
194 flatten_iterator end(c.end());
195 const_flatten_iterator const_begin(begin);
196 const_flatten_iterator const_end(end);
200 // test copying, dereferencing and element equality
201 std::vector<value_type> combined;
202 for (const_outer_iterator outer = c.begin();
203 outer != c.end(); ++outer)
205 std::copy(outer->begin(), outer->end(),
206 std::back_inserter(combined));
208 test_equality(begin, end, combined);
209 test_equality(const_begin, const_end, combined);
212 std::copy(begin, end, std::back_inserter(combined));
213 test_equality(begin, end, combined);
214 test_equality(const_begin, const_end, combined);
217 std::copy(const_begin, const_end, std::back_inserter(combined));
218 test_equality(begin, end, combined);
219 test_equality(const_begin, const_end, combined);
221 // test sizes (and std::distance)
222 test_size(begin, end, combined);
223 test_size(const_begin, const_end, combined);
225 #ifdef BOOST_GEOMETRY_TEST_DEBUG
226 print_nested_container(std::cout, c.begin(), c.end(), "nested :")
228 print_container(std::cout, begin, end, "flattened :")
233 std::cout << "min element: "
234 << *std::min_element(begin, end)
236 std::cout << "max element: "
237 << *std::max_element(const_begin, const_end)
242 // perform reversals (std::reverse)
243 test_using_reverse(begin, end, combined);
245 // test std::max_element, dereferencing and value assigment
246 test_using_max_element(begin, end, const_begin, const_end, c);
248 // test std::count_if / std::remove_if
249 test_using_remove_if(begin, end, combined);
250 #ifdef BOOST_GEOMETRY_TEST_DEBUG
251 std::cout << "====================" << std::endl << std::endl;
258 // the actual test cases -- START
259 template <int CaseNumber>
260 struct test_case_per_container;
263 struct test_case_per_container<0>
265 template <typename NestedContainer>
266 static inline void apply(std::string const& case_id,
267 std::string const& container_id)
270 test_flatten_iterator::apply(c, case_id, container_id);
275 struct test_case_per_container<1>
277 template <typename NestedContainer>
278 static inline void apply(std::string const& case_id,
279 std::string const& container_id)
282 for (int i = 0; i < 5; ++i)
284 c += typename NestedContainer::value_type();
286 test_flatten_iterator::apply(c, case_id, container_id);
291 struct test_case_per_container<2>
293 template <typename NestedContainer>
294 static inline void apply(std::string const& case_id,
295 std::string const& container_id)
298 typename NestedContainer::value_type ic[4];
304 c += ic[0],ic[1],ic[2],ic[3];
306 test_flatten_iterator::apply(c, case_id, container_id);
311 struct test_case_per_container<3>
313 template <typename NestedContainer>
314 static inline void apply(std::string const& case_id,
315 std::string const& container_id)
318 typename NestedContainer::value_type ic[20];
325 for (std::size_t i = 0; i < 20; ++i)
330 test_flatten_iterator::apply(c, case_id, container_id);
333 // the actual test cases -- END
337 template <int CaseNumber>
338 inline void test_case_all_containers(std::string const& case_id)
340 typedef typename std::vector<std::vector<int> > VV;
341 typedef typename std::vector<std::list<int> > VL;
342 typedef typename std::list<std::vector<int> > LV;
343 typedef typename std::list<std::list<int> > LL;
345 #ifdef BOOST_GEOMETRY_TEST_DEBUG
346 std::cout << std::endl << std::endl;
348 test_case_per_container<CaseNumber>::template apply<VV>(case_id, "VV");
349 test_case_per_container<CaseNumber>::template apply<VL>(case_id, "VL");
350 test_case_per_container<CaseNumber>::template apply<LV>(case_id, "LV");
351 test_case_per_container<CaseNumber>::template apply<LL>(case_id, "LL");
353 #ifdef BOOST_GEOMETRY_TEST_DEBUG
354 std::cout << std::endl;
355 std::cout << "********************************************************"
356 << std::endl << std::endl;
362 BOOST_AUTO_TEST_CASE( test_flatten_iterator_all )
364 test_case_all_containers<0>("empty");
365 test_case_all_containers<1>("case1");
366 test_case_all_containers<2>("case2");
367 test_case_all_containers<3>("case3");