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 // <scoped_allocator> 12 13 // template <class OtherAlloc, class ...InnerAlloc> 14 // class scoped_allocator_adaptor 15 16 // template <class U1, class U2> 17 // void scoped_allocator_adaptor::construct(pair<U1, U2>*, pair<T1, T2>&&) 18 19 #include <scoped_allocator> 20 #include <type_traits> 21 #include <utility> 22 #include <tuple> 23 #include <cassert> 24 #include <cstdlib> 25 #include "uses_alloc_types.h" 26 #include "controlled_allocators.h" 27 28 #include "test_macros.h" 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 using PairIn = std::pair<int&, int const&&>; 40 int x = 42; 41 const int y = 101; 42 using Alloc = CountingAllocator<Pair>; 43 using SA = std::scoped_allocator_adaptor<Alloc>; 44 static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); 45 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 46 assert(ptr != nullptr); 47 Alloc CA(P); 48 SA A(CA); 49 PairIn in(x, std::move(y)); 50 A.construct(ptr, std::move(in)); 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); hvl_GenPanningTables(void)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 using PairIn = std::pair<int, int const&>; 67 int x = 42; 68 const int y = 101; 69 using Alloc = CountingAllocator<Pair>; 70 using SA = std::scoped_allocator_adaptor<Alloc>; 71 static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); 72 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 73 assert(ptr != nullptr); 74 Alloc CA(P); 75 SA A(CA); 76 PairIn in(x, y); 77 A.construct(ptr, std::move(in)); 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&, hvl_reset_some_stuff(struct hvl_tune * ht)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 using PairIn = std::pair<int&, int const&&>; 100 int x = 42; 101 int y = 101; 102 using Outer = CountingAllocator<Pair, 1>; 103 using Inner = CountingAllocator<Pair, 2>; 104 using SA = std::scoped_allocator_adaptor<Outer, Inner>; 105 using SAInner = std::scoped_allocator_adaptor<Inner>; 106 static_assert(!std::uses_allocator<T, Outer>::value, ""); 107 static_assert(std::uses_allocator<T, Inner>::value, ""); 108 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 109 assert(ptr != nullptr); 110 Outer O(POuter); 111 Inner I(PInner); 112 SA A(O, I); 113 PairIn in(x, std::move(y)); 114 A.construct(ptr, std::move(in)); 115 assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I)); 116 assert(checkConstruct<int const&&>(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 const&&, 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 using PairIn = std::pair<int, int const &>; 131 int x = 42; 132 int y = 101; 133 using Outer = CountingAllocator<Pair, 1>; 134 using Inner = CountingAllocator<Pair, 2>; 135 using SA = std::scoped_allocator_adaptor<Outer, Inner>; 136 using SAInner = std::scoped_allocator_adaptor<Inner>; 137 static_assert(!std::uses_allocator<T, Outer>::value, ""); 138 static_assert(std::uses_allocator<T, Inner>::value, ""); 139 Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 140 assert(ptr != nullptr); 141 Outer O(POuter); 142 Inner I(PInner); 143 SA A(O, I); 144 PairIn in(x, y); 145 A.construct(ptr, std::move(in)); 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(int, char**) { 157 test_no_inner_alloc(); 158 test_with_inner_alloc(); 159 160 return 0; 161 } 162