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
28template <class C>
29void 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& a1 = v.get_allocator();
54 assert(a1.get_id() == test_alloc_base::moved_value);
55 assert(a1.get_data() == 42);
56
57 const AllocT& a2 = v2.get_allocator();
58 assert(a2.get_id() == 101);
59 assert(a2.get_data() == 42);
60
61 assert(a1 == a2);
62 }
63 }
64}
65
66int main(int, char**) {
67 { // test sequence containers
68 test<std::vector<int, test_allocator<int> > >();
69 test<std::vector<bool, test_allocator<bool> > >();
70 test<std::list<int, test_allocator<int> > >();
71 test<std::forward_list<int, test_allocator<int> > >();
72
73 // libc++ stores two allocators in deque
74#ifdef _LIBCPP_VERSION
75 int stored_allocators = 2;
76#else
77 int stored_allocators = 1;
78#endif
79 test<std::deque<int, test_allocator<int> > >(stored_allocators);
80 }
81 { // test associative containers
82 test<std::set<int, std::less<int>, test_allocator<int> > >();
83 test<std::multiset<int, std::less<int>, test_allocator<int> > >();
84
85 using KV = std::pair<const int, int>;
86 test<std::map<int, int, std::less<int>, test_allocator<KV> > >();
87 test<std::multimap<int, int, std::less<int>, test_allocator<KV> > >();
88 }
89 { // test unordered containers
90 // libc++ stores two allocators in the unordered containers.
91#ifdef _LIBCPP_VERSION
92 int stored_allocators = 2;
93#else
94 int stored_allocators = 1;
95#endif
96 test<std::unordered_set<int, std::hash<int>, std::equal_to<int>, test_allocator<int> > >(stored_allocators);
97 test<std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, test_allocator<int> > >(stored_allocators);
98
99 using KV = std::pair<const int, int>;
100 test<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, test_allocator<KV> > >(stored_allocators);
101 test<std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, test_allocator<KV> > >(
102 stored_allocators);
103 }
104
105 return 0;
106}
107

source code of libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp