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 Tp, class Vp> 18 // void scoped_allocator_adaptor::construct(pair<U1, U2>*, Tp&&, Up&&) 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 int x = 42; 39 const int y = 101; 40 using Alloc = CountingAllocator<Pair>; 41 using SA = std::scoped_allocator_adaptor<Alloc>; 42 static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); 43 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 44 assert(ptr != nullptr); 45 Alloc CA(P); 46 SA A(CA); 47 A.construct(ptr, x, std::move(y)); 48 assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA)); 49 assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA)); 50 assert((P.checkConstruct<std::piecewise_construct_t const&, 51 std::tuple<std::allocator_arg_t, SA&, int&>&&, 52 std::tuple<int const&&, SA&>&& 53 >(CA, ptr))); 54 A.destroy(ptr); 55 std::free(ptr); 56 57 } 58 P.reset(); 59 { 60 using T = UsesAllocatorV3<VoidAlloc, 1>; 61 using U = NotUsesAllocator<VoidAlloc, 1>; 62 using Pair = std::pair<T, U>; 63 int x = 42; 64 const int y = 101; 65 using Alloc = CountingAllocator<Pair>; 66 using SA = std::scoped_allocator_adaptor<Alloc>; 67 static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); 68 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 69 assert(ptr != nullptr); 70 Alloc CA(P); 71 SA A(CA); 72 A.construct(ptr, std::move(x), y); 73 assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA)); 74 assert(checkConstruct<int const&>(ptr->second, UA_None)); 75 assert((P.checkConstruct<std::piecewise_construct_t const&, 76 std::tuple<std::allocator_arg_t, SA&, int&&>&&, 77 std::tuple<int const&>&& 78 >(CA, ptr))); 79 A.destroy(ptr); 80 std::free(ptr); 81 } 82 } 83 84 void test_with_inner_alloc() 85 { 86 using VoidAlloc2 = CountingAllocator<void, 2>; 87 88 AllocController POuter; 89 AllocController PInner; 90 { 91 using T = UsesAllocatorV1<VoidAlloc2, 1>; 92 using U = UsesAllocatorV2<VoidAlloc2, 1>; 93 using Pair = std::pair<T, U>; 94 int x = 42; 95 int y = 101; 96 using Outer = CountingAllocator<Pair, 1>; 97 using Inner = CountingAllocator<Pair, 2>; 98 using SA = std::scoped_allocator_adaptor<Outer, Inner>; 99 using SAInner = std::scoped_allocator_adaptor<Inner>; 100 static_assert(!std::uses_allocator<T, Outer>::value, ""); 101 static_assert(std::uses_allocator<T, Inner>::value, ""); 102 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 103 assert(ptr != nullptr); 104 Outer O(POuter); 105 Inner I(PInner); 106 SA A(O, I); 107 A.construct(ptr, x, std::move(y)); 108 assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I)); 109 assert(checkConstruct<int &&>(ptr->second, UA_AllocLast)); 110 assert((POuter.checkConstruct<std::piecewise_construct_t const&, 111 std::tuple<std::allocator_arg_t, SAInner&, int&>&&, 112 std::tuple<int &&, SAInner&>&& 113 >(O, ptr))); 114 A.destroy(ptr); 115 std::free(ptr); 116 } 117 PInner.reset(); 118 POuter.reset(); 119 { 120 using T = UsesAllocatorV3<VoidAlloc2, 1>; 121 using U = NotUsesAllocator<VoidAlloc2, 1>; 122 using Pair = std::pair<T, U>; 123 int x = 42; 124 const int y = 101; 125 using Outer = CountingAllocator<Pair, 1>; 126 using Inner = CountingAllocator<Pair, 2>; 127 using SA = std::scoped_allocator_adaptor<Outer, Inner>; 128 using SAInner = std::scoped_allocator_adaptor<Inner>; 129 static_assert(!std::uses_allocator<T, Outer>::value, ""); 130 static_assert(std::uses_allocator<T, Inner>::value, ""); 131 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 132 assert(ptr != nullptr); 133 Outer O(POuter); 134 Inner I(PInner); 135 SA A(O, I); 136 A.construct(ptr, std::move(x), std::move(y)); 137 assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I)); 138 assert(checkConstruct<int const&&>(ptr->second, UA_None)); 139 assert((POuter.checkConstruct<std::piecewise_construct_t const&, 140 std::tuple<std::allocator_arg_t, SAInner&, int&&>&&, 141 std::tuple<int const&&>&& 142 >(O, ptr))); 143 A.destroy(ptr); 144 std::free(ptr); 145 } 146 } 147 int main() { 148 test_no_inner_alloc(); 149 test_with_inner_alloc(); 150 } 151