[WebAssembly] Fix asan issue from https://reviews.llvm.org/D121349
[llvm-project.git] / libcxx / test / support / deduction_guides_sfinae_checks.h
blobf1f31c8e8c3848e814222b90c2cc595cb6c716ac
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 //===----------------------------------------------------------------------===//
9 #ifndef TEST_SUPPORT_DEDUCTION_GUIDES_SFINAE_CHECKS_H
10 #define TEST_SUPPORT_DEDUCTION_GUIDES_SFINAE_CHECKS_H
12 #include <initializer_list>
13 #include <memory>
14 #include <type_traits>
15 #include <utility>
17 #include "test_macros.h"
19 // `SFINAEs_away` template variable checks whether the template arguments for
20 // a given template class `Instantiated` can be deduced from the given
21 // constructor parameter types `CtrArgs` using CTAD.
23 template<template<typename ...> class Instantiated, class ...CtrArgs,
24 class = decltype(Instantiated(std::declval<CtrArgs>()...))>
25 std::false_type SFINAEs_away_impl(int);
27 template<template<typename ...> class Instantiated, class ...CtrArgs>
28 std::true_type SFINAEs_away_impl(...);
30 template<template<typename ...> class Instantiated, class ...CtrArgs>
31 constexpr bool SFINAEs_away =
32 decltype(SFINAEs_away_impl<Instantiated, CtrArgs...>(0))::value;
34 // For sequence containers the deduction guides should be SFINAE'd away when
35 // given:
36 // - "bad" input iterators (that is, a type not qualifying as an input
37 // iterator);
38 // - a bad allocator.
39 template<template<typename ...> class Container, typename InstantiatedContainer>
40 constexpr void SequenceContainerDeductionGuidesSfinaeAway() {
41 using Alloc = std::allocator<int>;
42 using Iter = int*;
44 struct BadAlloc {};
45 // Note: the only requirement in the Standard is that integral types cannot be
46 // considered input iterators; however, this doesn't work for sequence
47 // containers because they have constructors of the form `(size_type count,
48 // const value_type& value)`. These constructors would be used when passing
49 // two integral types and would deduce `value_type` to be an integral type.
50 #ifdef _LIBCPP_VERSION
51 using OutputIter = std::insert_iterator<InstantiatedContainer>;
52 #endif // _LIBCPP_VERSION
54 // (iter, iter)
56 // Cannot deduce from (BAD_iter, BAD_iter)
57 LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter>);
59 // (iter, iter, alloc)
61 // Cannot deduce from (BAD_iter, BAD_iter, alloc)
62 LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, Alloc>);
63 // Cannot deduce from (iter, iter, BAD_alloc)
64 static_assert(SFINAEs_away<Container, Iter, Iter, BadAlloc>);
66 // (alloc)
68 // Cannot deduce from (alloc)
69 static_assert(SFINAEs_away<Container, Alloc>);
72 // For associative containers the deduction guides should be SFINAE'd away when
73 // given:
74 // - "bad" input iterators (that is, a type not qualifying as an input
75 // iterator);
76 // - a bad allocator;
77 // - an allocator in place of a comparator.
79 template<template<typename ...> class Container, typename InstantiatedContainer>
80 constexpr void AssociativeContainerDeductionGuidesSfinaeAway() {
81 using ValueType = typename InstantiatedContainer::value_type;
82 using Comp = std::less<int>;
83 using Alloc = std::allocator<ValueType>;
84 using Iter = ValueType*;
85 using InitList = std::initializer_list<ValueType>;
87 struct BadAlloc {};
88 // The only requirement in the Standard is that integral types cannot be
89 // considered input iterators, beyond that it is unspecified.
90 using BadIter = int;
91 #ifdef _LIBCPP_VERSION
92 using OutputIter = std::insert_iterator<InstantiatedContainer>;
93 #endif // _LIBCPP_VERSION
94 using AllocAsComp = Alloc;
96 // (iter, iter)
98 // Cannot deduce from (BAD_iter, BAD_iter)
99 static_assert(SFINAEs_away<Container, BadIter, BadIter>);
100 LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter>);
102 // (iter, iter, comp)
104 // Cannot deduce from (BAD_iter, BAD_iter, comp)
105 static_assert(SFINAEs_away<Container, BadIter, BadIter, Comp>);
106 LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, Comp>);
108 // (iter, iter, comp, alloc)
110 // Cannot deduce from (BAD_iter, BAD_iter, comp, alloc)
111 static_assert(SFINAEs_away<Container, BadIter, BadIter, Comp, Alloc>);
112 LIBCPP_STATIC_ASSERT(
113 SFINAEs_away<Container, OutputIter, OutputIter, Comp, Alloc>);
114 // Cannot deduce from (iter, iter, ALLOC_as_comp, alloc)
115 static_assert(SFINAEs_away<Container, Iter, Iter, AllocAsComp, Alloc>);
116 // Cannot deduce from (iter, iter, comp, BAD_alloc)
117 static_assert(SFINAEs_away<Container, Iter, Iter, Comp, BadAlloc>);
119 // (iter, iter, alloc)
121 // Cannot deduce from (BAD_iter, BAD_iter, alloc)
122 static_assert(SFINAEs_away<Container, BadIter, BadIter, Alloc>);
123 LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, Alloc>);
124 // Note: (iter, iter, BAD_alloc) is interpreted as (iter, iter, comp)
125 // instead and fails upon instantiation. There is no requirement to SFINAE
126 // away bad comparators.
128 // (init_list, comp, alloc)
130 // Cannot deduce from (init_list, ALLOC_as_comp, alloc)
131 static_assert(SFINAEs_away<Container, InitList, AllocAsComp, Alloc>);
132 // Cannot deduce from (init_list, comp, BAD_alloc)
133 static_assert(SFINAEs_away<Container, InitList, Comp, BadAlloc>);
135 // (init_list, alloc)
137 // Note: (init_list, BAD_alloc) is interpreted as (init_list, comp) instead
138 // and fails upon instantiation. There is no requirement to SFINAE away bad
139 // comparators.
142 // For unordered containers the deduction guides should be SFINAE'd away when
143 // given:
144 // - "bad" input iterators (that is, a type not qualifying as an input
145 // iterator);
146 // - a bad allocator;
147 // - a bad hash functor (an integral type in place of a hash);
148 // - an allocator in place of a hash functor;
149 // - an allocator in place of a predicate.
150 template<template<typename ...> class Container, typename InstantiatedContainer>
151 constexpr void UnorderedContainerDeductionGuidesSfinaeAway() {
152 using ValueType = typename InstantiatedContainer::value_type;
153 using Pred = std::equal_to<int>;
154 using Hash = std::hash<int>;
155 using Alloc = std::allocator<ValueType>;
156 using Iter = ValueType*;
157 using InitList = std::initializer_list<ValueType>;
159 using BadHash = int;
160 struct BadAlloc {};
161 // The only requirement in the Standard is that integral types cannot be
162 // considered input iterators, beyond that it is unspecified.
163 using BadIter = int;
164 #ifdef _LIBCPP_VERSION
165 using OutputIter = std::insert_iterator<InstantiatedContainer>;
166 #endif // _LIBCPP_VERSION
167 using AllocAsHash = Alloc;
168 using AllocAsPred = Alloc;
170 // (iter, iter)
172 // Cannot deduce from (BAD_iter, BAD_iter)
173 static_assert(SFINAEs_away<Container, BadIter, BadIter>);
174 LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter>);
176 // (iter, iter, buckets)
178 // Cannot deduce from (BAD_iter, BAD_iter, buckets)
179 static_assert(SFINAEs_away<Container, BadIter, BadIter, size_t>);
180 LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, size_t>);
182 // (iter, iter, buckets, hash)
184 // Cannot deduce from (BAD_iter, BAD_iter, buckets, hash)
185 static_assert(SFINAEs_away<Container, BadIter, BadIter, size_t, Hash>);
186 LIBCPP_STATIC_ASSERT(
187 SFINAEs_away<Container, OutputIter, OutputIter, size_t, Hash>);
188 // Cannot deduce from (iter, iter, buckets, BAD_hash)
189 static_assert(SFINAEs_away<Container, Iter, Iter, size_t, BadHash>);
190 // Note: (iter, iter, buckets, ALLOC_as_hash) is allowed -- it just calls
191 // (iter, iter, buckets, alloc)
193 // (iter, iter, buckets, hash, pred)
195 // Cannot deduce from (BAD_iter, BAD_iter, buckets, hash, pred)
196 static_assert(SFINAEs_away<Container, BadIter, BadIter, size_t, Hash, Pred>);
197 LIBCPP_STATIC_ASSERT(
198 SFINAEs_away<Container, OutputIter, OutputIter, size_t, Hash, Pred>);
199 // Cannot deduce from (iter, iter, buckets, BAD_hash, pred)
200 static_assert(SFINAEs_away<Container, Iter, Iter, size_t, BadHash, Pred>);
201 // Cannot deduce from (iter, iter, buckets, ALLOC_as_hash, pred)
202 static_assert(SFINAEs_away<Container, Iter, Iter, size_t, AllocAsHash, Pred>);
203 // Note: (iter, iter, buckets, hash, ALLOC_as_pred) is allowed -- it just
204 // calls (iter, iter, buckets, hash, alloc)
206 // (iter, iter, buckets, hash, pred, alloc)
208 // Cannot deduce from (BAD_iter, BAD_iter, buckets, hash, pred, alloc)
209 static_assert(
210 SFINAEs_away<Container, BadIter, BadIter, size_t, Hash, Pred, Alloc>);
211 LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter,
212 size_t, Hash, Pred, Alloc>);
213 // Cannot deduce from (iter, iter, buckets, BAD_hash, pred, alloc)
214 static_assert(
215 SFINAEs_away<Container, Iter, Iter, size_t, BadHash, Pred, Alloc>);
216 // Cannot deduce from (iter, iter, buckets, ALLOC_as_hash, pred, alloc)
217 static_assert(
218 SFINAEs_away<Container, Iter, Iter, size_t, AllocAsHash, Pred, Alloc>);
219 // Cannot deduce from (iter, iter, buckets, hash, ALLOC_as_pred, alloc)
220 static_assert(
221 SFINAEs_away<Container, Iter, Iter, size_t, Hash, AllocAsPred, Alloc>);
222 // Cannot deduce from (iter, iter, buckets, hash, pred, BAD_alloc)
223 static_assert(
224 SFINAEs_away<Container, Iter, Iter, size_t, Hash, Pred, BadAlloc>);
226 // (iter, iter, buckets, alloc)
228 // Cannot deduce from (BAD_iter, BAD_iter, buckets, alloc)
229 static_assert(SFINAEs_away<Container, BadIter, BadIter, size_t, Alloc>);
230 LIBCPP_STATIC_ASSERT(
231 SFINAEs_away<Container, OutputIter, OutputIter, size_t, Alloc>);
232 // Note: (iter, iter, buckets, BAD_alloc) is interpreted as (iter, iter,
233 // buckets, hash), which is valid because the only requirement for the hash
234 // parameter is that it's not integral.
236 // (iter, iter, alloc)
238 // Cannot deduce from (BAD_iter, BAD_iter, alloc)
239 static_assert(SFINAEs_away<Container, BadIter, BadIter, Alloc>);
240 LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, Alloc>);
241 // Cannot deduce from (iter, iter, BAD_alloc)
242 static_assert(SFINAEs_away<Container, Iter, Iter, BadAlloc>);
244 // (iter, iter, buckets, hash, alloc)
246 // Cannot deduce from (BAD_iter, BAD_iter, buckets, hash, alloc)
247 static_assert(SFINAEs_away<Container, BadIter, BadIter, size_t, Hash, Alloc>);
248 LIBCPP_STATIC_ASSERT(
249 SFINAEs_away<Container, OutputIter, OutputIter, size_t, Hash, Alloc>);
250 // Cannot deduce from (iter, iter, buckets, BAD_hash, alloc)
251 static_assert(SFINAEs_away<Container, Iter, Iter, size_t, BadHash, Alloc>);
252 // Cannot deduce from (iter, iter, buckets, ALLOC_as_hash, alloc)
253 static_assert(
254 SFINAEs_away<Container, Iter, Iter, size_t, AllocAsHash, Alloc>);
255 // Note: (iter, iter, buckets, hash, BAD_alloc) is interpreted as (iter, iter,
256 // buckets, hash, pred), which is valid because there are no requirements for
257 // the predicate.
259 // (init_list, buckets, hash)
261 // Cannot deduce from (init_list, buckets, BAD_hash)
262 static_assert(SFINAEs_away<Container, InitList, size_t, BadHash>);
263 // Note: (init_list, buckets, ALLOC_as_hash) is interpreted as (init_list,
264 // buckets, alloc), which is valid.
266 // (init_list, buckets, hash, pred)
268 // Cannot deduce from (init_list, buckets, BAD_hash, pred)
269 static_assert(SFINAEs_away<Container, InitList, size_t, BadHash, Pred>);
270 // Cannot deduce from (init_list, buckets, ALLOC_as_hash, pred)
271 static_assert(SFINAEs_away<Container, InitList, size_t, AllocAsHash, Pred>);
272 // Note: (init_list, buckets, hash, ALLOC_as_pred) is interpreted as
273 // (init_list, buckets, hash, alloc), which is valid.
275 // (init_list, buckets, hash, pred, alloc)
277 // Cannot deduce from (init_list, buckets, BAD_hash, pred, alloc)
278 static_assert(
279 SFINAEs_away<Container, InitList, size_t, BadHash, Pred, Alloc>);
280 // Cannot deduce from (init_list, buckets, ALLOC_as_hash, pred, alloc)
281 static_assert(
282 SFINAEs_away<Container, InitList, size_t, AllocAsHash, Pred, Alloc>);
283 // Cannot deduce from (init_list, buckets, hash, ALLOC_as_pred, alloc)
284 static_assert(
285 SFINAEs_away<Container, InitList, size_t, Hash, AllocAsPred, Alloc>);
286 // Cannot deduce from (init_list, buckets, hash, pred, BAD_alloc)
287 static_assert(
288 SFINAEs_away<Container, InitList, size_t, Hash, Pred, BadAlloc>);
290 // (init_list, buckets, alloc)
292 // Note: (init_list, buckets, BAD_alloc) is interpreted as (init_list,
293 // buckets, hash), which is valid because the only requirement for the hash
294 // parameter is that it's not integral.
296 // (init_list, buckets, hash, alloc)
298 // Cannot deduce from (init_list, buckets, BAD_hash, alloc)
299 static_assert(SFINAEs_away<Container, InitList, size_t, BadHash, Alloc>);
300 // Cannot deduce from (init_list, buckets, ALLOC_as_hash, alloc)
301 static_assert(SFINAEs_away<Container, InitList, size_t, AllocAsHash, Alloc>);
303 // (init_list, alloc)
305 // Cannot deduce from (init_list, BAD_alloc)
306 static_assert(SFINAEs_away<Container, InitList, BadAlloc>);
309 #endif // TEST_SUPPORT_DEDUCTION_GUIDES_SFINAE_CHECKS_H