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