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& 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 66 int 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>, 97 test_allocator<int> > >(stored_allocators); 98 test<std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, 99 test_allocator<int> > >(stored_allocators); 100 101 using KV = std::pair<const int, int>; 102 test<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, 103 test_allocator<KV> > >(stored_allocators); 104 test<std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, 105 test_allocator<KV> > >(stored_allocators); 106 } 107 108 return 0; 109 } 110