diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-07 19:56:20 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-07 19:56:20 +0000 |
commit | e8bbf98ba4a388d89d1b4da9e15aabedf8eb53a6 (patch) | |
tree | 4702abe9fa9d6c96ab8694d0c531545d82765baa /test/CXX/temp/temp.decls/temp.variadic/example-function.cpp | |
parent | 9ce5270f0aadaaf03a0cf705787f42ce9eb1194c (diff) |
Variadic templates example: a nearly-complete implementation of a TR1
function class template.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123024 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CXX/temp/temp.decls/temp.variadic/example-function.cpp')
-rw-r--r-- | test/CXX/temp/temp.decls/temp.variadic/example-function.cpp | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp b/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp new file mode 100644 index 0000000000..b3d010c88d --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +// Example function implementation from the variadic templates proposal, +// ISO C++ committee document number N2080. + +template<typename Signature> class function; + +template<typename R, typename... Args> class invoker_base { +public: + virtual ~invoker_base() { } + virtual R invoke(Args...) = 0; + virtual invoker_base* clone() = 0; +}; + +template<typename F, typename R, typename... Args> +class functor_invoker : public invoker_base<R, Args...> { +public: + explicit functor_invoker(const F& f) : f(f) { } + R invoke(Args... args) { return f(args...); } + functor_invoker* clone() { return new functor_invoker(f); } + +private: + F f; +}; + +template<typename R, typename... Args> +class function<R (Args...)> { +public: + typedef R result_type; + function() : invoker (0) { } + function(const function& other) : invoker(0) { + if (other.invoker) + invoker = other.invoker->clone(); + } + + template<typename F> function(const F& f) : invoker(0) { + invoker = new functor_invoker<F, R, Args...>(f); + } + + ~function() { + if (invoker) + delete invoker; + } + + function& operator=(const function& other) { + function(other).swap(*this); + return *this; + } + + template<typename F> + function& operator=(const F& f) { + function(f).swap(*this); + return *this; + } + + void swap(function& other) { + invoker_base<R, Args...>* tmp = invoker; + invoker = other.invoker; + other.invoker = tmp; + } + + result_type operator()(Args... args) const { + return invoker->invoke(args...); + } + +private: + invoker_base<R, Args...>* invoker; +}; + +template<typename T> +struct add { + T operator()(T x, T y) { return x + y; } +}; + +int add_ints(int x, int y) { return x + y; } + +void test_function() { + function<int(int, int)> f2a; + function<int(int, int)> f2b = add<int>(); + function<int(int, int)> f2c = add<float>(); + function<int(int, int)> f2d(f2b); + function<int(int, int)> f2e = &add_ints; + f2c = f2d; + f2d = &add_ints; + f2c(1.0, 3); +} |