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