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