1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2016-2016. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
10 #include <boost/core/lightweight_test.hpp>
11 #include <boost/static_assert.hpp>
12 #include <boost/container/node_handle.hpp>
13 #include <boost/container/new_allocator.hpp>
14 #include <boost/move/utility_core.hpp>
15 #include <boost/move/adl_move_swap.hpp>
16 #include <boost/container/detail/pair_key_mapped_of_value.hpp>
18 using namespace ::boost::container
;
33 : public new_allocator
<Node
>
35 BOOST_COPYABLE_AND_MOVABLE(trace_allocator
)
37 typedef new_allocator
<Node
> base_t
;
41 struct propagate_on_container_move_assignment
43 static const bool value
= true;
46 struct propagate_on_container_swap
48 static const bool value
= true;
51 //!Obtains an new_allocator that allocates
56 typedef trace_allocator
<T2
> other
;
59 explicit trace_allocator(unsigned value
= 999)
60 : m_state(DefaultConstructed
), m_value(value
)
65 trace_allocator(BOOST_RV_REF(trace_allocator
) other
)
66 : base_t(boost::move(BOOST_MOVE_BASE(base_t
, other
))), m_state(MoveConstructed
), m_value(other
.m_value
)
71 trace_allocator(const trace_allocator
&other
)
72 : base_t(other
), m_state(CopyConstructed
), m_value(other
.m_value
)
77 trace_allocator
& operator=(BOOST_RV_REF(trace_allocator
) other
)
79 m_value
= other
.m_value
;
80 m_state
= MoveAssigned
;
84 template<class OtherNode
>
85 trace_allocator(const trace_allocator
<OtherNode
> &other
)
86 : m_state(CopyConstructed
), m_value(other
.m_value
)
91 template<class OtherNode
>
92 trace_allocator
& operator=(BOOST_COPY_ASSIGN_REF(trace_allocator
<OtherNode
>) other
)
94 m_value
= other
.m_value
;
95 m_state
= CopyAssigned
;
102 m_state
= Destructed
;
106 void swap(trace_allocator
&other
)
108 boost::adl_move_swap(m_value
, other
.m_value
);
109 m_state
= other
.m_state
= Swapped
;
112 friend void swap(trace_allocator
&left
, trace_allocator
&right
)
120 static unsigned int count
;
122 static void reset_count()
127 unsigned int trace_allocator
<Node
>::count
= 0;
132 typedef T value_type
;
135 value_type
&get_data() { return value
; }
136 const value_type
&get_data() const { return value
; }
148 static unsigned int count
;
150 static void reset_count()
154 template<class T1
, class T2
>
162 unsigned int node
<T
>::count
= 0;
166 typedef value
<int, unsigned> test_pair
;
167 typedef pair_key_mapped_of_value
<int, unsigned> key_mapped_t
;
168 typedef node
<test_pair
> node_t
;
169 typedef trace_allocator
< node_t
> node_alloc_t
;
170 typedef node_handle
<node_alloc_t
, void> node_handle_set_t
;
171 typedef node_handle
<node_alloc_t
, key_mapped_t
> node_handle_map_t
;
172 typedef allocator_traits
<node_alloc_t
>::portable_rebind_alloc
<test_pair
>::type value_allocator_type
;
177 BOOST_STATIC_ASSERT(( container_detail::is_same
<node_handle_set_t::value_type
, test_pair
>::value
));
178 BOOST_STATIC_ASSERT(( container_detail::is_same
<node_handle_set_t::key_type
, test_pair
>::value
));
179 BOOST_STATIC_ASSERT(( container_detail::is_same
<node_handle_set_t::mapped_type
, test_pair
>::value
));
180 BOOST_STATIC_ASSERT(( container_detail::is_same
<node_handle_set_t::allocator_type
, value_allocator_type
>::value
));
183 BOOST_STATIC_ASSERT(( container_detail::is_same
<node_handle_map_t::value_type
, test_pair
>::value
));
184 BOOST_STATIC_ASSERT(( container_detail::is_same
<node_handle_map_t::key_type
, int>::value
));
185 BOOST_STATIC_ASSERT(( container_detail::is_same
<node_handle_map_t::mapped_type
, unsigned>::value
));
186 BOOST_STATIC_ASSERT(( container_detail::is_same
<node_handle_map_t::allocator_type
, value_allocator_type
>::value
));
189 void test_default_constructor()
191 node_alloc_t::reset_count();
193 node_handle_set_t nh
;
194 BOOST_TEST(node_alloc_t::count
== 0);
196 BOOST_TEST(node_alloc_t::count
== 0);
199 void test_arg_constructor()
201 //With non-null pointer
202 node_alloc_t::reset_count();
203 node_t::reset_count();
205 const node_alloc_t al
;
206 BOOST_TEST(node_alloc_t::count
== 1);
208 node_handle_set_t
nh(new node_t
, al
);
209 BOOST_TEST(node_t::count
== 1);
210 BOOST_TEST(node_alloc_t::count
== 2);
212 BOOST_TEST(node_alloc_t::count
== 1);
214 BOOST_TEST(node_t::count
== 0);
215 BOOST_TEST(node_alloc_t::count
== 0);
218 node_alloc_t::reset_count();
219 node_t::reset_count();
221 const node_alloc_t al
;
222 BOOST_TEST(node_alloc_t::count
== 1);
224 node_handle_set_t
nh(0, al
);
225 BOOST_TEST(node_t::count
== 0);
226 BOOST_TEST(node_alloc_t::count
== 1);
228 BOOST_TEST(node_alloc_t::count
== 1);
229 BOOST_TEST(node_t::count
== 0);
231 BOOST_TEST(node_alloc_t::count
== 0);
234 void test_move_constructor()
236 //With non-null pointer
237 node_alloc_t::reset_count();
238 node_t::reset_count();
240 const node_alloc_t al
;
241 BOOST_TEST(node_alloc_t::count
== 1);
243 node_t
*const from_ptr
= new node_t
;
244 node_handle_set_t
nh(from_ptr
, al
);
245 BOOST_TEST(node_t::count
== 1);
246 BOOST_TEST(node_alloc_t::count
== 2);
248 node_handle_set_t
nh2(boost::move(nh
));
249 BOOST_TEST(nh
.empty());
250 BOOST_TEST(!nh2
.empty());
251 BOOST_TEST(nh2
.get() == from_ptr
);
252 BOOST_TEST(nh2
.node_alloc().m_state
== MoveConstructed
);
253 BOOST_TEST(node_t::count
== 1);
254 BOOST_TEST(node_alloc_t::count
== 2);
256 BOOST_TEST(node_t::count
== 0);
257 BOOST_TEST(node_alloc_t::count
== 1);
259 BOOST_TEST(node_alloc_t::count
== 1);
261 BOOST_TEST(node_t::count
== 0);
262 BOOST_TEST(node_alloc_t::count
== 0);
265 node_alloc_t::reset_count();
266 node_t::reset_count();
268 const node_alloc_t al
;
269 BOOST_TEST(node_alloc_t::count
== 1);
271 node_handle_set_t nh
;
273 node_handle_set_t
nh2(boost::move(nh
));
274 BOOST_TEST(nh
.empty());
275 BOOST_TEST(nh2
.empty());
276 BOOST_TEST(node_alloc_t::count
== 1);
278 BOOST_TEST(node_t::count
== 0);
279 BOOST_TEST(node_alloc_t::count
== 1);
281 BOOST_TEST(node_alloc_t::count
== 1);
283 BOOST_TEST(node_t::count
== 0);
284 BOOST_TEST(node_alloc_t::count
== 0);
287 void test_related_constructor()
289 //With non-null pointer
290 node_alloc_t::reset_count();
291 node_t::reset_count();
293 const node_alloc_t al
;
294 BOOST_TEST(node_alloc_t::count
== 1);
296 node_t
*const from_ptr
= new node_t
;
297 node_handle_map_t
nh(from_ptr
, al
);
298 BOOST_TEST(node_t::count
== 1);
299 BOOST_TEST(node_alloc_t::count
== 2);
301 node_handle_set_t
nh2(boost::move(nh
));
302 BOOST_TEST(nh
.empty());
303 BOOST_TEST(!nh2
.empty());
304 BOOST_TEST(nh2
.get() == from_ptr
);
305 BOOST_TEST(nh2
.node_alloc().m_state
== MoveConstructed
);
306 BOOST_TEST(node_t::count
== 1);
307 BOOST_TEST(node_alloc_t::count
== 2);
309 BOOST_TEST(node_t::count
== 0);
310 BOOST_TEST(node_alloc_t::count
== 1);
312 BOOST_TEST(node_alloc_t::count
== 1);
314 BOOST_TEST(node_t::count
== 0);
315 BOOST_TEST(node_alloc_t::count
== 0);
318 node_alloc_t::reset_count();
319 node_t::reset_count();
321 const node_alloc_t al
;
322 BOOST_TEST(node_alloc_t::count
== 1);
324 node_handle_set_t nh
;
326 node_handle_map_t
nh2(boost::move(nh
));
327 BOOST_TEST(nh
.empty());
328 BOOST_TEST(nh2
.empty());
329 BOOST_TEST(node_alloc_t::count
== 1);
331 BOOST_TEST(node_t::count
== 0);
332 BOOST_TEST(node_alloc_t::count
== 1);
334 BOOST_TEST(node_alloc_t::count
== 1);
336 BOOST_TEST(node_t::count
== 0);
337 BOOST_TEST(node_alloc_t::count
== 0);
340 void test_move_assignment()
344 node_alloc_t::reset_count();
345 node_t::reset_count();
346 node_t
*const from_ptr
= new node_t
;
347 node_handle_set_t
nh_from(from_ptr
, node_alloc_t());
348 BOOST_TEST(node_t::count
== 1);
349 BOOST_TEST(node_alloc_t::count
== 1);
351 node_handle_set_t nh_to
;
352 BOOST_TEST(nh_to
.empty());
353 BOOST_TEST(node_t::count
== 1);
354 BOOST_TEST(node_alloc_t::count
== 1);
356 nh_to
= boost::move(nh_from
);
358 BOOST_TEST(nh_from
.empty());
359 BOOST_TEST(!nh_to
.empty());
360 BOOST_TEST(nh_to
.get() == from_ptr
);
361 BOOST_TEST(nh_to
.node_alloc().m_state
== MoveConstructed
);
362 BOOST_TEST(node_t::count
== 1);
363 BOOST_TEST(node_alloc_t::count
== 1);
368 node_alloc_t::reset_count();
369 node_t::reset_count();
371 node_handle_set_t nh_from
;
372 BOOST_TEST(nh_from
.empty());
373 BOOST_TEST(node_t::count
== 0);
374 BOOST_TEST(node_alloc_t::count
== 0);
376 node_handle_set_t nh_to
;
377 BOOST_TEST(nh_to
.empty());
378 BOOST_TEST(node_t::count
== 0);
379 BOOST_TEST(node_alloc_t::count
== 0);
381 nh_to
= boost::move(nh_from
);
383 BOOST_TEST(nh_from
.empty());
384 BOOST_TEST(nh_to
.empty());
385 BOOST_TEST(node_t::count
== 0);
386 BOOST_TEST(node_alloc_t::count
== 0);
391 node_alloc_t::reset_count();
392 node_t::reset_count();
394 node_handle_set_t nh_from
;
395 BOOST_TEST(nh_from
.empty());
396 BOOST_TEST(node_t::count
== 0);
397 BOOST_TEST(node_alloc_t::count
== 0);
399 node_handle_set_t
nh_to(new node_t
, node_alloc_t());
400 BOOST_TEST(node_t::count
== 1);
401 BOOST_TEST(node_alloc_t::count
== 1);
403 nh_to
= boost::move(nh_from
);
405 BOOST_TEST(nh_from
.empty());
406 BOOST_TEST(nh_to
.empty());
407 BOOST_TEST(node_t::count
== 0);
408 BOOST_TEST(node_alloc_t::count
== 0);
413 node_alloc_t::reset_count();
414 node_t::reset_count();
416 node_t
*const from_ptr
= new node_t
;
417 node_handle_set_t
nh_from(from_ptr
, node_alloc_t());
418 BOOST_TEST(node_t::count
== 1);
419 BOOST_TEST(node_alloc_t::count
== 1);
421 node_handle_set_t
nh_to(new node_t
, node_alloc_t());
422 BOOST_TEST(node_t::count
== 2);
423 BOOST_TEST(node_alloc_t::count
== 2);
425 nh_to
= boost::move(nh_from
);
427 BOOST_TEST(nh_from
.empty());
428 BOOST_TEST(!nh_to
.empty());
429 BOOST_TEST(nh_to
.get() == from_ptr
);
430 BOOST_TEST(nh_to
.node_alloc().m_state
== MoveAssigned
);
431 BOOST_TEST(node_t::count
== 1);
432 BOOST_TEST(node_alloc_t::count
== 1);
436 void test_value_key_mapped()
440 node_t
*from_ptr
= new node_t
;
441 const node_handle_set_t
nh_from(from_ptr
, node_alloc_t());
442 from_ptr
->value
.first
= -99;
443 from_ptr
->value
.second
= 99;
444 BOOST_TEST(nh_from
.value().first
== -99);
445 BOOST_TEST(nh_from
.value().second
== 99);
449 node_t
*from_ptr
= new node_t
;
450 const node_handle_map_t
nh_from(from_ptr
, node_alloc_t());
451 from_ptr
->value
.first
= -98;
452 from_ptr
->value
.second
= 98;
453 BOOST_TEST(nh_from
.key() == -98);
454 BOOST_TEST(nh_from
.mapped() == 98);
458 void test_get_allocator()
460 const node_handle_set_t
nh(new node_t
, node_alloc_t(888));
461 allocator_traits
<node_alloc_t
>::portable_rebind_alloc
<test_pair
>::type a
= nh
.get_allocator();
462 BOOST_TEST(a
.m_value
== 888);
465 void test_bool_conversion_empty()
467 const node_handle_set_t
nh(new node_t
, node_alloc_t(777));
468 const node_handle_set_t nh_null
;
469 BOOST_TEST(nh
&& !nh_null
);
470 BOOST_TEST(!(!nh
|| nh_null
));
471 BOOST_TEST(!nh
.empty() && nh_null
.empty());
472 BOOST_TEST(!(nh
.empty() || !nh_null
.empty()));
479 node_alloc_t::reset_count();
480 node_t::reset_count();
481 node_t
*const from_ptr
= new node_t
;
482 node_handle_set_t
nh_from(from_ptr
, node_alloc_t());
483 BOOST_TEST(node_t::count
== 1);
484 BOOST_TEST(node_alloc_t::count
== 1);
486 node_handle_set_t nh_to
;
487 BOOST_TEST(nh_to
.empty());
488 BOOST_TEST(node_t::count
== 1);
489 BOOST_TEST(node_alloc_t::count
== 1);
493 BOOST_TEST(nh_from
.empty());
494 BOOST_TEST(!nh_to
.empty());
495 BOOST_TEST(nh_to
.get() == from_ptr
);
496 BOOST_TEST(nh_to
.node_alloc().m_state
== MoveConstructed
);
497 BOOST_TEST(node_t::count
== 1);
498 BOOST_TEST(node_alloc_t::count
== 1);
503 node_alloc_t::reset_count();
504 node_t::reset_count();
506 node_handle_set_t nh_from
;
507 BOOST_TEST(nh_from
.empty());
508 BOOST_TEST(node_t::count
== 0);
509 BOOST_TEST(node_alloc_t::count
== 0);
511 node_handle_set_t nh_to
;
512 BOOST_TEST(nh_to
.empty());
513 BOOST_TEST(node_t::count
== 0);
514 BOOST_TEST(node_alloc_t::count
== 0);
518 BOOST_TEST(nh_from
.empty());
519 BOOST_TEST(nh_to
.empty());
520 BOOST_TEST(node_t::count
== 0);
521 BOOST_TEST(node_alloc_t::count
== 0);
526 node_alloc_t::reset_count();
527 node_t::reset_count();
529 node_handle_set_t nh_from
;
530 BOOST_TEST(nh_from
.empty());
531 BOOST_TEST(node_t::count
== 0);
532 BOOST_TEST(node_alloc_t::count
== 0);
534 node_t
*const to_ptr
= new node_t
;
535 node_handle_set_t
nh_to(to_ptr
, node_alloc_t());
536 BOOST_TEST(node_t::count
== 1);
537 BOOST_TEST(node_alloc_t::count
== 1);
541 BOOST_TEST(!nh_from
.empty());
542 BOOST_TEST(nh_from
.node_alloc().m_state
== MoveConstructed
);
543 BOOST_TEST(nh_from
.get() == to_ptr
);
544 BOOST_TEST(nh_to
.empty());
546 BOOST_TEST(node_t::count
== 1);
547 BOOST_TEST(node_alloc_t::count
== 1);
552 node_alloc_t::reset_count();
553 node_t::reset_count();
555 node_t
*const from_ptr
= new node_t
;
556 node_handle_set_t
nh_from(from_ptr
, node_alloc_t());
557 BOOST_TEST(node_t::count
== 1);
558 BOOST_TEST(node_alloc_t::count
== 1);
560 node_t
*const to_ptr
= new node_t
;
561 node_handle_set_t
nh_to(to_ptr
, node_alloc_t());
562 BOOST_TEST(node_t::count
== 2);
563 BOOST_TEST(node_alloc_t::count
== 2);
567 BOOST_TEST(!nh_from
.empty());
568 BOOST_TEST(nh_from
.get() == to_ptr
);
569 BOOST_TEST(nh_from
.node_alloc().m_state
== Swapped
);
571 BOOST_TEST(!nh_to
.empty());
572 BOOST_TEST(nh_to
.get() == from_ptr
);
573 BOOST_TEST(nh_to
.node_alloc().m_state
== Swapped
);
575 BOOST_TEST(node_t::count
== 2);
576 BOOST_TEST(node_alloc_t::count
== 2);
580 void test_get_release()
584 node_alloc_t::reset_count();
585 node_t::reset_count();
587 node_t
*const ptr
= new node_t
;
588 const node_handle_set_t
nh(ptr
, node_alloc_t());
589 BOOST_TEST(node_t::count
== 1);
590 BOOST_TEST(node_alloc_t::count
== 1);
592 BOOST_TEST(nh
.get() == ptr
);
593 BOOST_TEST(!nh
.empty());
594 BOOST_TEST(node_t::count
== 1);
595 BOOST_TEST(node_alloc_t::count
== 1);
597 BOOST_TEST(node_t::count
== 0);
598 BOOST_TEST(node_alloc_t::count
== 0);
602 node_alloc_t::reset_count();
603 node_t::reset_count();
605 node_t
*const ptr
= new node_t
;
606 node_handle_set_t
nh(ptr
, node_alloc_t());
607 BOOST_TEST(node_t::count
== 1);
608 BOOST_TEST(node_alloc_t::count
== 1);
610 BOOST_TEST(nh
.release() == ptr
);
611 BOOST_TEST(nh
.empty());
612 BOOST_TEST(node_t::count
== 1);
613 BOOST_TEST(node_alloc_t::count
== 0);
616 BOOST_TEST(node_t::count
== 0);
622 test_default_constructor();
623 test_arg_constructor();
624 test_move_constructor();
625 test_related_constructor();
626 test_move_assignment();
627 test_value_key_mapped();
628 test_get_allocator();
629 test_bool_conversion_empty();
632 return ::boost::report_errors();