1 // { dg-do run { target c++17 } }
3 // PR libstdc++/114401 allocator destructor omitted when reinserting node_handle
7 #include <testsuite_hooks.h>
13 using propagate_on_container_copy_assignment
= std::true_type
;
14 using propagate_on_container_move_assignment
= std::true_type
;
15 using propagate_on_container_swap
= std::true_type
;
17 Alloc(int identity
) : id(std::make_shared
<int>(identity
)) { }
20 Alloc(const Alloc
<U
> a
) : id(a
.id
) { }
22 T
* allocate(std::size_t n
) { return std::allocator
<T
>().allocate(n
); }
23 void deallocate(T
* p
, std::size_t n
) { std::allocator
<T
>().deallocate(p
, n
); }
27 operator==(const Alloc
& a
, const Alloc
<U
>& a2
)
28 { return a
.id
== a2
.id
; }
32 operator!=(const Alloc
& a
, const Alloc
<U
>& a2
)
33 { return !(a
== a2
); }
35 std::shared_ptr
<int> id
;
38 using test_type
= std::set
<int, std::less
<int>, Alloc
<int>>;
43 test_type
s1({1,3,5}, Alloc
<int>(1));
44 test_type
s2({2,4,6,8}, Alloc
<int>(2));
45 VERIFY( s1
.get_allocator() != s2
.get_allocator() );
47 auto node_a
= s1
.extract(1);
48 VERIFY( ! node_a
.empty() );
49 VERIFY( node_a
.get_allocator() == s1
.get_allocator() );
51 node_a
= std::move(node_a
); // self-move
52 VERIFY( node_a
.empty() );
54 swap(node_a
, node_a
); // self-swap
55 VERIFY( node_a
.empty() );
57 auto node_b
= s2
.extract(2);
58 VERIFY( node_b
.get_allocator() == s2
.get_allocator() );
60 node_a
= std::move(node_b
); // empty = !empty
61 VERIFY( node_a
.get_allocator() == s2
.get_allocator() );
62 VERIFY( node_b
.empty() );
64 swap(node_a
, node_b
); // swap(!empty, empty)
65 VERIFY( node_a
.empty() );
66 VERIFY( node_b
.get_allocator() == s2
.get_allocator() );
68 swap(node_a
, node_b
); // swap(empty, !empty)
69 VERIFY( node_a
.get_allocator() == s2
.get_allocator() );
70 VERIFY( node_b
.empty() );
72 node_a
= s1
.extract(3); // !empty = !empty
73 VERIFY( node_a
.get_allocator() == s1
.get_allocator() );
74 node_b
= s2
.extract(0); // empty = empty
75 VERIFY( node_b
.empty() );
76 node_b
= s2
.extract(6); // empty = !empty
77 VERIFY( node_b
.get_allocator() == s2
.get_allocator() );
79 swap(node_a
, node_b
); // swap(!empty, !empty)
80 VERIFY( node_a
.get_allocator() == s2
.get_allocator() );
81 VERIFY( node_b
.get_allocator() == s1
.get_allocator() );
84 node_b
= std::move(node_a
); // !empty = empty
85 VERIFY( node_a
.empty() );
86 VERIFY( node_b
.empty() );
88 swap(node_a
, node_b
); // swap(empty, empty)
89 VERIFY( node_a
.empty() );
90 VERIFY( node_b
.empty() );
97 test_type
s({1,2,3}, a
);
98 VERIFY( a
.id
.use_count() == 2 ); // a and the copy in s
100 s
.insert(s
.extract(1));
101 VERIFY( a
.id
.use_count() == 2 );
103 s
.insert(s
.begin(), s
.extract(2));
104 VERIFY( a
.id
.use_count() == 2 );
106 auto node
= s
.extract(1);
107 VERIFY( a
.id
.use_count() == 3 );
109 VERIFY( a
.id
.use_count() == 2 );
111 s
.insert(std::move(node
));
112 VERIFY( a
.id
.use_count() == 2 );
114 s
.merge(test_type(s
));
115 VERIFY( a
.id
.use_count() == 2 );
117 s
.merge(test_type({4,5,6}, a
));
118 VERIFY( a
.id
.use_count() == 2 );
124 test_alloc_lifetime();