]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/bits/uses_allocator_args.h
8b95e8087a265a99f074e3b31bd013b3e6ac57af
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / uses_allocator_args.h
1 // Utility functions for uses-allocator construction -*- C++ -*-
2
3 // Copyright (C) 2019-2021 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /*
26 * Copyright (c) 1997-1999
27 * Silicon Graphics Computer Systems, Inc.
28 *
29 * Permission to use, copy, modify, distribute and sell this software
30 * and its documentation for any purpose is hereby granted without fee,
31 * provided that the above copyright notice appear in all copies and
32 * that both that copyright notice and this permission notice appear
33 * in supporting documentation. Silicon Graphics makes no
34 * representations about the suitability of this software for any
35 * purpose. It is provided "as is" without express or implied warranty.
36 *
37 */
38
39 /** @file include/bits/uses_allocator_args.h
40 * This is an internal header file, included by other library headers.
41 * Do not attempt to use it directly. @headername{memory}
42 */
43
44 #ifndef _USES_ALLOCATOR_ARGS
45 #define _USES_ALLOCATOR_ARGS 1
46
47 #pragma GCC system_header
48
49 #if __cplusplus > 201703L && __cpp_concepts
50
51 #include <new> // for placement operator new
52 #include <tuple> // for tuple, make_tuple, make_from_tuple
53 #include <bits/stl_construct.h> // construct_at
54 #include <bits/stl_pair.h> // pair
55
56 namespace std _GLIBCXX_VISIBILITY(default)
57 {
58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
59 template<typename _Tp>
60 inline constexpr bool __is_pair = false;
61 template<typename _Tp, typename _Up>
62 inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
63 template<typename _Tp, typename _Up>
64 inline constexpr bool __is_pair<const pair<_Tp, _Up>> = true;
65
66 template<typename _Tp>
67 concept _Std_pair = __is_pair<_Tp>;
68
69 /** @addtogroup allocators
70 * @{
71 */
72
73 // Not specified by C++20, used internally
74 #define __cpp_lib_make_obj_using_allocator 201811L
75
76 template<typename _Tp, typename _Alloc, typename... _Args>
77 constexpr auto
78 uses_allocator_construction_args(const _Alloc& __a,
79 _Args&&... __args) noexcept
80 requires (! _Std_pair<_Tp>)
81 {
82 if constexpr (uses_allocator_v<remove_cv_t<_Tp>, _Alloc>)
83 {
84 if constexpr (is_constructible_v<_Tp, allocator_arg_t,
85 const _Alloc&, _Args...>)
86 {
87 return tuple<allocator_arg_t, const _Alloc&, _Args&&...>(
88 allocator_arg, __a, std::forward<_Args>(__args)...);
89 }
90 else
91 {
92 static_assert(is_constructible_v<_Tp, _Args..., const _Alloc&>,
93 "construction with an allocator must be possible"
94 " if uses_allocator is true");
95
96 return tuple<_Args&&..., const _Alloc&>(
97 std::forward<_Args>(__args)..., __a);
98 }
99 }
100 else
101 {
102 static_assert(is_constructible_v<_Tp, _Args...>);
103
104 return tuple<_Args&&...>(std::forward<_Args>(__args)...);
105 }
106 }
107
108 template<_Std_pair _Tp, typename _Alloc, typename _Tuple1, typename _Tuple2>
109 constexpr auto
110 uses_allocator_construction_args(const _Alloc& __a, piecewise_construct_t,
111 _Tuple1&& __x, _Tuple2&& __y) noexcept;
112
113 template<_Std_pair _Tp, typename _Alloc>
114 constexpr auto
115 uses_allocator_construction_args(const _Alloc&) noexcept;
116
117 template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
118 constexpr auto
119 uses_allocator_construction_args(const _Alloc&, _Up&&, _Vp&&) noexcept;
120
121 template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
122 constexpr auto
123 uses_allocator_construction_args(const _Alloc&,
124 const pair<_Up, _Vp>&) noexcept;
125
126 template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
127 constexpr auto
128 uses_allocator_construction_args(const _Alloc&, pair<_Up, _Vp>&&) noexcept;
129
130 template<_Std_pair _Tp, typename _Alloc, typename _Tuple1, typename _Tuple2>
131 constexpr auto
132 uses_allocator_construction_args(const _Alloc& __a, piecewise_construct_t,
133 _Tuple1&& __x, _Tuple2&& __y) noexcept
134 {
135 using _Tp1 = typename _Tp::first_type;
136 using _Tp2 = typename _Tp::second_type;
137
138 return std::make_tuple(piecewise_construct,
139 std::apply([&__a](auto&&... __args1) {
140 return std::uses_allocator_construction_args<_Tp1>(
141 __a, std::forward<decltype(__args1)>(__args1)...);
142 }, std::forward<_Tuple1>(__x)),
143 std::apply([&__a](auto&&... __args2) {
144 return std::uses_allocator_construction_args<_Tp2>(
145 __a, std::forward<decltype(__args2)>(__args2)...);
146 }, std::forward<_Tuple2>(__y)));
147 }
148
149 template<_Std_pair _Tp, typename _Alloc>
150 constexpr auto
151 uses_allocator_construction_args(const _Alloc& __a) noexcept
152 {
153 using _Tp1 = typename _Tp::first_type;
154 using _Tp2 = typename _Tp::second_type;
155
156 return std::make_tuple(piecewise_construct,
157 std::uses_allocator_construction_args<_Tp1>(__a),
158 std::uses_allocator_construction_args<_Tp2>(__a));
159 }
160
161 template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
162 constexpr auto
163 uses_allocator_construction_args(const _Alloc& __a, _Up&& __u, _Vp&& __v)
164 noexcept
165 {
166 using _Tp1 = typename _Tp::first_type;
167 using _Tp2 = typename _Tp::second_type;
168
169 return std::make_tuple(piecewise_construct,
170 std::uses_allocator_construction_args<_Tp1>(__a,
171 std::forward<_Up>(__u)),
172 std::uses_allocator_construction_args<_Tp2>(__a,
173 std::forward<_Vp>(__v)));
174 }
175
176 template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
177 constexpr auto
178 uses_allocator_construction_args(const _Alloc& __a,
179 const pair<_Up, _Vp>& __pr) noexcept
180 {
181 using _Tp1 = typename _Tp::first_type;
182 using _Tp2 = typename _Tp::second_type;
183
184 return std::make_tuple(piecewise_construct,
185 std::uses_allocator_construction_args<_Tp1>(__a, __pr.first),
186 std::uses_allocator_construction_args<_Tp2>(__a, __pr.second));
187 }
188
189 template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
190 constexpr auto
191 uses_allocator_construction_args(const _Alloc& __a,
192 pair<_Up, _Vp>&& __pr) noexcept
193 {
194 using _Tp1 = typename _Tp::first_type;
195 using _Tp2 = typename _Tp::second_type;
196
197 return std::make_tuple(piecewise_construct,
198 std::uses_allocator_construction_args<_Tp1>(__a,
199 std::move(__pr).first),
200 std::uses_allocator_construction_args<_Tp2>(__a,
201 std::move(__pr).second));
202 }
203
204 template<typename _Tp, typename _Alloc, typename... _Args>
205 inline _Tp
206 make_obj_using_allocator(const _Alloc& __a, _Args&&... __args)
207 {
208 return std::make_from_tuple<_Tp>(
209 std::uses_allocator_construction_args<_Tp>(__a,
210 std::forward<_Args>(__args)...));
211 }
212
213 template<typename _Tp, typename _Alloc, typename... _Args>
214 inline _Tp*
215 uninitialized_construct_using_allocator(_Tp* __p, const _Alloc& __a,
216 _Args&&... __args)
217 {
218 return std::apply([&](auto&&... __xs) {
219 return std::construct_at(__p, std::forward<decltype(__xs)>(__xs)...);
220 }, std::uses_allocator_construction_args<_Tp>(__a,
221 std::forward<_Args>(__args)...));
222 }
223 // @}
224 _GLIBCXX_END_NAMESPACE_VERSION
225 } // namespace std
226 #endif // C++20
227 #endif // _USES_ALLOCATOR_ARGS