1 // Copyright (C) 2020-2021 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library.  This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8 //
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3.  If not see
16 // <http://www.gnu.org/licenses/>.
17 
18 // expensive: * [1-9] * *
19 #include "bits/verify.h"
20 #include "bits/metahelpers.h"
21 
22 template <class V>
23   struct call_generator
24   {
25     template <class F>
26       auto
27       operator()(const F& f) -> decltype(V(f));
28   };
29 
30 using schar = signed char;
31 using uchar = unsigned char;
32 using ullong = unsigned long long;
33 
34 template <typename V>
35   void
test()36   test()
37   {
38     using T = typename V::value_type;
39     V x([](int) { return T(1); });
40     COMPARE(x, V(1));
41     // unconditionally returns int from generator lambda
42     x = V([](int) { return 1; });
43     COMPARE(x, V(1));
44     x = V([](auto i) { return T(i); });
45     COMPARE(x, V([](T i) { return i; }));
46 
47     VERIFY((// that int always works
48 	sfinae_is_callable<int (&)(int)>(call_generator<V>())));
49     COMPARE(sfinae_is_callable<schar (&)(int)>(call_generator<V>()),
50 	    std::is_signed<T>::value);
51     COMPARE(sfinae_is_callable<uchar (&)(int)>(call_generator<V>()),
52 	    !(std::is_signed_v<T> && sizeof(T) <= sizeof(uchar)));
53     COMPARE(sfinae_is_callable<float (&)(int)>(call_generator<V>()),
54 	    (std::is_floating_point<T>::value));
55 
56     COMPARE(sfinae_is_callable<ullong (&)(int)>(call_generator<V>()),
57       std::__finite_max_v<T> >= std::__finite_max_v<ullong>
58       && std::__digits_v<T> >= std::__digits_v<ullong>);
59   }
60