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

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