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