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

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