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