1 // Boost.Geometry
2 // Unit Test
3
4 // Copyright (c) 2014-2015 Oracle and/or its affiliates.
5
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7
8 // Use, modification and distribution is subject to the Boost Software License,
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11
12
13 #include <geometry_test_common.hpp>
14
15 #include <iterator>
16 #include <vector>
17
18 #include <boost/range/iterator_range.hpp>
19
20 #include <boost/geometry/util/range.hpp>
21
22 namespace bgt {
23
24 template <bool MutableIterator>
25 struct beginner
26 {
27 template <typename Range>
28 typename boost::range_iterator<Range>::type
operator ()bgt::beginner29 operator()(Range & rng)
30 {
31 return boost::begin(rng);
32 }
33 };
34 template <>
35 struct beginner<false>
36 {
37 template <typename Range>
38 typename boost::range_iterator<Range const>::type
operator ()bgt::beginner39 operator()(Range & rng)
40 {
41 return boost::const_begin(rng);
42 }
43 };
44
45 template <bool MutableIterator>
46 struct ender
47 {
48 template <typename Range>
49 typename boost::range_iterator<Range>::type
operator ()bgt::ender50 operator()(Range & rng)
51 {
52 return boost::end(rng);
53 }
54 };
55 template <>
56 struct ender<false>
57 {
58 template <typename Range>
59 typename boost::range_iterator<Range const>::type
operator ()bgt::ender60 operator()(Range & rng)
61 {
62 return boost::const_end(rng);
63 }
64 };
65
66 struct NonMovable
67 {
NonMovablebgt::NonMovable68 NonMovable(int ii = 0) : i(ii) {}
NonMovablebgt::NonMovable69 NonMovable(NonMovable const& ii) : i(ii.i) {}
operator =bgt::NonMovable70 NonMovable & operator=(NonMovable const& ii) { i = ii.i; return *this; }
operator ==bgt::NonMovable71 bool operator==(NonMovable const& ii) const { return i == ii.i; }
72 int i;
73 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
74 private:
75 NonMovable(NonMovable && ii);
76 NonMovable & operator=(NonMovable && ii);
77 #endif
78 };
79
80 struct CopyableAndMovable
81 {
CopyableAndMovablebgt::CopyableAndMovable82 CopyableAndMovable(int ii = 0) : i(ii) {}
CopyableAndMovablebgt::CopyableAndMovable83 CopyableAndMovable(CopyableAndMovable const& ii) : i(ii.i) {}
operator =bgt::CopyableAndMovable84 CopyableAndMovable & operator=(CopyableAndMovable const& ii) { i = ii.i; return *this; }
operator ==bgt::CopyableAndMovable85 bool operator==(CopyableAndMovable const& ii) const { return i == ii.i; }
86 int i;
87 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
CopyableAndMovablebgt::CopyableAndMovable88 CopyableAndMovable(CopyableAndMovable && ii) : i(std::move(ii.i)) {}
operator =bgt::CopyableAndMovable89 CopyableAndMovable & operator=(CopyableAndMovable && ii) { i = std::move(ii.i); return *this; }
90 #endif
91 };
92
93 } // namespace bgt
94
95 namespace bgr = bg::range;
96
97 template <typename T, bool MutableIterator>
test_all()98 void test_all()
99 {
100 bgt::beginner<MutableIterator> begin;
101 bgt::ender<MutableIterator> end;
102
103 std::vector<T> v;
104 for (int i = 0 ; i < 20 ; ++i)
105 {
106 bgr::push_back(v, i);
107 }
108
109 for (int i = 0 ; i < 20 ; ++i)
110 {
111 BOOST_CHECK(bgr::at(v, i) == i);
112 }
113
114 {
115 std::vector<T> w;
116 std::copy(v.begin(), v.end(), bgr::back_inserter(w));
117 BOOST_CHECK(v.size() == w.size() && std::equal(v.begin(), v.end(), w.begin()));
118 }
119
120 BOOST_CHECK(bgr::front(v) == 0);
121 BOOST_CHECK(bgr::back(v) == 19);
122
123 BOOST_CHECK(boost::size(v) == 20); // [0,19]
124 bgr::resize(v, 15);
125 BOOST_CHECK(boost::size(v) == 15); // [0,14]
126 BOOST_CHECK(bgr::back(v) == 14);
127
128 bgr::pop_back(v);
129 BOOST_CHECK(boost::size(v) == 14); // [0,13]
130 BOOST_CHECK(bgr::back(v) == 13);
131
132 typename std::vector<T>::iterator
133 it = bgr::erase(v, end(v) - 1);
134 BOOST_CHECK(boost::size(v) == 13); // [0,12]
135 BOOST_CHECK(bgr::back(v) == 12);
136 BOOST_CHECK(it == end(v));
137
138 it = bgr::erase(v, end(v) - 3, end(v));
139 BOOST_CHECK(boost::size(v) == 10); // [0,9]
140 BOOST_CHECK(bgr::back(v) == 9);
141 BOOST_CHECK(it == end(v));
142
143 it = bgr::erase(v, begin(v) + 2);
144 BOOST_CHECK(boost::size(v) == 9); // {0,1,3..9}
145 BOOST_CHECK(bgr::at(v, 1) == 1);
146 BOOST_CHECK(bgr::at(v, 2) == 3);
147 BOOST_CHECK(bgr::back(v) == 9);
148 BOOST_CHECK(it == bgr::pos(v, 2));
149
150 it = bgr::erase(v, begin(v) + 2, begin(v) + 2);
151 BOOST_CHECK(boost::size(v) == 9); // {0,1,3..9}
152 BOOST_CHECK(bgr::at(v, 1) == 1);
153 BOOST_CHECK(bgr::at(v, 2) == 3);
154 BOOST_CHECK(bgr::back(v) == 9);
155 BOOST_CHECK(it == bgr::pos(v, 2));
156
157 it = bgr::erase(v, begin(v) + 2, begin(v) + 5);
158 BOOST_CHECK(boost::size(v) == 6); // {0,1,6..9}
159 BOOST_CHECK(bgr::at(v, 1) == 1);
160 BOOST_CHECK(bgr::at(v, 2) == 6);
161 BOOST_CHECK(bgr::back(v) == 9);
162 BOOST_CHECK(it == bgr::pos(v, 2));
163
164 it = bgr::erase(v, begin(v));
165 BOOST_CHECK(boost::size(v) == 5); // {1,6..9}
166 BOOST_CHECK(bgr::at(v, 0) == 1);
167 BOOST_CHECK(bgr::at(v, 1) == 6);
168 BOOST_CHECK(bgr::back(v) == 9);
169 BOOST_CHECK(it == bgr::pos(v, 0));
170
171 it = bgr::erase(v, begin(v), begin(v) + 3);
172 BOOST_CHECK(boost::size(v) == 2); // {8,9}
173 BOOST_CHECK(bgr::at(v, 0) == 8);
174 BOOST_CHECK(bgr::at(v, 1) == 9);
175 BOOST_CHECK(bgr::back(v) == 9);
176 BOOST_CHECK(it == bgr::pos(v, 0));
177
178 it = bgr::erase(v, begin(v), end(v));
179 BOOST_CHECK(boost::size(v) == 0);
180 BOOST_CHECK(it == end(v));
181 }
182
test_detail()183 void test_detail()
184 {
185 int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
186 bgr::detail::copy_or_move(arr + 1, arr + 10, arr);
187 BOOST_CHECK(arr[0] == 1);
188
189 std::vector<int> v(10, 0);
190 bgr::detail::copy_or_move(v.begin() + 1, v.begin() + 10, v.begin());
191 BOOST_CHECK(boost::size(v) == 10);
192 bgr::erase(v, v.begin() + 1);
193 BOOST_CHECK(boost::size(v) == 9);
194
195 bgt::NonMovable * arr2[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
196 bgt::NonMovable foo;
197 arr2[1] = &foo;
198 bgr::detail::copy_or_move(arr2 + 1, arr2 + 10, arr2);
199 BOOST_CHECK(arr2[0] == &foo);
200
201 // Storing pointers in a std::vector is not possible in MinGW C++98
202 #if __cplusplus >= 201103L
203 std::vector<bgt::NonMovable*> v2(10, (bgt::NonMovable*)NULL);
204 bgr::detail::copy_or_move(v2.begin() + 1, v2.begin() + 10, v2.begin());
205 BOOST_CHECK(boost::size(v2) == 10);
206 bgr::erase(v2, v2.begin() + 1);
207 BOOST_CHECK(boost::size(v2) == 9);
208 #endif
209 }
210
211 template <class Iterator>
test_pointers()212 void test_pointers()
213 {
214 int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
215
216 boost::iterator_range<Iterator> r1(arr, arr + 10);
217 std::pair<Iterator, Iterator> r2(arr, arr + 10);
218
219 BOOST_CHECK(bgr::front(r1) == 0);
220 BOOST_CHECK(bgr::front(r2) == 0);
221 BOOST_CHECK(bgr::back(r1) == 9);
222 BOOST_CHECK(bgr::back(r2) == 9);
223 BOOST_CHECK(bgr::at(r1, 5) == 5);
224 BOOST_CHECK(bgr::at(r2, 5) == 5);
225 }
226
test_main(int,char * [])227 int test_main(int, char* [])
228 {
229 test_all<int, true>();
230 test_all<int, false>();
231 // Storing non-movable elements in a std::vector is not possible in some implementations of STD lib
232 #ifdef BOOST_GEOMETRY_TEST_NONMOVABLE_ELEMENTS
233 test_all<bgt::NonMovable, true>();
234 test_all<bgt::NonMovable, false>();
235 #endif
236 test_all<bgt::CopyableAndMovable, true>();
237 test_all<bgt::CopyableAndMovable, false>();
238
239 test_detail();
240 test_pointers<int*>();
241 test_pointers<int const*>();
242
243 return 0;
244 }
245