1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // UNSUPPORTED: c++03 |
10 | |
11 | // C++2a[container.requirements.general]p8 |
12 | // Move constructors obtain an allocator by move construction from the allocator |
13 | // belonging to the container being moved. Such move construction of the |
14 | // allocator shall not exit via an exception. |
15 | |
16 | #include <vector> |
17 | #include <deque> |
18 | #include <list> |
19 | #include <forward_list> |
20 | #include <set> |
21 | #include <map> |
22 | #include <unordered_map> |
23 | #include <unordered_set> |
24 | |
25 | #include "test_macros.h" |
26 | #include "test_allocator.h" |
27 | |
28 | template <class C> |
29 | void test(int expected_num_allocs = 1) { |
30 | test_allocator_statistics alloc_stats; |
31 | { |
32 | alloc_stats.clear(); |
33 | using AllocT = typename C::allocator_type; |
34 | C v(AllocT(42, 101, &alloc_stats)); |
35 | |
36 | assert(alloc_stats.count == expected_num_allocs); |
37 | |
38 | const int num_stored_allocs = alloc_stats.count; |
39 | { |
40 | const AllocT& a = v.get_allocator(); |
41 | assert(alloc_stats.count == 1 + num_stored_allocs); |
42 | assert(a.get_data() == 42); |
43 | assert(a.get_id() == 101); |
44 | } |
45 | assert(alloc_stats.count == num_stored_allocs); |
46 | alloc_stats.clear_ctor_counters(); |
47 | |
48 | C v2 = std::move(v); |
49 | assert(alloc_stats.count == num_stored_allocs * 2); |
50 | assert(alloc_stats.copied == 0); |
51 | assert(alloc_stats.moved == num_stored_allocs); |
52 | { |
53 | const AllocT& a = v.get_allocator(); |
54 | assert(a.get_id() == test_alloc_base::moved_value); |
55 | assert(a.get_data() == test_alloc_base::moved_value); |
56 | } |
57 | { |
58 | const AllocT& a = v2.get_allocator(); |
59 | assert(a.get_id() == 101); |
60 | assert(a.get_data() == 42); |
61 | } |
62 | } |
63 | } |
64 | |
65 | int main(int, char**) { |
66 | { // test sequence containers |
67 | test<std::vector<int, test_allocator<int> > >(); |
68 | test<std::vector<bool, test_allocator<bool> > >(); |
69 | test<std::list<int, test_allocator<int> > >(); |
70 | test<std::forward_list<int, test_allocator<int> > >(); |
71 | |
72 | // libc++ stores two allocators in deque |
73 | #ifdef _LIBCPP_VERSION |
74 | int stored_allocators = 2; |
75 | #else |
76 | int stored_allocators = 1; |
77 | #endif |
78 | test<std::deque<int, test_allocator<int> > >(stored_allocators); |
79 | } |
80 | { // test associative containers |
81 | test<std::set<int, std::less<int>, test_allocator<int> > >(); |
82 | test<std::multiset<int, std::less<int>, test_allocator<int> > >(); |
83 | |
84 | using KV = std::pair<const int, int>; |
85 | test<std::map<int, int, std::less<int>, test_allocator<KV> > >(); |
86 | test<std::multimap<int, int, std::less<int>, test_allocator<KV> > >(); |
87 | } |
88 | { // test unordered containers |
89 | // libc++ stores two allocators in the unordered containers. |
90 | #ifdef _LIBCPP_VERSION |
91 | int stored_allocators = 2; |
92 | #else |
93 | int stored_allocators = 1; |
94 | #endif |
95 | test<std::unordered_set<int, std::hash<int>, std::equal_to<int>, |
96 | test_allocator<int> > >(stored_allocators); |
97 | test<std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, |
98 | test_allocator<int> > >(stored_allocators); |
99 | |
100 | using KV = std::pair<const int, int>; |
101 | test<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, |
102 | test_allocator<KV> > >(stored_allocators); |
103 | test<std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, |
104 | test_allocator<KV> > >(stored_allocators); |
105 | } |
106 | |
107 | return 0; |
108 | } |
109 | |