From b41e2d92982b1f3f1961db479a9d2a8801f71477 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 7 Jan 2011 19:56:20 +0000 Subject: [PATCH] Variadic templates example: a nearly-complete implementation of a TR1 function class template. llvm-svn: 123024 --- .../temp.variadic/example-function.cpp | 86 +++++++++++++++++++ .../temp.variadic/example-tuple.cpp | 2 +- 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp new file mode 100644 index 000000000000..b3d010c88d95 --- /dev/null +++ b/clang/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 class function; + +template class invoker_base { +public: + virtual ~invoker_base() { } + virtual R invoke(Args...) = 0; + virtual invoker_base* clone() = 0; +}; + +template +class functor_invoker : public invoker_base { +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 +class function { +public: + typedef R result_type; + function() : invoker (0) { } + function(const function& other) : invoker(0) { + if (other.invoker) + invoker = other.invoker->clone(); + } + + template function(const F& f) : invoker(0) { + invoker = new functor_invoker(f); + } + + ~function() { + if (invoker) + delete invoker; + } + + function& operator=(const function& other) { + function(other).swap(*this); + return *this; + } + + template + function& operator=(const F& f) { + function(f).swap(*this); + return *this; + } + + void swap(function& other) { + invoker_base* tmp = invoker; + invoker = other.invoker; + other.invoker = tmp; + } + + result_type operator()(Args... args) const { + return invoker->invoke(args...); + } + +private: + invoker_base* invoker; +}; + +template +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 f2a; + function f2b = add(); + function f2c = add(); + function f2d(f2b); + function f2e = &add_ints; + f2c = f2d; + f2d = &add_ints; + f2c(1.0, 3); +} diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp index 1652bc59551a..ff8dfda7686f 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s // Example tuple implementation from the variadic templates proposal, -// ISO C++ committee document nmber N2080. +// ISO C++ committee document number N2080. // Helper type traits template