1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // <functional>
11
12 // template<class F>
13 // function(F) -> function<see-below>;
14
15 // UNSUPPORTED: c++03, c++11, c++14
16 // UNSUPPORTED: libcpp-no-deduction-guides
17
18 #include <functional>
19 #include <type_traits>
20 #include <utility>
21
22 #include "test_macros.h"
23
24
25 struct R { };
26 struct A1 { };
27 struct A2 { };
28 struct A3 { };
29
30 #define DECLARE_FUNCTIONS_WITH_QUALS(N, ...) \
31 struct f0_##N { R operator()() __VA_ARGS__ { return {}; } }; \
32 struct f1_##N { R operator()(A1) __VA_ARGS__ { return {}; } }; \
33 struct f2_##N { R operator()(A1, A2) __VA_ARGS__ { return {}; } }; \
34 struct f3_##N { R operator()(A1, A2, A3) __VA_ARGS__ { return {}; } } \
35 /**/
36
37 DECLARE_FUNCTIONS_WITH_QUALS(0, /* nothing */);
38 DECLARE_FUNCTIONS_WITH_QUALS(1, const);
39 DECLARE_FUNCTIONS_WITH_QUALS(2, volatile);
40 DECLARE_FUNCTIONS_WITH_QUALS(3, const volatile);
41 DECLARE_FUNCTIONS_WITH_QUALS(4, &);
42 DECLARE_FUNCTIONS_WITH_QUALS(5 , const &);
43 DECLARE_FUNCTIONS_WITH_QUALS(6 , volatile &);
44 DECLARE_FUNCTIONS_WITH_QUALS(7 , const volatile &);
45 DECLARE_FUNCTIONS_WITH_QUALS(8 , noexcept);
46 DECLARE_FUNCTIONS_WITH_QUALS(9 , const noexcept);
47 DECLARE_FUNCTIONS_WITH_QUALS(10, volatile noexcept);
48 DECLARE_FUNCTIONS_WITH_QUALS(11, const volatile noexcept);
49 DECLARE_FUNCTIONS_WITH_QUALS(12, & noexcept);
50 DECLARE_FUNCTIONS_WITH_QUALS(13, const & noexcept);
51 DECLARE_FUNCTIONS_WITH_QUALS(14, volatile & noexcept);
52 DECLARE_FUNCTIONS_WITH_QUALS(15, const volatile & noexcept);
53
main(int,char **)54 int main(int, char**) {
55 #define CHECK_FUNCTIONS(N) \
56 do { \
57 /* implicit */ \
58 std::function g0 = f0_##N{}; \
59 ASSERT_SAME_TYPE(decltype(g0), std::function<R()>); \
60 \
61 std::function g1 = f1_##N{}; \
62 ASSERT_SAME_TYPE(decltype(g1), std::function<R(A1)>); \
63 \
64 std::function g2 = f2_##N{}; \
65 ASSERT_SAME_TYPE(decltype(g2), std::function<R(A1, A2)>); \
66 \
67 std::function g3 = f3_##N{}; \
68 ASSERT_SAME_TYPE(decltype(g3), std::function<R(A1, A2, A3)>); \
69 \
70 /* explicit */ \
71 std::function g4{f0_##N{}}; \
72 ASSERT_SAME_TYPE(decltype(g4), std::function<R()>); \
73 \
74 std::function g5{f1_##N{}}; \
75 ASSERT_SAME_TYPE(decltype(g5), std::function<R(A1)>); \
76 \
77 std::function g6{f2_##N{}}; \
78 ASSERT_SAME_TYPE(decltype(g6), std::function<R(A1, A2)>); \
79 \
80 std::function g7{f3_##N{}}; \
81 ASSERT_SAME_TYPE(decltype(g7), std::function<R(A1, A2, A3)>); \
82 \
83 /* from std::function */ \
84 std::function<R(A1)> unary; \
85 std::function g8 = unary; \
86 ASSERT_SAME_TYPE(decltype(g8), std::function<R(A1)>); \
87 \
88 std::function g9 = std::move(unary); \
89 ASSERT_SAME_TYPE(decltype(g9), std::function<R(A1)>); \
90 \
91 std::function<R(A1&&)> unary_ref; \
92 std::function g10 = unary_ref; \
93 ASSERT_SAME_TYPE(decltype(g10), std::function<R(A1&&)>); \
94 \
95 std::function g11 = std::move(unary_ref); \
96 ASSERT_SAME_TYPE(decltype(g11), std::function<R(A1&&)>); \
97 } while (false) \
98 /**/
99
100 // Make sure we can deduce from function objects with valid call operators
101 CHECK_FUNCTIONS(0);
102 CHECK_FUNCTIONS(1);
103 CHECK_FUNCTIONS(2);
104 CHECK_FUNCTIONS(3);
105 CHECK_FUNCTIONS(4);
106 CHECK_FUNCTIONS(5);
107 CHECK_FUNCTIONS(6);
108 CHECK_FUNCTIONS(7);
109 CHECK_FUNCTIONS(8);
110 CHECK_FUNCTIONS(9);
111 CHECK_FUNCTIONS(10);
112 CHECK_FUNCTIONS(11);
113 CHECK_FUNCTIONS(12);
114 CHECK_FUNCTIONS(13);
115 CHECK_FUNCTIONS(14);
116 CHECK_FUNCTIONS(15);
117
118 return 0;
119 }
120
121 // Make sure we fail in a SFINAE-friendly manner when we try to deduce
122 // from a type without a valid call operator.
123 template <typename F, typename = decltype(std::function{std::declval<F>()})>
can_deduce()124 constexpr bool can_deduce() { return true; }
125 template <typename F>
can_deduce(...)126 constexpr bool can_deduce(...) { return false; }
127
128 struct invalid1 { };
129 struct invalid2 {
130 template <typename ...Args>
131 void operator()(Args ...);
132 };
133 struct invalid3 {
134 void operator()(int);
135 void operator()(long);
136 };
137 static_assert(!can_deduce<invalid1>());
138 static_assert(!can_deduce<invalid2>());
139 static_assert(!can_deduce<invalid3>());
140