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> 18 // void scoped_allocator_adaptor::construct(pair<U1, U2>*, pair<T1, T2>&&) 19 20 #include <scoped_allocator> 21 #include <type_traits> 22 #include <utility> 23 #include <tuple> 24 #include <cassert> 25 #include <cstdlib> 26 #include "uses_alloc_types.hpp" 27 #include "controlled_allocators.hpp" 28 29 30 void test_no_inner_alloc() 31 { 32 using VoidAlloc = CountingAllocator<void>; 33 AllocController P; 34 { 35 using T = UsesAllocatorV1<VoidAlloc, 1>; 36 using U = UsesAllocatorV2<VoidAlloc, 1>; 37 using Pair = std::pair<T, U>; 38 using PairIn = std::pair<int&, int const&&>; 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 PairIn in(x, std::move(y)); 49 A.construct(ptr, std::move(in)); 50 assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA)); 51 assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA)); 52 assert((P.checkConstruct<std::piecewise_construct_t const&, 53 std::tuple<std::allocator_arg_t, SA&, int&>&&, 54 std::tuple<int const&&, SA&>&& 55 >(CA, ptr))); 56 A.destroy(ptr); 57 std::free(ptr); 58 59 } 60 P.reset(); 61 { 62 using T = UsesAllocatorV3<VoidAlloc, 1>; 63 using U = NotUsesAllocator<VoidAlloc, 1>; 64 using Pair = std::pair<T, U>; 65 using PairIn = std::pair<int, int const&>; 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 PairIn in(x, y); 76 A.construct(ptr, std::move(in)); 77 assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA)); 78 assert(checkConstruct<int const&>(ptr->second, UA_None)); 79 assert((P.checkConstruct<std::piecewise_construct_t const&, 80 std::tuple<std::allocator_arg_t, SA&, int&&>&&, 81 std::tuple<int const&>&& 82 >(CA, ptr))); 83 A.destroy(ptr); 84 std::free(ptr); 85 } 86 } 87 88 void test_with_inner_alloc() 89 { 90 using VoidAlloc2 = CountingAllocator<void, 2>; 91 92 AllocController POuter; 93 AllocController PInner; 94 { 95 using T = UsesAllocatorV1<VoidAlloc2, 1>; 96 using U = UsesAllocatorV2<VoidAlloc2, 1>; 97 using Pair = std::pair<T, U>; 98 using PairIn = std::pair<int&, int const&&>; 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 PairIn in(x, std::move(y)); 113 A.construct(ptr, std::move(in)); 114 assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I)); 115 assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast)); 116 assert((POuter.checkConstruct<std::piecewise_construct_t const&, 117 std::tuple<std::allocator_arg_t, SAInner&, int&>&&, 118 std::tuple<int const&&, SAInner&>&& 119 >(O, ptr))); 120 A.destroy(ptr); 121 std::free(ptr); 122 } 123 PInner.reset(); 124 POuter.reset(); 125 { 126 using T = UsesAllocatorV3<VoidAlloc2, 1>; 127 using U = NotUsesAllocator<VoidAlloc2, 1>; 128 using Pair = std::pair<T, U>; 129 using PairIn = std::pair<int, int const &>; 130 int x = 42; 131 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 PairIn in(x, y); 144 A.construct(ptr, std::move(in)); 145 assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I)); 146 assert(checkConstruct<int const&>(ptr->second, UA_None)); 147 assert((POuter.checkConstruct<std::piecewise_construct_t const&, 148 std::tuple<std::allocator_arg_t, SAInner&, int&&>&&, 149 std::tuple<int const&>&& 150 >(O, ptr))); 151 A.destroy(ptr); 152 std::free(ptr); 153 } 154 } 155 int main() { 156 test_no_inner_alloc(); 157 test_with_inner_alloc(); 158 } 159