1 /* Copyright 2016-2017 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * See http://www.boost.org/libs/poly_collection for library home page.
7 */
8
9 #include "test_insertion.hpp"
10
11 #include <algorithm>
12 #include <boost/core/lightweight_test.hpp>
13 #include <numeric>
14 #include <vector>
15 #include "any_types.hpp"
16 #include "base_types.hpp"
17 #include "function_types.hpp"
18 #include "test_utilities.hpp"
19
20 using namespace test_utilities;
21
22 template<typename PolyCollection,typename ValueFactory,typename... Types>
test_insertion()23 void test_insertion()
24 {
25 {
26 using unregistered_type=boost::poly_collection::unregistered_type;
27 using type=first_of<constraints<is_copy_constructible>,Types...>;
28
29 PolyCollection p,p2;
30 ValueFactory v;
31
32 p2.insert(v.template make<type>());
33 check_throw<unregistered_type>(
34 [&]{p.insert(*p2.begin());},
35 [&]{p.insert(p.end(),*p2.begin());},
36 [&]{p.insert(p.cend(),*p2.begin());},
37 [&]{p.insert(
38 external_iterator(p2.begin()),external_iterator(p2.end()));},
39 [&]{p.insert(
40 p.end(),
41 external_iterator(p2.begin()),external_iterator(p2.end()));},
42 [&]{p.insert(
43 p.cend(),
44 external_iterator(p2.begin()),external_iterator(p2.end()));});
45 }
46 {
47 using not_copy_constructible=
48 boost::poly_collection::not_copy_constructible;
49 using type=first_of<constraints<is_not_copy_constructible>,Types...>;
50
51 PolyCollection p,p2;
52 ValueFactory v;
53
54 p.template register_types<type>();
55 p2.insert(v.template make<type>());
56 auto p2b=external_iterator(p2.begin()),
57 p2e=external_iterator(p2.end());
58 auto p2lb=external_iterator(p2.template begin<type>()),
59 p2le=external_iterator(p2.template end<type>());
60 check_throw<not_copy_constructible>(
61 [&]{p.insert(*p2.begin());},
62 [&]{p.insert(p.end(),*p2.begin());},
63 [&]{p.insert(p.cend(),*p2.cbegin());},
64 [&]{p.insert(p.end(typeid(type)),*p2.begin());},
65 [&]{p.insert(p.cend(typeid(type)),*p2.begin());},
66 [&]{p.insert(p.template end<type>(),*p2.begin());},
67 [&]{p.insert(p.template cend<type>(),*p2.begin());},
68 [&]{p.insert(p2b,p2e);},
69 [&]{p.insert(p2lb,p2le);},
70 [&]{p.insert(p2.begin(),p2.end());},
71 [&]{p.insert(p2.begin(typeid(type)),p2.end(typeid(type)));},
72 [&]{p.insert(p2.template begin<type>(),p2.template end<type>());},
73 [&]{p.insert(p.end(),p2b,p2e);},
74 [&]{p.insert(p.end(),p2lb,p2le);},
75 [&]{p.insert(p.end(),p2.begin(),p2.end());},
76 [&]{p.insert(p.end(),p2.begin(typeid(type)),p2.end(typeid(type)));},
77 [&]{p.insert(
78 p.end(),p2.template begin<type>(),p2.template end<type>());},
79 [&]{p.insert(p.cend(),p2b,p2e);},
80 [&]{p.insert(p.cend(),p2lb,p2le);},
81 [&]{p.insert(p.cend(),p2.begin(),p2.end());},
82 [&]{p.insert(p.cend(),p2.begin(typeid(type)),p2.end(typeid(type)));},
83 [&]{p.insert(
84 p.cend(),p2.template begin<type>(),p2.template end<type>());},
85 [&]{p.insert(p.end(typeid(type)),p2b,p2e);},
86 [&]{p.insert(p.cend(typeid(type)),p2b,p2e);},
87 [&]{p.insert(p.template end<type>(),p2b,p2e);},
88 [&]{p.insert(p.template cend<type>(),p2b,p2e);});
89 }
90 {
91 PolyCollection p;
92 ValueFactory v;
93
94 fill<constraints<>,Types...>(p,v,2);
95
96 do_((BOOST_TEST(
97 is_last(
98 p,typeid(Types),
99 p.insert(constref_if_copy_constructible(v.template make<Types>())))
100 ),0)...);
101 }
102 {
103 PolyCollection p;
104 ValueFactory v;
105
106 fill<constraints<>,Types...>(p,v,2);
107
108 auto& info=p.segment_traversal().begin()->type_info();
109 do_((BOOST_TEST(
110 info==typeid(Types)?
111 is_first(
112 p,typeid(Types),
113 p.insert(
114 p.cbegin(),
115 constref_if_copy_constructible(v.template make<Types>()))):
116 is_last(
117 p,typeid(Types),
118 p.insert(
119 p.cbegin(),
120 constref_if_copy_constructible(v.template make<Types>())))
121 ),0)...);
122
123 do_((BOOST_TEST(
124 is_first(
125 p,typeid(Types),
126 p.insert(
127 p.cbegin(typeid(Types)),
128 constref_if_copy_constructible(v.template make<Types>())))
129 ),0)...);
130
131 do_((BOOST_TEST(
132 is_first<Types>(
133 p,
134 p.insert(
135 p.template cbegin<Types>(),
136 constref_if_copy_constructible(v.template make<Types>())))
137 ),0)...);
138 }
139 {
140 PolyCollection p,p2;
141 ValueFactory v;
142
143 p.template register_types<Types...>();
144 p2.template register_types<Types...>();
145 fill<
146 constraints<is_copy_constructible,is_equality_comparable>,
147 Types...
148 >(p2,v,2);
149
150 p.insert(external_iterator(p2.begin()),external_iterator(p2.end()));
151 BOOST_TEST(p==p2);
152 p.clear();
153
154 p.insert(p2.begin(),p2.end());
155 BOOST_TEST(p==p2);
156 p.clear();
157
158 p.insert(p2.cbegin(),p2.cend());
159 BOOST_TEST(p==p2);
160 p.clear();
161
162 for(auto s:p2.segment_traversal()){
163 p.insert(s.begin(),s.end());
164 BOOST_TEST(p.size()==p2.size(s.type_info()));
165 p.clear();
166
167 p.insert(s.cbegin(),s.cend());
168 BOOST_TEST(p.size()==p2.size(s.type_info()));
169 p.clear();
170 }
171
172 do_((
173 p.insert(
174 external_iterator(p2.template begin<Types>()),
175 external_iterator(p2.template end<Types>())),
176 BOOST_TEST(p.size()==p2.template size<Types>()),
177 p.clear()
178 ,0)...);
179
180 do_((
181 p.insert(p2.template begin<Types>(),p2.template end<Types>()),
182 BOOST_TEST(p.size()==p2.template size<Types>()),
183 p.clear()
184 ,0)...);
185
186 do_((
187 p.insert(p2.template cbegin<Types>(),p2.template cend<Types>()),
188 BOOST_TEST(p.size()==p2.template size<Types>()),
189 p.clear()
190 ,0)...);
191 }
192 {
193 PolyCollection p,p1,p2;
194 ValueFactory v;
195
196 p2.template register_types<Types...>();
197 fill<
198 constraints<is_copy_constructible,is_equality_comparable>,
199 Types...
200 >(p1,v,2);
201 fill<
202 constraints<is_copy_constructible,is_equality_comparable>,
203 Types...
204 >(p2,v,2);
205
206 auto remove_original=[](PolyCollection& p)
207 {
208 bool first=true;
209 for(auto s:p.segment_traversal()){
210 if(first)p.erase(s.end()-2,s.end()),first=false;
211 else p.erase(s.begin(),s.begin()+2);
212 }
213 };
214
215 p=p1;
216 p.insert(
217 p.begin(),external_iterator(p2.begin()),external_iterator(p2.end()));
218 remove_original(p);
219 BOOST_TEST(p==p2);
220
221 p=p1;
222 p.insert(p.begin(),p2.begin(),p2.end());
223 remove_original(p);
224 BOOST_TEST(p==p2);
225
226 p=p1;
227 p.insert(p.begin(),p2.cbegin(),p2.cend());
228 remove_original(p);
229 BOOST_TEST(p==p2);
230
231 p=p1;
232 for(auto s:p2.segment_traversal())p.insert(p.begin(),s.begin(),s.end());
233 remove_original(p);
234 BOOST_TEST(p==p2);
235
236 p=p1;
237 for(auto s:p2.segment_traversal())p.insert(p.begin(),s.cbegin(),s.cend());
238 remove_original(p);
239 BOOST_TEST(p==p2);
240
241 p=p1;
242 do_((p.insert(
243 p.begin(),
244 external_iterator(p2.template begin<Types>()),
245 external_iterator(p2.template end<Types>())),0)...);
246 remove_original(p);
247 BOOST_TEST(p==p2);
248
249 p=p1;
250 do_((p.insert(
251 p.begin(),p2.template begin<Types>(),p2.template end<Types>()),0)...);
252 remove_original(p);
253 BOOST_TEST(p==p2);
254
255 p=p1;
256 do_((p.insert(
257 p.begin(),p2.template cbegin<Types>(),p2.template cend<Types>()),0)...);
258 remove_original(p);
259 BOOST_TEST(p==p2);
260 }
261 {
262 using type=first_of<
263 constraints<is_copy_constructible,is_equality_comparable>,
264 Types...
265 >;
266
267 PolyCollection p,p1,p2;
268 ValueFactory v;
269
270 fill<constraints<>,type>(p1,v,2);
271 fill<constraints<>,type>(p2,v,2);
272
273 auto remove_original=[](PolyCollection& p)
274 {
275 auto it=p.segment_traversal().begin()->end();
276 p.erase(it-2,it);
277 };
278
279 p=p1;
280 BOOST_TEST(is_first(
281 p,typeid(type),
282 p.insert(
283 p.begin(typeid(type)),
284 external_iterator(p2.begin()),external_iterator(p2.end()))));
285 remove_original(p);
286 BOOST_TEST(p==p2);
287
288 p=p1;
289 BOOST_TEST(is_first(
290 p,typeid(type),
291 p.insert(
292 p.cbegin(typeid(type)),
293 external_iterator(p2.begin()),external_iterator(p2.end()))));
294 remove_original(p);
295 BOOST_TEST(p==p2);
296
297 p=p1;
298 BOOST_TEST(is_first<type>(
299 p,
300 p.insert(
301 p.template begin<type>(),
302 external_iterator(p2.begin()),external_iterator(p2.end()))));
303 remove_original(p);
304 BOOST_TEST(p==p2);
305
306 p=p1;
307 BOOST_TEST(is_first<type>(
308 p,
309 p.insert(
310 p.template cbegin<type>(),
311 external_iterator(p2.begin()),external_iterator(p2.end()))));
312 remove_original(p);
313 BOOST_TEST(p==p2);
314 }
315 {
316 using type=first_of<
317 constraints<
318 is_constructible_from_int,is_not_copy_constructible,
319 is_equality_comparable
320 >,
321 Types...
322 >;
323
324 PolyCollection p;
325 std::vector<int> s(10);
326 ValueFactory v;
327
328 fill<constraints<>,type>(p,v,2);
329 std::iota(s.begin(),s.end(),0);
330 BOOST_TEST(is_first<type>(
331 p,
332 p.insert(p.template begin<type>(),s.begin(),s.end())));
333 BOOST_TEST(
334 std::equal(s.begin(),s.end(),p.template begin<type>(),
335 [](int x,const type& y){return type{x}==y;})
336 );
337 }
338 }
339
test_insertion()340 void test_insertion()
341 {
342 test_insertion<
343 any_types::collection,auto_increment,
344 any_types::t1,any_types::t2,any_types::t3,
345 any_types::t4,any_types::t5>();
346 test_insertion<
347 base_types::collection,auto_increment,
348 base_types::t1,base_types::t2,base_types::t3,
349 base_types::t4,base_types::t5>();
350 test_insertion<
351 function_types::collection,auto_increment,
352 function_types::t1,function_types::t2,function_types::t3,
353 function_types::t4,function_types::t5>();
354 }
355