]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/poly_collection/test/test_construction.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / poly_collection / test / test_construction.cpp
CommitLineData
92f5a8d4 1/* Copyright 2016-2019 Joaquin M Lopez Munoz.
b32b8144
FG
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_construction.hpp"
10
11#include <algorithm>
12#include <boost/config.hpp>
13#include <boost/core/lightweight_test.hpp>
14#include <boost/detail/workaround.hpp>
b32b8144
FG
15#include <boost/type_erasure/relaxed.hpp>
16#include <scoped_allocator>
17#include <utility>
18#include <vector>
19#include "any_types.hpp"
20#include "base_types.hpp"
21#include "function_types.hpp"
22#include "test_utilities.hpp"
23
24using namespace test_utilities;
25
92f5a8d4
TL
26template<
27 bool Propagate,bool AlwaysEqual,
28 typename PolyCollection,typename ValueFactory,typename... Types
29>
30void test_allocator_aware_construction()
31{
32 using rooted_poly_collection=realloc_poly_collection<
33 PolyCollection,rooted_allocator,
34 std::integral_constant<bool,Propagate>,
35 std::integral_constant<bool,AlwaysEqual>>;
36 using allocator_type=typename rooted_poly_collection::allocator_type;
37
38 allocator_type root1{0},root2{0};
39 rooted_poly_collection p{root1};
40 const rooted_poly_collection& cp=p;
41 ValueFactory v;
42
43 fill<
44 constraints<is_equality_comparable,is_copy_constructible>,
45 Types...
46 >(p,v,2);
47
48 {
49 rooted_poly_collection p2{cp};
50 BOOST_TEST(p2==p);
51 BOOST_TEST(p2.get_allocator().comes_from(root1));
52 }
53 {
54 rooted_poly_collection p2{cp};
55 auto d2=get_layout_data<Types...>(p2);
56 rooted_poly_collection p3{std::move(p2)};
57 auto d3=get_layout_data<Types...>(p3);
58 BOOST_TEST(p3==p);
59 BOOST_TEST(d2==d3);
60 BOOST_TEST(p2.empty());
61 do_((BOOST_TEST(!p2.template is_registered<Types>()),0)...);
62 BOOST_TEST(p2.get_allocator().comes_from(root1));
63 }
64 {
65 rooted_poly_collection p2{cp,root2};
66 BOOST_TEST(p2==p);
67 BOOST_TEST(p2.get_allocator().comes_from(root2));
68 }
69#if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
70 /* std::unordered_map allocator move ctor does not work when source and
71 * and target allocators are not equal.
72 */
73
74 if(AlwaysEqual)
75#endif
76#if BOOST_WORKAROUND(_MSVC_STL_UPDATE,==201811L)
77 /* This particular version of VS2019 has a bug in std::unordered_map
78 * allocator move ctor when source and target allocators are not equal.
79 * After private communication from Billy O'Neal.
80 */
81
82 if(AlwaysEqual)
83#endif
84 {
85 rooted_poly_collection p2{cp};
86 auto d2=get_layout_data<Types...>(p2);
87 rooted_poly_collection p3{std::move(p2),root2};
88 auto d3=get_layout_data<Types...>(p3);
89
90 BOOST_TEST(p3==p);
91
92#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40900)
93 /* Limitations from libstdc++-v3 force move construction with allocator
94 * to decay to copy construction with allocator.
95 */
96
97 (void)(d2==d3); /* Wunused-variable */
98#else
99 if(AlwaysEqual)BOOST_TEST(d2==d3);
100#endif
101
102 BOOST_TEST(p2.empty());
103 do_((BOOST_TEST(!p2.template is_registered<Types>()),0)...);
104
105#if !defined(BOOST_MSVC)&&\
106 BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB,BOOST_TESTED_AT(804))
107 /* Very odd behavior probably due to std::unordered_map allocator move
108 * ctor being implemented with move assignment, as reported in
109 * https://github.com/boostorg/poly_collection/issues/16
110 */
111
112 if(!(Propagate&&!AlwaysEqual))
113#endif
114 BOOST_TEST(p3.get_allocator().comes_from(root2));
115 }
116 {
117 rooted_poly_collection p2{root2};
118 p2=cp;
119 BOOST_TEST(p2==p);
120
121#if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
122 /* std::unordered_map copy assignment does not propagate allocators */
123
124 if(!Propagate)
125#endif
126#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40900)
127 /* std::unordered_map copy assignment always and only propagates unequal
128 * allocators.
129 */
130
131 if(!((Propagate&&AlwaysEqual)||(!Propagate&&!AlwaysEqual)))
132#endif
133#if !defined(BOOST_MSVC)&&\
134 BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB,BOOST_TESTED_AT(804))
135 /* std::unordered_map copy assignment does not propagate allocators, as
136 * reported in https://github.com/boostorg/poly_collection/issues/16
137 */
138
139 if(!Propagate)
140#endif
141 BOOST_TEST(p2.get_allocator().comes_from(Propagate?root1:root2));
142 }
143#if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
144 /* std::unordered_map move asignment does not propagate allocators */
145
146 if(!Propagate&&AlwaysEqual)
147#endif
148 {
149 rooted_poly_collection p2{cp};
150 auto d2=get_layout_data<Types...>(p2);
151 rooted_poly_collection p3{root2};
152 p3=std::move(p2);
153 auto d3=get_layout_data<Types...>(p3);
154 BOOST_TEST(p3==p);
155 if(Propagate||AlwaysEqual){
156 BOOST_TEST(d2==d3);
157 BOOST_TEST(p2.empty());
158 do_((BOOST_TEST(!p2.template is_registered<Types>()),0)...);
159 }
160
161#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40900)
162 /* std::unordered_map move assignment always and only propagates unequal
163 * allocators.
164 */
165
166 if(!((Propagate&&AlwaysEqual)||(!Propagate&&!AlwaysEqual)))
167#endif
168#if !defined(BOOST_MSVC)&&\
169 BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB,BOOST_TESTED_AT(804))
170 /* std::unordered_map move assignment does not propagate equal allocators,
171 * as reported in https://github.com/boostorg/poly_collection/issues/16
172 */
173
174 if(!(Propagate&&AlwaysEqual))
175#endif
176 BOOST_TEST(p3.get_allocator().comes_from(Propagate?root1:root2));
177 }
178#if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
179 /* std::unordered_map::swap does not correctly swap control information when
180 * swapping allocators, which causes crashes on "Checked Iterators" mode.
181 */
182
183 if(!(Propagate&&!AlwaysEqual))
184#endif
185 {
186 constexpr bool use_same_allocator=!Propagate&&!AlwaysEqual;
187
188 rooted_poly_collection p2{cp},
189 p3{use_same_allocator?root1:root2};
190
191 auto d2=get_layout_data<Types...>(p2),
192 d3=get_layout_data<Types...>(p3);
193
194 p2.swap(p3);
195 auto e2=get_layout_data<Types...>(p2),
196 e3=get_layout_data<Types...>(p3);
197 BOOST_TEST(d2==e3);
198 BOOST_TEST(d3==e2);
199 do_((BOOST_TEST(!p2.template is_registered<Types>()),0)...);
200 if(!use_same_allocator
201#if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
202 /* std::unordered_map::swap does not swap equal allocators */
203
204 &&!(Propagate&&AlwaysEqual)
205#endif
206#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40900)
207 /* std::unordered_map::swap always and only swaps unequal allocators */
208
209 &&!((Propagate&&AlwaysEqual)||(!Propagate&&!AlwaysEqual))
210#endif
211#if !defined(BOOST_MSVC)&&\
212 BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB,BOOST_TESTED_AT(804))
213 /* std::unordered_map::swap does not swap equal allocators, as reported
214 * in https://github.com/boostorg/poly_collection/issues/16
215 */
216
217 &&!(Propagate&&AlwaysEqual)
218#endif
219 ){
220 BOOST_TEST(p2.get_allocator().comes_from(Propagate?root2:root1));
221 BOOST_TEST(p3.get_allocator().comes_from(Propagate?root1:root2));
222 }
223
224 using std::swap;
225 swap(p2,p3);
226 auto f2=get_layout_data<Types...>(p2),
227 f3=get_layout_data<Types...>(p3);
228 BOOST_TEST(e2==f3);
229 BOOST_TEST(e3==f2);
230 do_((BOOST_TEST(!p3.template is_registered<Types>()),0)...);
231 if(!use_same_allocator){
232 BOOST_TEST(p2.get_allocator().comes_from(root1));
233 BOOST_TEST(p3.get_allocator().comes_from(root2));
234 }
235 }
236}
237
b32b8144
FG
238template<typename PolyCollection,typename ValueFactory,typename... Types>
239void test_construction()
240{
92f5a8d4
TL
241 {
242 constexpr bool propagate=true,always_equal=true;
243
244 test_allocator_aware_construction<
245 !propagate,!always_equal,PolyCollection,ValueFactory,Types...>();
246 test_allocator_aware_construction<
247 !propagate, always_equal,PolyCollection,ValueFactory,Types...>();
248 test_allocator_aware_construction<
249 propagate,!always_equal,PolyCollection,ValueFactory,Types...>();
250 test_allocator_aware_construction<
251 propagate, always_equal,PolyCollection,ValueFactory,Types...>();
252 }
253
b32b8144
FG
254 {
255 PolyCollection p;
256 const PolyCollection& cp=p;
257 ValueFactory v;
258
259 fill<
260 constraints<is_equality_comparable,is_copy_constructible>,
261 Types...
262 >(p,v,2);
263
b32b8144
FG
264 {
265 PolyCollection p2{cp.begin(),cp.end()};
266 BOOST_TEST(p2==p);
267 }
268 {
269 using type=first_of<
270 constraints<is_equality_comparable,is_copy_constructible>,
271 Types...>;
272
273 PolyCollection p2{cp.template begin<type>(),cp.template end<type>()};
274 BOOST_TEST(
275 p2.size()==cp.template size<type>()&&
276 std::equal(
277 p2.template begin<type>(),p2.template end<type>(),
278 cp.template begin<type>()));
279 }
280 }
281
b32b8144
FG
282 {
283 using not_copy_constructible=
284 boost::poly_collection::not_copy_constructible;
285
286 PolyCollection p;
287 const PolyCollection& cp=p;
288 ValueFactory v;
289
290 fill<
291 constraints<is_equality_comparable,is_not_copy_constructible>,
292 Types...
293 >(p,v,2);
294
295#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40900)
296 /* std::unordered_map copy construction and assigment crash when elements
297 * throw on copy construction.
298 */
299
300 static_assert(
301 sizeof(not_copy_constructible)>0,""); /* Wunused-local-typedefs */
302 (void)cp; /* Wunused-variable */
303#else
304 check_throw<not_copy_constructible>([&]{
305 PolyCollection p2{cp};
306 (void)p2;
307 });
308 check_throw<not_copy_constructible>([&]{
309 PolyCollection p2;
310 p2=cp;
311 });
312#endif
313
314 {
315 PolyCollection p2{std::move(p)};
316 BOOST_TEST(!p2.empty());
317 BOOST_TEST(p.empty());
318 do_((BOOST_TEST(!p.template is_registered<Types>()),0)...);
319
320 p={std::move(p2)};
321 BOOST_TEST(!p.empty());
322 BOOST_TEST(p2.empty());
323 do_((BOOST_TEST(!p2.template is_registered<Types>()),0)...);
324 }
325 }
b32b8144
FG
326}
327
328void test_scoped_allocator()
329{
92f5a8d4
TL
330#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<50000)&&\
331 BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,>40704)
332 /* std::scoped_allocator_adaptor not assignable, see
333 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65279 .
334 * The bug prevents poly_collection below from creating any segment.
335 */
336#else
b32b8144
FG
337 using vector_allocator=rooted_allocator<char>;
338 using vector=std::vector<char,vector_allocator>;
339 using concept_=boost::type_erasure::relaxed;
340 using element_allocator=rooted_allocator<
341 boost::poly_collection::any_collection_value_type<concept_>
342 >;
343 using collection_allocator=std::scoped_allocator_adaptor<
344 element_allocator,
345 vector_allocator
346 >;
347 using poly_collection=
348 boost::any_collection<concept_,collection_allocator>;
349
350 element_allocator roote{0};
351 vector_allocator rootv{0};
352 collection_allocator al{roote,rootv};
353 poly_collection p{al};
354
355 p.emplace<vector>();
92f5a8d4
TL
356 auto& s=*p.begin<vector>();
357 BOOST_TEST(p.get_allocator().comes_from(roote));
b32b8144 358
92f5a8d4
TL
359#if BOOST_WORKAROUND(BOOST_MSVC,>=1910)&&BOOST_WORKAROUND(BOOST_MSVC,<1916)
360 /* https://developercommunity.visualstudio.com/content/problem/246251/
361 * 3136309.html
362 */
b32b8144 363#else
92f5a8d4
TL
364 BOOST_TEST(s.get_allocator().comes_from(rootv));
365#endif
b32b8144
FG
366#endif
367}
368
369void test_construction()
370{
371 test_construction<
372 any_types::collection,auto_increment,
373 any_types::t1,any_types::t2,any_types::t3,
374 any_types::t4,any_types::t5>();
375 test_construction<
376 base_types::collection,auto_increment,
377 base_types::t1,base_types::t2,base_types::t3,
378 base_types::t4,base_types::t5>();
379 test_construction<
380 function_types::collection,auto_increment,
381 function_types::t1,function_types::t2,function_types::t3,
382 function_types::t4,function_types::t5>();
383 test_scoped_allocator();
384}