• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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