]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
2 | ||
3 | // Example function implementation from the variadic templates proposal, | |
4 | // ISO C++ committee document number N2080. | |
5 | ||
6 | template<typename Signature> class function; | |
7 | ||
8 | template<typename R, typename... Args> class invoker_base { | |
9 | public: | |
10 | virtual ~invoker_base() { } | |
11 | virtual R invoke(Args...) = 0; | |
12 | virtual invoker_base* clone() = 0; | |
13 | }; | |
14 | ||
15 | template<typename F, typename R, typename... Args> | |
16 | class functor_invoker : public invoker_base<R, Args...> { | |
17 | public: | |
18 | explicit functor_invoker(const F& f) : f(f) { } | |
19 | R invoke(Args... args) { return f(args...); } | |
20 | functor_invoker* clone() { return new functor_invoker(f); } | |
21 | ||
22 | private: | |
23 | F f; | |
24 | }; | |
25 | ||
26 | template<typename R, typename... Args> | |
27 | class function<R (Args...)> { | |
28 | public: | |
29 | typedef R result_type; | |
30 | function() : invoker (0) { } | |
31 | function(const function& other) : invoker(0) { | |
32 | if (other.invoker) | |
33 | invoker = other.invoker->clone(); | |
34 | } | |
35 | ||
36 | template<typename F> function(const F& f) : invoker(0) { | |
37 | invoker = new functor_invoker<F, R, Args...>(f); | |
38 | } | |
39 | ||
40 | ~function() { | |
41 | if (invoker) | |
42 | delete invoker; | |
43 | } | |
44 | ||
45 | function& operator=(const function& other) { | |
46 | function(other).swap(*this); | |
47 | return *this; | |
48 | } | |
49 | ||
50 | template<typename F> | |
51 | function& operator=(const F& f) { | |
52 | function(f).swap(*this); | |
53 | return *this; | |
54 | } | |
55 | ||
56 | void swap(function& other) { | |
57 | invoker_base<R, Args...>* tmp = invoker; | |
58 | invoker = other.invoker; | |
59 | other.invoker = tmp; | |
60 | } | |
61 | ||
62 | result_type operator()(Args... args) const { | |
63 | return invoker->invoke(args...); | |
64 | } | |
65 | ||
66 | private: | |
67 | invoker_base<R, Args...>* invoker; | |
68 | }; | |
69 | ||
70 | template<typename T> | |
71 | struct add { | |
72 | T operator()(T x, T y) { return x + y; } | |
73 | }; | |
74 | ||
75 | int add_ints(int x, int y) { return x + y; } | |
76 | ||
77 | void test_function() { | |
78 | function<int(int, int)> f2a; | |
79 | function<int(int, int)> f2b = add<int>(); | |
80 | function<int(int, int)> f2c = add<float>(); | |
81 | function<int(int, int)> f2d(f2b); | |
82 | function<int(int, int)> f2e = &add_ints; | |
83 | f2c = f2d; | |
84 | f2d = &add_ints; | |
85 | f2c(1.0, 3); | |
86 | } |