1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef TEST_SUPPORT_DEDUCTION_GUIDES_SFINAE_CHECKS_H
10 #define TEST_SUPPORT_DEDUCTION_GUIDES_SFINAE_CHECKS_H
12 #include <initializer_list>
14 #include <type_traits>
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
36 // - "bad" input iterators (that is, a type not qualifying as an input
39 template<template<typename
...> class Container
, typename InstantiatedContainer
>
40 constexpr void SequenceContainerDeductionGuidesSfinaeAway() {
41 using Alloc
= std::allocator
<int>;
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
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
>);
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
74 // - "bad" input iterators (that is, a type not qualifying as an input
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
>;
88 // The only requirement in the Standard is that integral types cannot be
89 // considered input iterators, beyond that it is unspecified.
91 #ifdef _LIBCPP_VERSION
92 using OutputIter
= std::insert_iterator
<InstantiatedContainer
>;
93 #endif // _LIBCPP_VERSION
94 using AllocAsComp
= Alloc
;
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
142 // For unordered containers the deduction guides should be SFINAE'd away when
144 // - "bad" input iterators (that is, a type not qualifying as an input
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
>;
161 // The only requirement in the Standard is that integral types cannot be
162 // considered input iterators, beyond that it is unspecified.
164 #ifdef _LIBCPP_VERSION
165 using OutputIter
= std::insert_iterator
<InstantiatedContainer
>;
166 #endif // _LIBCPP_VERSION
167 using AllocAsHash
= Alloc
;
168 using AllocAsPred
= Alloc
;
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)
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)
215 SFINAEs_away
<Container
, Iter
, Iter
, size_t, BadHash
, Pred
, Alloc
>);
216 // Cannot deduce from (iter, iter, buckets, ALLOC_as_hash, pred, alloc)
218 SFINAEs_away
<Container
, Iter
, Iter
, size_t, AllocAsHash
, Pred
, Alloc
>);
219 // Cannot deduce from (iter, iter, buckets, hash, ALLOC_as_pred, alloc)
221 SFINAEs_away
<Container
, Iter
, Iter
, size_t, Hash
, AllocAsPred
, Alloc
>);
222 // Cannot deduce from (iter, iter, buckets, hash, pred, BAD_alloc)
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)
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
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)
279 SFINAEs_away
<Container
, InitList
, size_t, BadHash
, Pred
, Alloc
>);
280 // Cannot deduce from (init_list, buckets, ALLOC_as_hash, pred, alloc)
282 SFINAEs_away
<Container
, InitList
, size_t, AllocAsHash
, Pred
, Alloc
>);
283 // Cannot deduce from (init_list, buckets, hash, ALLOC_as_pred, alloc)
285 SFINAEs_away
<Container
, InitList
, size_t, Hash
, AllocAsPred
, Alloc
>);
286 // Cannot deduce from (init_list, buckets, hash, pred, BAD_alloc)
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