]> git.proxmox.com Git - rustc.git/blame - src/llvm/tools/clang/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp
Imported Upstream version 0.6
[rustc.git] / src / llvm / tools / clang / test / CXX / temp / temp.decls / temp.variadic / example-function.cpp
CommitLineData
223e47cc
LB
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
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}