From 1e8a58b5680508c241f25f03af5b57502221f215 Mon Sep 17 00:00:00 2001 From: Mike Klein Date: Wed, 29 Jul 2015 11:50:09 -0400 Subject: Revert "Move headers with no dependencies." This reverts commit 117842223bd13325b6da26110d80e0590c1a742b. No good: https://uberchromegw.corp.google.com/i/client.skia/builders/Mac%20Builder/builds/3465/steps/compile/logs/stdio BUG=skia:4126 Review URL: https://codereview.chromium.org/1262173002 . --- src/core/SkFunction.h | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/core/SkFunction.h (limited to 'src/core/SkFunction.h') diff --git a/src/core/SkFunction.h b/src/core/SkFunction.h new file mode 100644 index 0000000000..8e41cba929 --- /dev/null +++ b/src/core/SkFunction.h @@ -0,0 +1,75 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkFunction_DEFINED +#define SkFunction_DEFINED + +// TODO: document, more pervasive move support in constructors, small-Fn optimization + +#include "SkTemplates.h" +#include "SkTypes.h" + +template class SkFunction; + +template +class SkFunction { +public: + SkFunction() {} + + template + SkFunction(const Fn& fn) : fFunction(SkNEW_ARGS(LambdaImpl, (fn))) {} + + SkFunction(R (*fn)(Args...)) : fFunction(SkNEW_ARGS(FnPtrImpl, (fn))) {} + + SkFunction(const SkFunction& other) { *this = other; } + SkFunction& operator=(const SkFunction& other) { + if (this != &other) { + fFunction.reset(other.fFunction ? other.fFunction->clone() : nullptr); + } + return *this; + } + + R operator()(Args... args) const { + SkASSERT(fFunction.get()); + return fFunction->call(Forward(args)...); + } + +private: + // ~= std::forward. This moves its argument if possible, falling back to a copy if not. + template static T&& Forward(T& v) { return (T&&)v; } + + struct Interface { + virtual ~Interface() {} + virtual R call(Args...) const = 0; + virtual Interface* clone() const = 0; + }; + + template + class LambdaImpl final : public Interface { + public: + LambdaImpl(const Fn& fn) : fFn(fn) {} + + R call(Args... args) const override { return fFn(Forward(args)...); } + Interface* clone() const override { return SkNEW_ARGS(LambdaImpl, (fFn)); } + private: + Fn fFn; + }; + + class FnPtrImpl final : public Interface { + public: + FnPtrImpl(R (*fn)(Args...)) : fFn(fn) {} + + R call(Args... args) const override { return fFn(Forward(args)...); } + Interface* clone() const override { return SkNEW_ARGS(FnPtrImpl, (fFn)); } + private: + R (*fFn)(Args...); + }; + + SkAutoTDelete fFunction; +}; + +#endif//SkFunction_DEFINED -- cgit v1.2.3