]>
Commit | Line | Data |
---|---|---|
b8214660 JW |
1 | // Uses-allocator Construction -*- C++ -*- |
2 | ||
a5544970 | 3 | // Copyright (C) 2010-2019 Free Software Foundation, Inc. |
b8214660 JW |
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 | #ifndef _USES_ALLOCATOR_H | |
26 | #define _USES_ALLOCATOR_H 1 | |
27 | ||
734f5023 | 28 | #if __cplusplus < 201103L |
b8214660 JW |
29 | # include <bits/c++0x_warning.h> |
30 | #else | |
31 | ||
32 | #include <type_traits> | |
e525d78c | 33 | #include <bits/move.h> |
b8214660 JW |
34 | |
35 | namespace std _GLIBCXX_VISIBILITY(default) | |
36 | { | |
37 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
38 | ||
4f3c75ba | 39 | // This is used for std::experimental::erased_type from Library Fundamentals. |
bfeffbd1 FY |
40 | struct __erased_type { }; |
41 | ||
4f3c75ba JW |
42 | // This also supports the "type-erased allocator" protocol from the |
43 | // Library Fundamentals TS, where allocator_type is erased_type. | |
44 | // The second condition will always be false for types not using the TS. | |
bfeffbd1 FY |
45 | template<typename _Alloc, typename _Tp> |
46 | using __is_erased_or_convertible | |
4f3c75ba | 47 | = __or_<is_convertible<_Alloc, _Tp>, is_same<_Tp, __erased_type>>; |
bfeffbd1 | 48 | |
b8214660 | 49 | /// [allocator.tag] |
269fa2a9 | 50 | struct allocator_arg_t { explicit allocator_arg_t() = default; }; |
b8214660 | 51 | |
288695f7 DK |
52 | _GLIBCXX17_INLINE constexpr allocator_arg_t allocator_arg = |
53 | allocator_arg_t(); | |
b8214660 | 54 | |
847e9cf8 | 55 | template<typename _Tp, typename _Alloc, typename = __void_t<>> |
b8214660 | 56 | struct __uses_allocator_helper |
314efb66 | 57 | : false_type { }; |
b8214660 JW |
58 | |
59 | template<typename _Tp, typename _Alloc> | |
847e9cf8 JW |
60 | struct __uses_allocator_helper<_Tp, _Alloc, |
61 | __void_t<typename _Tp::allocator_type>> | |
bfeffbd1 | 62 | : __is_erased_or_convertible<_Alloc, typename _Tp::allocator_type>::type |
b8214660 JW |
63 | { }; |
64 | ||
65 | /// [allocator.uses.trait] | |
66 | template<typename _Tp, typename _Alloc> | |
67 | struct uses_allocator | |
314efb66 | 68 | : __uses_allocator_helper<_Tp, _Alloc>::type |
b8214660 JW |
69 | { }; |
70 | ||
b8214660 | 71 | struct __uses_alloc_base { }; |
314efb66 | 72 | |
b8214660 | 73 | struct __uses_alloc0 : __uses_alloc_base |
314efb66 JW |
74 | { |
75 | struct _Sink { void operator=(const void*) { } } _M_a; | |
76 | }; | |
77 | ||
b8214660 JW |
78 | template<typename _Alloc> |
79 | struct __uses_alloc1 : __uses_alloc_base { const _Alloc* _M_a; }; | |
314efb66 | 80 | |
b8214660 JW |
81 | template<typename _Alloc> |
82 | struct __uses_alloc2 : __uses_alloc_base { const _Alloc* _M_a; }; | |
83 | ||
314efb66 | 84 | template<bool, typename _Tp, typename _Alloc, typename... _Args> |
b8214660 JW |
85 | struct __uses_alloc; |
86 | ||
87 | template<typename _Tp, typename _Alloc, typename... _Args> | |
88 | struct __uses_alloc<true, _Tp, _Alloc, _Args...> | |
89 | : conditional< | |
90 | is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value, | |
91 | __uses_alloc1<_Alloc>, | |
92 | __uses_alloc2<_Alloc>>::type | |
d7c1581c JW |
93 | { |
94 | static_assert(__or_< | |
95 | is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>, | |
96 | is_constructible<_Tp, _Args..., _Alloc>>::value, "construction with" | |
97 | " an allocator must be possible if uses_allocator is true"); | |
98 | }; | |
b8214660 JW |
99 | |
100 | template<typename _Tp, typename _Alloc, typename... _Args> | |
101 | struct __uses_alloc<false, _Tp, _Alloc, _Args...> | |
102 | : __uses_alloc0 { }; | |
103 | ||
104 | template<typename _Tp, typename _Alloc, typename... _Args> | |
314efb66 JW |
105 | using __uses_alloc_t = |
106 | __uses_alloc<uses_allocator<_Tp, _Alloc>::value, _Tp, _Alloc, _Args...>; | |
b8214660 JW |
107 | |
108 | template<typename _Tp, typename _Alloc, typename... _Args> | |
314efb66 | 109 | inline __uses_alloc_t<_Tp, _Alloc, _Args...> |
b8214660 JW |
110 | __use_alloc(const _Alloc& __a) |
111 | { | |
314efb66 | 112 | __uses_alloc_t<_Tp, _Alloc, _Args...> __ret; |
f885fa89 | 113 | __ret._M_a = std::__addressof(__a); |
b8214660 JW |
114 | return __ret; |
115 | } | |
318c48e3 JW |
116 | |
117 | template<typename _Tp, typename _Alloc, typename... _Args> | |
118 | void | |
119 | __use_alloc(const _Alloc&&) = delete; | |
120 | ||
8c914227 VV |
121 | #if __cplusplus > 201402L |
122 | template <typename _Tp, typename _Alloc> | |
288695f7 DK |
123 | inline constexpr bool uses_allocator_v = |
124 | uses_allocator<_Tp, _Alloc>::value; | |
8c914227 | 125 | #endif // C++17 |
b8214660 | 126 | |
197c757c TS |
127 | template<template<typename...> class _Predicate, |
128 | typename _Tp, typename _Alloc, typename... _Args> | |
129 | struct __is_uses_allocator_predicate | |
130 | : conditional<uses_allocator<_Tp, _Alloc>::value, | |
131 | __or_<_Predicate<_Tp, allocator_arg_t, _Alloc, _Args...>, | |
132 | _Predicate<_Tp, _Args..., _Alloc>>, | |
133 | _Predicate<_Tp, _Args...>>::type { }; | |
134 | ||
135 | template<typename _Tp, typename _Alloc, typename... _Args> | |
136 | struct __is_uses_allocator_constructible | |
137 | : __is_uses_allocator_predicate<is_constructible, _Tp, _Alloc, _Args...> | |
138 | { }; | |
139 | ||
0aeb81f8 | 140 | #if __cplusplus >= 201402L |
197c757c | 141 | template<typename _Tp, typename _Alloc, typename... _Args> |
288695f7 | 142 | _GLIBCXX17_INLINE constexpr bool __is_uses_allocator_constructible_v = |
197c757c | 143 | __is_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value; |
0aeb81f8 | 144 | #endif // C++14 |
197c757c TS |
145 | |
146 | template<typename _Tp, typename _Alloc, typename... _Args> | |
147 | struct __is_nothrow_uses_allocator_constructible | |
148 | : __is_uses_allocator_predicate<is_nothrow_constructible, | |
149 | _Tp, _Alloc, _Args...> | |
150 | { }; | |
151 | ||
152 | ||
0aeb81f8 | 153 | #if __cplusplus >= 201402L |
197c757c | 154 | template<typename _Tp, typename _Alloc, typename... _Args> |
288695f7 DK |
155 | _GLIBCXX17_INLINE constexpr bool |
156 | __is_nothrow_uses_allocator_constructible_v = | |
197c757c | 157 | __is_nothrow_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value; |
0aeb81f8 | 158 | #endif // C++14 |
197c757c TS |
159 | |
160 | template<typename _Tp, typename... _Args> | |
161 | void __uses_allocator_construct_impl(__uses_alloc0 __a, _Tp* __ptr, | |
162 | _Args&&... __args) | |
64626fca | 163 | { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)...); } |
197c757c TS |
164 | |
165 | template<typename _Tp, typename _Alloc, typename... _Args> | |
166 | void __uses_allocator_construct_impl(__uses_alloc1<_Alloc> __a, _Tp* __ptr, | |
167 | _Args&&... __args) | |
64626fca JW |
168 | { |
169 | ::new ((void*)__ptr) _Tp(allocator_arg, *__a._M_a, | |
170 | std::forward<_Args>(__args)...); | |
171 | } | |
197c757c TS |
172 | |
173 | template<typename _Tp, typename _Alloc, typename... _Args> | |
174 | void __uses_allocator_construct_impl(__uses_alloc2<_Alloc> __a, _Tp* __ptr, | |
175 | _Args&&... __args) | |
64626fca | 176 | { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)..., *__a._M_a); } |
197c757c TS |
177 | |
178 | template<typename _Tp, typename _Alloc, typename... _Args> | |
179 | void __uses_allocator_construct(const _Alloc& __a, _Tp* __ptr, | |
180 | _Args&&... __args) | |
181 | { | |
b479fbad JW |
182 | std::__uses_allocator_construct_impl( |
183 | std::__use_alloc<_Tp, _Alloc, _Args...>(__a), __ptr, | |
184 | std::forward<_Args>(__args)...); | |
197c757c TS |
185 | } |
186 | ||
b8214660 JW |
187 | _GLIBCXX_END_NAMESPACE_VERSION |
188 | } // namespace std | |
189 | ||
190 | #endif | |
191 | #endif |