example-function.cpp revision e8bbf98ba4a388d89d1b4da9e15aabedf8eb53a6
1// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
2
3// Example function implementation from the variadic templates proposal,
4// ISO C++ committee document number N2080.
5
6template<typename Signature> class function;
7
8template<typename R, typename... Args> class invoker_base {
9public:
10  virtual ~invoker_base() { }
11  virtual R invoke(Args...) = 0;
12  virtual invoker_base* clone() = 0;
13};
14
15template<typename F, typename R, typename... Args>
16class functor_invoker : public invoker_base<R, Args...> {
17public:
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
22private:
23  F f;
24};
25
26template<typename R, typename... Args>
27class function<R (Args...)> {
28public:
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
66private:
67  invoker_base<R, Args...>* invoker;
68};
69
70template<typename T>
71struct add {
72  T operator()(T x, T y) { return x + y; }
73};
74
75int add_ints(int x, int y) { return x + y; }
76
77void 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}
87