Home | History | Annotate | Download | only in temp.variadic
      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