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 // class function<R(ArgTypes...)>
12 
13 // template<typename T>
14 //   requires Callable<T, ArgTypes...> && Convertible<Callable<T, ArgTypes...>::result_type, R>
15 //   T*
16 //   target();
17 // template<typename T>
18 //   requires Callable<T, ArgTypes...> && Convertible<Callable<T, ArgTypes...>::result_type, R>
19 //   const T*
20 //   target() const;
21 
22 #include <functional>
23 #include <new>
24 #include <cstdlib>
25 #include <cassert>
26 
27 class A
28 {
29     int data_[10];
30 public:
31     static int count;
32 
33     A()
34     {
35         ++count;
36         for (int i = 0; i < 10; ++i)
37             data_[i] = i;
38     }
39 
40     A(const A&) {++count;}
41 
42     ~A() {--count;}
43 
44     int operator()(int i) const
45     {
46         for (int j = 0; j < 10; ++j)
47             i += data_[j];
48         return i;
49     }
50 
51     int foo(int) const {return 1;}
52 };
53 
54 int A::count = 0;
55 
56 int g(int) {return 0;}
57 
58 int main()
59 {
60     {
61     std::function<int(int)> f = A();
62     assert(A::count == 1);
63     assert(f.target<A>());
64     assert(f.target<int(*)(int)>() == 0);
65     assert(f.target<int>() == nullptr);
66     }
67     assert(A::count == 0);
68     {
69     std::function<int(int)> f = g;
70     assert(A::count == 0);
71     assert(f.target<int(*)(int)>());
72     assert(f.target<A>() == 0);
73     assert(f.target<int>() == nullptr);
74     }
75     assert(A::count == 0);
76     {
77     const std::function<int(int)> f = A();
78     assert(A::count == 1);
79     assert(f.target<A>());
80     assert(f.target<int(*)(int)>() == 0);
81     assert(f.target<int>() == nullptr);
82     }
83     assert(A::count == 0);
84     {
85     const std::function<int(int)> f = g;
86     assert(A::count == 0);
87     assert(f.target<int(*)(int)>());
88     assert(f.target<A>() == 0);
89     assert(f.target<int>() == nullptr);
90     }
91     assert(A::count == 0);
92 }
93