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

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