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
30void test_no_inner_alloc() {
31 using VoidAlloc = CountingAllocator<void>;
32 AllocController P;
33 {
34 using T = UsesAllocatorV1<VoidAlloc, 1>;
35 using U = UsesAllocatorV2<VoidAlloc, 1>;
36 using Pair = std::pair<T, U>;
37 using PairIn = std::pair<int&, int const&&>;
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 PairIn in(x, std::move(y));
48 A.construct(ptr, std::move(in));
49 assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
50 assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
51#if TEST_STD_VER >= 20
52 assert((P.checkConstruct<std::piecewise_construct_t&&,
53 std::tuple<std::allocator_arg_t, const SA&, int&>&&,
54 std::tuple<int const&&, const SA&>&& >(CA, ptr)));
55#else
56 assert((P.checkConstruct<std::piecewise_construct_t const&,
57 std::tuple<std::allocator_arg_t, SA&, int&>&&,
58 std::tuple<int const&&, SA&>&& >(CA, ptr)));
59#endif
60 A.destroy(ptr);
61 std::free(ptr: ptr);
62 }
63 P.reset();
64 {
65 using T = UsesAllocatorV3<VoidAlloc, 1>;
66 using U = NotUsesAllocator<VoidAlloc, 1>;
67 using Pair = std::pair<T, U>;
68 using PairIn = std::pair<int, int const&>;
69 int x = 42;
70 const int y = 101;
71 using Alloc = CountingAllocator<Pair>;
72 using SA = std::scoped_allocator_adaptor<Alloc>;
73 static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
74 Pair* ptr = (Pair*)std::malloc(sizeof(Pair));
75 assert(ptr != nullptr);
76 Alloc CA(P);
77 SA A(CA);
78 PairIn in(x, y);
79 A.construct(ptr, std::move(in));
80 assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
81 assert(checkConstruct<int const&>(ptr->second, UA_None));
82#if TEST_STD_VER >= 20
83 assert((P.checkConstruct<std::piecewise_construct_t&&,
84 std::tuple<std::allocator_arg_t, const SA&, int&&>&&,
85 std::tuple<int const&>&& >(CA, ptr)));
86#else
87 assert((P.checkConstruct<std::piecewise_construct_t const&,
88 std::tuple<std::allocator_arg_t, SA&, int&&>&&,
89 std::tuple<int const&>&& >(CA, ptr)));
90#endif
91 A.destroy(ptr);
92 std::free(ptr: ptr);
93 }
94}
95
96void test_with_inner_alloc() {
97 using VoidAlloc2 = CountingAllocator<void, 2>;
98
99 AllocController POuter;
100 AllocController PInner;
101 {
102 using T = UsesAllocatorV1<VoidAlloc2, 1>;
103 using U = UsesAllocatorV2<VoidAlloc2, 1>;
104 using Pair = std::pair<T, U>;
105 using PairIn = std::pair<int&, int const&&>;
106 int x = 42;
107 int y = 101;
108 using Outer = CountingAllocator<Pair, 1>;
109 using Inner = CountingAllocator<Pair, 2>;
110 using SA = std::scoped_allocator_adaptor<Outer, Inner>;
111 using SAInner = std::scoped_allocator_adaptor<Inner>;
112 static_assert(!std::uses_allocator<T, Outer>::value, "");
113 static_assert(std::uses_allocator<T, Inner>::value, "");
114 Pair* ptr = (Pair*)std::malloc(sizeof(Pair));
115 assert(ptr != nullptr);
116 Outer O(POuter);
117 Inner I(PInner);
118 SA A(O, I);
119 PairIn in(x, std::move(y));
120 A.construct(ptr, std::move(in));
121 assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
122 assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast));
123#if TEST_STD_VER >= 20
124 assert((POuter.checkConstruct<std::piecewise_construct_t&&,
125 std::tuple<std::allocator_arg_t, const SAInner&, int&>&&,
126 std::tuple<int const&&, const SAInner&>&& >(O, ptr)));
127#else
128 assert((POuter.checkConstruct<std::piecewise_construct_t const&,
129 std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
130 std::tuple<int const&&, SAInner&>&& >(O, ptr)));
131#endif
132 A.destroy(ptr);
133 std::free(ptr: ptr);
134 }
135 PInner.reset();
136 POuter.reset();
137 {
138 using T = UsesAllocatorV3<VoidAlloc2, 1>;
139 using U = NotUsesAllocator<VoidAlloc2, 1>;
140 using Pair = std::pair<T, U>;
141 using PairIn = std::pair<int, int const&>;
142 int x = 42;
143 int y = 101;
144 using Outer = CountingAllocator<Pair, 1>;
145 using Inner = CountingAllocator<Pair, 2>;
146 using SA = std::scoped_allocator_adaptor<Outer, Inner>;
147 using SAInner = std::scoped_allocator_adaptor<Inner>;
148 static_assert(!std::uses_allocator<T, Outer>::value, "");
149 static_assert(std::uses_allocator<T, Inner>::value, "");
150 Pair* ptr = (Pair*)std::malloc(sizeof(Pair));
151 assert(ptr != nullptr);
152 Outer O(POuter);
153 Inner I(PInner);
154 SA A(O, I);
155 PairIn in(x, y);
156 A.construct(ptr, std::move(in));
157 assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
158 assert(checkConstruct<int const&>(ptr->second, UA_None));
159#if TEST_STD_VER >= 20
160 assert((POuter.checkConstruct<std::piecewise_construct_t&&,
161 std::tuple<std::allocator_arg_t, const SAInner&, int&&>&&,
162 std::tuple<int const&>&& >(O, ptr)));
163#else
164 assert((POuter.checkConstruct<std::piecewise_construct_t const&,
165 std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
166 std::tuple<int const&>&& >(O, ptr)));
167#endif
168 A.destroy(ptr);
169 std::free(ptr: ptr);
170 }
171}
172int main(int, char**) {
173 test_no_inner_alloc();
174 test_with_inner_alloc();
175
176 return 0;
177}
178

source code of libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp