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 // <scoped_allocator> 13 14 // template <class OtherAlloc, class ...InnerAlloc> 15 // class scoped_allocator_adaptor 16 17 // template <class U1, class U2, class ...Args1, class ...Args2> 18 // void scoped_allocator_adaptor::construct(pair<U1, U2>*, 19 // piecewise_construct_t, tuple<Args1...>, tuple<Args2...>) 20 21 #include <scoped_allocator> 22 #include <type_traits> 23 #include <utility> 24 #include <tuple> 25 #include <cassert> 26 #include <cstdlib> 27 #include "uses_alloc_types.hpp" 28 #include "controlled_allocators.hpp" 29 30 31 void test_no_inner_alloc() 32 { 33 using VoidAlloc = CountingAllocator<void>; 34 AllocController P; 35 { 36 using T = UsesAllocatorV1<VoidAlloc, 1>; 37 using U = UsesAllocatorV2<VoidAlloc, 1>; 38 using Pair = std::pair<T, U>; 39 int x = 42; 40 const int y = 101; 41 using Alloc = CountingAllocator<Pair>; 42 using SA = std::scoped_allocator_adaptor<Alloc>; 43 static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); 44 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 45 assert(ptr != nullptr); 46 Alloc CA(P); 47 SA A(CA); 48 A.construct(ptr, std::piecewise_construct, 49 std::forward_as_tuple(x), 50 std::forward_as_tuple(std::move(y))); 51 assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA)); 52 assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA)); 53 assert((P.checkConstruct<std::piecewise_construct_t const&, 54 std::tuple<std::allocator_arg_t, SA&, int&>&&, 55 std::tuple<int const&&, SA&>&& 56 >(CA, ptr))); 57 A.destroy(ptr); 58 std::free(ptr); 59 60 } 61 P.reset(); 62 { 63 using T = UsesAllocatorV3<VoidAlloc, 1>; 64 using U = NotUsesAllocator<VoidAlloc, 1>; 65 using Pair = std::pair<T, U>; 66 int x = 42; 67 const int y = 101; 68 using Alloc = CountingAllocator<Pair>; 69 using SA = std::scoped_allocator_adaptor<Alloc>; 70 static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); 71 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 72 assert(ptr != nullptr); 73 Alloc CA(P); 74 SA A(CA); 75 A.construct(ptr, std::piecewise_construct, 76 std::forward_as_tuple(std::move(x)), 77 std::forward_as_tuple(y)); 78 assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA)); 79 assert(checkConstruct<int const&>(ptr->second, UA_None)); 80 assert((P.checkConstruct<std::piecewise_construct_t const&, 81 std::tuple<std::allocator_arg_t, SA&, int&&>&&, 82 std::tuple<int const&>&& 83 >(CA, ptr))); 84 A.destroy(ptr); 85 std::free(ptr); 86 } 87 } 88 89 void test_with_inner_alloc() 90 { 91 using VoidAlloc2 = CountingAllocator<void, 2>; 92 93 AllocController POuter; 94 AllocController PInner; 95 { 96 using T = UsesAllocatorV1<VoidAlloc2, 1>; 97 using U = UsesAllocatorV2<VoidAlloc2, 1>; 98 using Pair = std::pair<T, U>; 99 int x = 42; 100 int y = 101; 101 using Outer = CountingAllocator<Pair, 1>; 102 using Inner = CountingAllocator<Pair, 2>; 103 using SA = std::scoped_allocator_adaptor<Outer, Inner>; 104 using SAInner = std::scoped_allocator_adaptor<Inner>; 105 static_assert(!std::uses_allocator<T, Outer>::value, ""); 106 static_assert(std::uses_allocator<T, Inner>::value, ""); 107 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 108 assert(ptr != nullptr); 109 Outer O(POuter); 110 Inner I(PInner); 111 SA A(O, I); 112 A.construct(ptr, std::piecewise_construct, 113 std::forward_as_tuple(x), 114 std::forward_as_tuple(std::move(y))); 115 assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I)); 116 assert(checkConstruct<int &&>(ptr->second, UA_AllocLast)); 117 assert((POuter.checkConstruct<std::piecewise_construct_t const&, 118 std::tuple<std::allocator_arg_t, SAInner&, int&>&&, 119 std::tuple<int &&, SAInner&>&& 120 >(O, ptr))); 121 A.destroy(ptr); 122 std::free(ptr); 123 } 124 PInner.reset(); 125 POuter.reset(); 126 { 127 using T = UsesAllocatorV3<VoidAlloc2, 1>; 128 using U = NotUsesAllocator<VoidAlloc2, 1>; 129 using Pair = std::pair<T, U>; 130 int x = 42; 131 const int y = 101; 132 using Outer = CountingAllocator<Pair, 1>; 133 using Inner = CountingAllocator<Pair, 2>; 134 using SA = std::scoped_allocator_adaptor<Outer, Inner>; 135 using SAInner = std::scoped_allocator_adaptor<Inner>; 136 static_assert(!std::uses_allocator<T, Outer>::value, ""); 137 static_assert(std::uses_allocator<T, Inner>::value, ""); 138 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 139 assert(ptr != nullptr); 140 Outer O(POuter); 141 Inner I(PInner); 142 SA A(O, I); 143 A.construct(ptr, std::piecewise_construct, 144 std::forward_as_tuple(std::move(x)), 145 std::forward_as_tuple(std::move(y))); 146 assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I)); 147 assert(checkConstruct<int const&&>(ptr->second, UA_None)); 148 assert((POuter.checkConstruct<std::piecewise_construct_t const&, 149 std::tuple<std::allocator_arg_t, SAInner&, int&&>&&, 150 std::tuple<int const&&>&& 151 >(O, ptr))); 152 A.destroy(ptr); 153 std::free(ptr); 154 } 155 } 156 int main() { 157 test_no_inner_alloc(); 158 test_with_inner_alloc(); 159 } 160