xref: /llvm-project/libcxx/test/support/deduction_guides_sfinae_checks.h (revision 316634ff5925481201a7b27d5f806cc2361cf4f2)
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 #ifndef TEST_SUPPORT_DEDUCTION_GUIDES_SFINAE_CHECKS_H
10 #define TEST_SUPPORT_DEDUCTION_GUIDES_SFINAE_CHECKS_H
11 
12 #include <cstddef>
13 #include <functional>
14 #include <initializer_list>
15 #include <iterator>
16 #include <memory>
17 #include <type_traits>
18 #include <utility>
19 #include <vector>
20 
21 #include "test_macros.h"
22 #if TEST_STD_VER >= 23
23 #include "almost_satisfies_types.h"
24 #endif
25 
26 #if TEST_STD_VER >= 23
27 
28 template <class T>
29 struct RangeT {
30   T* begin();
31   T* end();
32 };
33 static_assert(std::ranges::input_range<RangeT<int>>);
34 
35 template <class T>
36 using BadRangeT = InputRangeNotDerivedFromGeneric<T>;
37 static_assert(std::ranges::range<BadRangeT<int>>);
38 static_assert(!std::ranges::input_range<BadRangeT<int>>);
39 
40 #endif
41 
42 // `SFINAEs_away` template variable checks whether the template arguments for
43 // a given template class `Instantiated` can be deduced from the given
44 // constructor parameter types `CtrArgs` using CTAD.
45 
46 template<template<typename ...> class Instantiated, class ...CtrArgs,
47     class = decltype(Instantiated(std::declval<CtrArgs>()...))>
48 std::false_type SFINAEs_away_impl(int);
49 
50 template<template<typename ...> class Instantiated, class ...CtrArgs>
51 std::true_type SFINAEs_away_impl(...);
52 
53 template<template<typename ...> class Instantiated, class ...CtrArgs>
54 constexpr bool SFINAEs_away =
55     decltype(SFINAEs_away_impl<Instantiated, CtrArgs...>(0))::value;
56 
57 struct Empty {};
58 
59 // For sequence containers the deduction guides should be SFINAE'd away when
60 // given:
61 // - "bad" input iterators (that is, a type not qualifying as an input
62 //   iterator);
63 // - a bad allocator;
64 // - a range not satisfying the `input_range` concept.
65 template<template<typename ...> class Container, typename InstantiatedContainer, typename BadAlloc = Empty>
SequenceContainerDeductionGuidesSfinaeAway()66 constexpr void SequenceContainerDeductionGuidesSfinaeAway() {
67   using T = typename InstantiatedContainer::value_type;
68   using Alloc = std::allocator<T>;
69   using Iter = T*;
70 
71   // Note: the only requirement in the Standard is that integral types cannot be
72   // considered input iterators; however, this doesn't work for sequence
73   // containers because they have constructors of the form `(size_type count,
74   // const value_type& value)`. These constructors would be used when passing
75   // two integral types and would deduce `value_type` to be an integral type.
76 #ifdef _LIBCPP_VERSION
77   using OutputIter = std::insert_iterator<InstantiatedContainer>;
78 #endif // _LIBCPP_VERSION
79 
80   // (iter, iter)
81   //
82   // Cannot deduce from (BAD_iter, BAD_iter)
83   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter>);
84 
85   // (iter, iter, alloc)
86   //
87   // Cannot deduce from (BAD_iter, BAD_iter, alloc)
88   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, Alloc>);
89   // Cannot deduce from (iter, iter, BAD_alloc)
90   static_assert(SFINAEs_away<Container, Iter, Iter, BadAlloc>);
91 
92   // (alloc)
93   //
94   // Cannot deduce from (alloc)
95   static_assert(SFINAEs_away<Container, Alloc>);
96 
97 #if TEST_STD_VER >= 23
98   using BadRange = BadRangeT<T>;
99 
100   // (from_range, range)
101   //
102   // Cannot deduce from (BAD_range)
103   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange>);
104 
105   // (from_range, range, alloc)
106   //
107   // Cannot deduce from (range, BAD_alloc)
108   static_assert(SFINAEs_away<Container, std::from_range_t, RangeT<int>, BadAlloc>);
109 #endif
110 }
111 
112 // Deduction guides should be SFINAE'd away when given:
113 // - a "bad" allocator (that is, a type not qualifying as an allocator);
114 // - an allocator instead of a container;
115 // - an allocator and a container that uses a different allocator;
116 // - a range not satisfying the `input_range` concept.
117 template<template<typename ...> class Container, typename InstantiatedContainer>
ContainerAdaptorDeductionGuidesSfinaeAway()118 constexpr void ContainerAdaptorDeductionGuidesSfinaeAway() {
119   using T = typename InstantiatedContainer::value_type;
120   using Alloc [[maybe_unused]] = std::allocator<T>;
121   using Iter = T*;
122 
123   using BadIter [[maybe_unused]] = int;
124   using BadAlloc = Empty;
125 
126   // (container) -- no constraints.
127 
128   // (container, alloc)
129   //
130   // Cannot deduce from (container, BAD_alloc)
131   static_assert(SFINAEs_away<Container, std::vector<T>, BadAlloc>);
132 
133   // (iter, iter)
134   //
135   // Cannot deduce from (BAD_iter, BAD_iter)
136   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, BadIter, BadIter>);
137 
138 #if TEST_STD_VER >= 23
139   using BadRange = BadRangeT<T>;
140 
141   // (iter, iter, alloc)
142   //
143   // Cannot deduce from (BAD_iter, BAD_iter, alloc)
144   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, BadIter, BadIter, Alloc>);
145   // Cannot deduce from (iter, iter, BAD_alloc)
146   static_assert(SFINAEs_away<Container, Iter, Iter, BadAlloc>);
147 
148   // (from_range, range)
149   //
150   // Cannot deduce from (BAD_range)
151   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange>);
152 
153   // (from_range, range, alloc)
154   //
155   // Cannot deduce from (range, BAD_alloc)
156   static_assert(SFINAEs_away<Container, std::from_range_t, RangeT<int>, BadAlloc>);
157 #endif
158 }
159 
160 // For associative containers the deduction guides should be SFINAE'd away when
161 // given:
162 // - "bad" input iterators (that is, a type not qualifying as an input
163 //   iterator);
164 // - a bad allocator;
165 // - an allocator in place of a comparator;
166 // - a range not satisfying the `input_range` concept.
167 template<template<typename ...> class Container, typename InstantiatedContainer>
AssociativeContainerDeductionGuidesSfinaeAway()168 constexpr void AssociativeContainerDeductionGuidesSfinaeAway() {
169   using ValueType = typename InstantiatedContainer::value_type;
170   using Comp = std::less<int>;
171   using Alloc = std::allocator<ValueType>;
172   using Iter = ValueType*;
173   using InitList = std::initializer_list<ValueType>;
174 
175   struct BadAlloc {};
176   // The only requirement in the Standard is that integral types cannot be
177   // considered input iterators, beyond that it is unspecified.
178   using BadIter = int;
179 #ifdef _LIBCPP_VERSION
180   using OutputIter = std::insert_iterator<InstantiatedContainer>;
181 #endif // _LIBCPP_VERSION
182   using AllocAsComp = Alloc;
183 
184   // (iter, iter)
185   //
186   // Cannot deduce from (BAD_iter, BAD_iter)
187   static_assert(SFINAEs_away<Container, BadIter, BadIter>);
188   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter>);
189 
190   // (iter, iter, comp)
191   //
192   // Cannot deduce from (BAD_iter, BAD_iter, comp)
193   static_assert(SFINAEs_away<Container, BadIter, BadIter, Comp>);
194   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, Comp>);
195 
196   // (iter, iter, comp, alloc)
197   //
198   // Cannot deduce from (BAD_iter, BAD_iter, comp, alloc)
199   static_assert(SFINAEs_away<Container, BadIter, BadIter, Comp, Alloc>);
200   LIBCPP_STATIC_ASSERT(
201       SFINAEs_away<Container, OutputIter, OutputIter, Comp, Alloc>);
202   // Cannot deduce from (iter, iter, ALLOC_as_comp, alloc)
203   static_assert(SFINAEs_away<Container, Iter, Iter, AllocAsComp, Alloc>);
204   // Cannot deduce from (iter, iter, comp, BAD_alloc)
205   static_assert(SFINAEs_away<Container, Iter, Iter, Comp, BadAlloc>);
206 
207   // (iter, iter, alloc)
208   //
209   // Cannot deduce from (BAD_iter, BAD_iter, alloc)
210   static_assert(SFINAEs_away<Container, BadIter, BadIter, Alloc>);
211   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, Alloc>);
212   // Note: (iter, iter, BAD_alloc) is interpreted as (iter, iter, comp)
213   // instead and fails upon instantiation. There is no requirement to SFINAE
214   // away bad comparators.
215 
216   // (init_list, comp, alloc)
217   //
218   // Cannot deduce from (init_list, ALLOC_as_comp, alloc)
219   static_assert(SFINAEs_away<Container, InitList, AllocAsComp, Alloc>);
220   // Cannot deduce from (init_list, comp, BAD_alloc)
221   static_assert(SFINAEs_away<Container, InitList, Comp, BadAlloc>);
222 
223   // (init_list, alloc)
224   //
225   // Note: (init_list, BAD_alloc) is interpreted as (init_list, comp) instead
226   // and fails upon instantiation. There is no requirement to SFINAE away bad
227   // comparators.
228 
229 #if TEST_STD_VER >= 23
230   using Range = RangeT<ValueType>;
231   using BadRange = BadRangeT<ValueType>;
232 
233   // (from_range, range)
234   //
235   // Can deduce from (from_range, range)
236   static_assert(!SFINAEs_away<Container, std::from_range_t, Range>);
237   // Cannot deduce from (from_range, BAD_range)
238   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange>);
239 
240   // (from_range, range, comp)
241   //
242   // Can deduce from (from_range, _range, comp)
243   static_assert(!SFINAEs_away<Container, std::from_range_t, Range, Comp>);
244   // Cannot deduce from (from_range, BAD_range, comp)
245   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, Comp>);
246 
247   // (from_range, range, comp, alloc)
248   //
249   // Can deduce from (from_range, range, comp, alloc)
250   static_assert(!SFINAEs_away<Container, std::from_range_t, Range, Comp, Alloc>);
251   // Cannot deduce from (from_range, BAD_range, comp, alloc)
252   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, Comp, Alloc>);
253   // Cannot deduce from (from_range, range, comp, BAD_alloc)
254   static_assert(SFINAEs_away<Container, std::from_range_t, Range, Comp, BadAlloc>);
255 
256   // (from_range, range, alloc)
257   //
258   // Can deduce from (from_range, range, alloc)
259   static_assert(!SFINAEs_away<Container, std::from_range_t, Range, Alloc>);
260   // Cannot deduce from (from_range, BAD_range, alloc)
261   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, Alloc>);
262   // Note: (from_range, range, BAD_alloc) is interpreted as (from_range, range, comp) instead.
263 #endif
264 }
265 
266 // For unordered containers the deduction guides should be SFINAE'd away when
267 // given:
268 // - "bad" input iterators (that is, a type not qualifying as an input
269 //   iterator);
270 // - a bad allocator;
271 // - a bad hash functor (an integral type in place of a hash);
272 // - an allocator in place of a hash functor;
273 // - an allocator in place of a predicate;
274 // - a range not satisfying the `input_range` concept.
275 template<template<typename ...> class Container, typename InstantiatedContainer>
UnorderedContainerDeductionGuidesSfinaeAway()276 constexpr void UnorderedContainerDeductionGuidesSfinaeAway() {
277   using ValueType = typename InstantiatedContainer::value_type;
278   using Pred = std::equal_to<int>;
279   using Hash = std::hash<int>;
280   using Alloc = std::allocator<ValueType>;
281   using Iter = ValueType*;
282   using InitList = std::initializer_list<ValueType>;
283 
284   using BadHash = short;
285   struct BadAlloc {};
286   // The only requirement in the Standard is that integral types cannot be
287   // considered input iterators, beyond that it is unspecified.
288   using BadIter = int;
289 #ifdef _LIBCPP_VERSION
290   using OutputIter = std::insert_iterator<InstantiatedContainer>;
291 #endif // _LIBCPP_VERSION
292   using AllocAsHash = Alloc;
293   using AllocAsPred = Alloc;
294 
295   // (iter, iter)
296   //
297   // Cannot deduce from (BAD_iter, BAD_iter)
298   static_assert(SFINAEs_away<Container, BadIter, BadIter>);
299   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter>);
300 
301   // (iter, iter, buckets)
302   //
303   // Cannot deduce from (BAD_iter, BAD_iter, buckets)
304   static_assert(SFINAEs_away<Container, BadIter, BadIter, std::size_t>);
305   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, std::size_t>);
306 
307   // (iter, iter, buckets, hash)
308   //
309   // Cannot deduce from (BAD_iter, BAD_iter, buckets, hash)
310   static_assert(SFINAEs_away<Container, BadIter, BadIter, std::size_t, Hash>);
311   LIBCPP_STATIC_ASSERT(
312       SFINAEs_away<Container, OutputIter, OutputIter, std::size_t, Hash>);
313   // Cannot deduce from (iter, iter, buckets, BAD_hash)
314   static_assert(SFINAEs_away<Container, Iter, Iter, std::size_t, BadHash>);
315   // Note: (iter, iter, buckets, ALLOC_as_hash) is allowed -- it just calls
316   // (iter, iter, buckets, alloc)
317 
318   // (iter, iter, buckets, hash, pred)
319   //
320   // Cannot deduce from (BAD_iter, BAD_iter, buckets, hash, pred)
321   static_assert(SFINAEs_away<Container, BadIter, BadIter, std::size_t, Hash, Pred>);
322   LIBCPP_STATIC_ASSERT(
323       SFINAEs_away<Container, OutputIter, OutputIter, std::size_t, Hash, Pred>);
324   // Cannot deduce from (iter, iter, buckets, BAD_hash, pred)
325   static_assert(SFINAEs_away<Container, Iter, Iter, std::size_t, BadHash, Pred>);
326   // Cannot deduce from (iter, iter, buckets, ALLOC_as_hash, pred)
327   static_assert(SFINAEs_away<Container, Iter, Iter, std::size_t, AllocAsHash, Pred>);
328   // Note: (iter, iter, buckets, hash, ALLOC_as_pred) is allowed -- it just
329   // calls (iter, iter, buckets, hash, alloc)
330 
331   // (iter, iter, buckets, hash, pred, alloc)
332   //
333   // Cannot deduce from (BAD_iter, BAD_iter, buckets, hash, pred, alloc)
334   static_assert(
335       SFINAEs_away<Container, BadIter, BadIter, std::size_t, Hash, Pred, Alloc>);
336   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter,
337       std::size_t, Hash, Pred, Alloc>);
338   // Cannot deduce from (iter, iter, buckets, BAD_hash, pred, alloc)
339   static_assert(SFINAEs_away<Container, Iter, Iter, std::size_t, BadHash, Pred, Alloc>);
340   // Cannot deduce from (iter, iter, buckets, ALLOC_as_hash, pred, alloc)
341   static_assert(
342       SFINAEs_away<Container, Iter, Iter, std::size_t, AllocAsHash, Pred, Alloc>);
343   // Cannot deduce from (iter, iter, buckets, hash, ALLOC_as_pred, alloc)
344   static_assert(
345       SFINAEs_away<Container, Iter, Iter, std::size_t, Hash, AllocAsPred, Alloc>);
346   // Cannot deduce from (iter, iter, buckets, hash, pred, BAD_alloc)
347   static_assert(
348       SFINAEs_away<Container, Iter, Iter, std::size_t, Hash, Pred, BadAlloc>);
349 
350   // (iter, iter, buckets, alloc)
351   //
352   // Cannot deduce from (BAD_iter, BAD_iter, buckets, alloc)
353   static_assert(SFINAEs_away<Container, BadIter, BadIter, std::size_t, Alloc>);
354   LIBCPP_STATIC_ASSERT(
355       SFINAEs_away<Container, OutputIter, OutputIter, std::size_t, Alloc>);
356   // Note: (iter, iter, buckets, BAD_alloc) is interpreted as (iter, iter,
357   // buckets, hash), which is valid because the only requirement for the hash
358   // parameter is that it's not integral.
359 
360   // (iter, iter, alloc)
361   //
362   // Cannot deduce from (BAD_iter, BAD_iter, alloc)
363   static_assert(SFINAEs_away<Container, BadIter, BadIter, Alloc>);
364   LIBCPP_STATIC_ASSERT(SFINAEs_away<Container, OutputIter, OutputIter, Alloc>);
365   // Cannot deduce from (iter, iter, BAD_alloc)
366   static_assert(SFINAEs_away<Container, Iter, Iter, BadAlloc>);
367 
368   // (iter, iter, buckets, hash, alloc)
369   //
370   // Cannot deduce from (BAD_iter, BAD_iter, buckets, hash, alloc)
371   static_assert(SFINAEs_away<Container, BadIter, BadIter, std::size_t, Hash, Alloc>);
372   LIBCPP_STATIC_ASSERT(
373       SFINAEs_away<Container, OutputIter, OutputIter, std::size_t, Hash, Alloc>);
374   // Cannot deduce from (iter, iter, buckets, BAD_hash, alloc)
375   static_assert(SFINAEs_away<Container, Iter, Iter, std::size_t, BadHash, Alloc>);
376   // Cannot deduce from (iter, iter, buckets, ALLOC_as_hash, alloc)
377   static_assert(SFINAEs_away<Container, Iter, Iter, std::size_t, AllocAsHash, Alloc>);
378   // Note: (iter, iter, buckets, hash, BAD_alloc) is interpreted as (iter, iter,
379   // buckets, hash, pred), which is valid because there are no requirements for
380   // the predicate.
381 
382   // (init_list, buckets, hash)
383   //
384   // Cannot deduce from (init_list, buckets, BAD_hash)
385   static_assert(SFINAEs_away<Container, InitList, std::size_t, BadHash>);
386   // Note: (init_list, buckets, ALLOC_as_hash) is interpreted as (init_list,
387   // buckets, alloc), which is valid.
388 
389   // (init_list, buckets, hash, pred)
390   //
391   // Cannot deduce from (init_list, buckets, BAD_hash, pred)
392   static_assert(SFINAEs_away<Container, InitList, std::size_t, BadHash, Pred>);
393   // Cannot deduce from (init_list, buckets, ALLOC_as_hash, pred)
394   static_assert(SFINAEs_away<Container, InitList, std::size_t, AllocAsHash, Pred>);
395   // Note: (init_list, buckets, hash, ALLOC_as_pred) is interpreted as
396   // (init_list, buckets, hash, alloc), which is valid.
397 
398   // (init_list, buckets, hash, pred, alloc)
399   //
400   // Cannot deduce from (init_list, buckets, BAD_hash, pred, alloc)
401   static_assert(
402       SFINAEs_away<Container, InitList, std::size_t, BadHash, Pred, Alloc>);
403   // Cannot deduce from (init_list, buckets, ALLOC_as_hash, pred, alloc)
404   static_assert(
405       SFINAEs_away<Container, InitList, std::size_t, AllocAsHash, Pred, Alloc>);
406   // Cannot deduce from (init_list, buckets, hash, ALLOC_as_pred, alloc)
407   static_assert(
408       SFINAEs_away<Container, InitList, std::size_t, Hash, AllocAsPred, Alloc>);
409   // Cannot deduce from (init_list, buckets, hash, pred, BAD_alloc)
410   static_assert(
411       SFINAEs_away<Container, InitList, std::size_t, Hash, Pred, BadAlloc>);
412 
413   // (init_list, buckets, alloc)
414   //
415   // Note: (init_list, buckets, BAD_alloc) is interpreted as (init_list,
416   // buckets, hash), which is valid because the only requirement for the hash
417   // parameter is that it's not integral.
418 
419   // (init_list, buckets, hash, alloc)
420   //
421   // Cannot deduce from (init_list, buckets, BAD_hash, alloc)
422   static_assert(SFINAEs_away<Container, InitList, std::size_t, BadHash, Alloc>);
423   // Cannot deduce from (init_list, buckets, ALLOC_as_hash, alloc)
424   static_assert(SFINAEs_away<Container, InitList, std::size_t, AllocAsHash, Alloc>);
425 
426   // (init_list, alloc)
427   //
428   // Cannot deduce from (init_list, BAD_alloc)
429   static_assert(SFINAEs_away<Container, InitList, BadAlloc>);
430 
431 #if TEST_STD_VER >= 23
432   using Range = RangeT<ValueType>;
433   using BadRange = BadRangeT<ValueType>;
434 
435   // (from_range, range)
436   //
437   // Can deduce from (from_range, range)
438   static_assert(!SFINAEs_away<Container, std::from_range_t, Range>);
439   // Cannot deduce from (from_range, BAD_range)
440   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange>);
441 
442   // (from_range, range, buckets)
443   //
444   // Can deduce from (from_range, range, buckets)
445   static_assert(!SFINAEs_away<Container, std::from_range_t, Range, std::size_t>);
446   // Cannot deduce from (from_range, BAD_range, buckets)
447   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, std::size_t>);
448 
449   // (from_range, range, buckets, hash)
450   //
451   // Can deduce from (from_range, range, buckets, hash)
452   static_assert(!SFINAEs_away<Container, std::from_range_t, Range, std::size_t, Hash>);
453   // Cannot deduce from (from_range, BAD_range, buckets, hash)
454   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, std::size_t, Hash>);
455   // Cannot deduce from (from_range, range, buckets, BAD_hash)
456   static_assert(SFINAEs_away<Container, std::from_range_t, Range, std::size_t, BadHash>);
457 
458   // (from_range, range, buckets, hash, pred)
459   //
460   // Can deduce from (from_range, range, buckets, hash, pred)
461   static_assert(!SFINAEs_away<Container, std::from_range_t, Range, std::size_t, Hash, Pred>);
462   // Cannot deduce from (from_range, BAD_range, buckets, hash, pred)
463   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, std::size_t, Hash, Pred>);
464   // Cannot deduce from (from_range, range, buckets, BAD_hash, pred)
465   static_assert(SFINAEs_away<Container, std::from_range_t, Range, std::size_t, BadHash, Pred>);
466 
467   // (from_range, range, buckets, hash, pred, alloc)
468   //
469   // Can deduce from (from_range, range, buckets, hash, pred, alloc)
470   static_assert(!SFINAEs_away<Container, std::from_range_t, Range, std::size_t, Hash, Pred, Alloc>);
471   // Cannot deduce from (from_range, BAD_range, buckets, hash, pred, alloc)
472   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, std::size_t, Hash, Pred, Alloc>);
473   // Cannot deduce from (from_range, range, buckets, BAD_hash, pred, alloc)
474   static_assert(SFINAEs_away<Container, std::from_range_t, Range, std::size_t, BadHash, Pred, Alloc>);
475   // Cannot deduce from (from_range, range, buckets, hash, pred, BAD_alloc)
476   static_assert(SFINAEs_away<Container, std::from_range_t, Range, std::size_t, Hash, Pred, BadAlloc>);
477 
478   // (from_range, range, buckets, alloc)
479   //
480   // Can deduce from (from_range, range, buckets, alloc)
481   static_assert(!SFINAEs_away<Container, std::from_range_t, Range, std::size_t, Alloc>);
482   // Cannot deduce from (from_range, BAD_range, buckets, alloc)
483   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, std::size_t, Alloc>);
484   // Note: (from_range, range, buckets, BAD_alloc) is interpreted as (from_range, range, buckets, hash), which is valid
485   // because the only requirement for the hash parameter is that it's not integral.
486 
487   // (from_range, range, alloc)
488   //
489   // Can deduce from (from_range, range, alloc)
490   // TODO(LWG 2713): uncomment this test once the constructor is added.
491   // static_assert(!SFINAEs_away<Container, std::from_range_t, Range, Alloc>);
492   // Cannot deduce from (from_range, BAD_range, alloc)
493   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, Alloc>);
494   // Cannot deduce from (from_range, range, BAD_alloc)
495   static_assert(SFINAEs_away<Container, std::from_range_t, Range, BadAlloc>);
496 
497   // (from_range, range, buckets, hash, alloc)
498   //
499   // Can deduce from (from_range, range, buckets, hash, alloc)
500   static_assert(!SFINAEs_away<Container, std::from_range_t, Range, std::size_t, Hash, Alloc>);
501   // Cannot deduce from (from_range, BAD_range, buckets, hash, alloc)
502   static_assert(SFINAEs_away<Container, std::from_range_t, BadRange, std::size_t, Hash, Alloc>);
503   // Cannot deduce from (from_range, range, buckets, BAD_hash, alloc)
504   static_assert(SFINAEs_away<Container, std::from_range_t, Range, std::size_t, BadHash, Alloc>);
505   // Cannot deduce from (from_range, range, buckets, ALLOC_as_hash, alloc)
506   static_assert(SFINAEs_away<Container, std::from_range_t, Range, std::size_t, AllocAsHash, Alloc>);
507   // Cannot deduce from (from_range, range, buckets, hash, BAD_alloc)
508   // Note: (from_range, range, buckets, hash, BAD_alloc) is interpreted as (from_range, range, buckets, hash, pred),
509   // which is valid because the only requirement for the predicate parameter is that it does not resemble an allocator.
510 #endif
511 }
512 
513 #endif // TEST_SUPPORT_DEDUCTION_GUIDES_SFINAE_CHECKS_H
514