• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // UNSUPPORTED: c++98, c++03
11 
12 // C++2a[container.requirements.general]p8
13 //   Move constructors obtain an allocator by move construction from the allocator
14 //   belonging to the container being moved. Such move construction of the
15 //   allocator shall not exit via an exception.
16 
17 #include <vector>
18 #include <deque>
19 #include <list>
20 #include <forward_list>
21 #include <set>
22 #include <map>
23 #include <unordered_map>
24 #include <unordered_set>
25 
26 #include "test_macros.h"
27 #include "test_allocator.h"
28 
29 template <class C>
test(int expected_num_allocs=1)30 void test(int expected_num_allocs = 1) {
31   {
32     test_alloc_base::clear();
33     using AllocT = typename C::allocator_type;
34     C v(AllocT(42, 101));
35 
36     assert(test_alloc_base::count == expected_num_allocs);
37 
38     const int num_stored_allocs = test_alloc_base::count;
39     {
40       const AllocT& a = v.get_allocator();
41       assert(test_alloc_base::count == 1 + num_stored_allocs);
42       assert(a.get_data() == 42);
43       assert(a.get_id() == 101);
44     }
45     assert(test_alloc_base::count == num_stored_allocs);
46     test_alloc_base::clear_ctor_counters();
47 
48     C v2 = std::move(v);
49     assert(test_alloc_base::count == num_stored_allocs * 2);
50     assert(test_alloc_base::copied == 0);
51     assert(test_alloc_base::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 
main()65 int main() {
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