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