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

source code of libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_F.pass.cpp