• 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