brintos

brintos / llvm-project-archived public Read only

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