Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Unified Diff: src/core/SkFunction.h

Issue 1050113003: Constructor and call argument forwarding for SkFunction. (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: run them Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/FunctionTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkFunction.h
diff --git a/src/core/SkFunction.h b/src/core/SkFunction.h
index 300959342139646064c533c12ef7d3a9bfab821a..98ae789cae2c70d8f29bd542034e0ecf397af691 100644
--- a/src/core/SkFunction.h
+++ b/src/core/SkFunction.h
@@ -27,21 +27,25 @@ public:
explicit SkFunction(Fn fn, SK_WHEN_C((sizeof(Fn) > sizeof(void*)), void*) = nullptr)
: fVTable(GetOutlineVTable<Fn>()) {
// We've got a functor larger than a pointer. We've go to copy it onto the heap.
- fFunction = SkNEW_ARGS(Fn, (fn));
+ fFunction = SkNEW_ARGS(Fn, (Forward(fn)));
}
template <typename Fn>
explicit SkFunction(Fn fn, SK_WHEN_C((sizeof(Fn) <= sizeof(void*)), void*) = nullptr)
: fVTable(GetInlineVTable<Fn>()) {
// We've got a functor that fits in a pointer. We copy it right inline.
- SkNEW_PLACEMENT_ARGS(&fFunction, Fn, (fn));
+ fFunction = NULL; // Quiets a (spurious) warning that fFunction might be uninitialized.
+ SkNEW_PLACEMENT_ARGS(&fFunction, Fn, (Forward(fn)));
}
~SkFunction() { fVTable.fCleanUp(fFunction); }
- R operator()(Args... args) { return fVTable.fCall(fFunction, args...); }
+ R operator()(Args... args) { return fVTable.fCall(fFunction, Forward(args)...); }
private:
+ // ~= std::forward. This moves its argument if possible, falling back to a copy if not.
+ template <typename T> static T&& Forward(T& v) { return (T&&)v; }
+
struct VTable {
R (*fCall)(void*, Args...);
void (*fCleanUp)(void*);
@@ -50,7 +54,9 @@ private:
// Used when fFunction is a function pointer of type R(*)(Args...).
static const VTable& GetFunctionPointerVTable() {
static const VTable vtable = {
- [](void* fn, Args... args) { return reinterpret_cast<R(*)(Args...)>(fn)(args...); },
+ [](void* fn, Args... args) {
+ return reinterpret_cast<R(*)(Args...)>(fn)(Forward(args)...);
+ },
[](void*) { /* Nothing to clean up for function pointers. */ }
};
return vtable;
@@ -60,7 +66,7 @@ private:
template <typename Fn>
static const VTable& GetOutlineVTable() {
static const VTable vtable = {
- [](void* fn, Args... args) { return (*static_cast<Fn*>(fn))(args...); },
+ [](void* fn, Args... args) { return (*static_cast<Fn*>(fn))(Forward(args)...); },
[](void* fn) { SkDELETE(static_cast<Fn*>(fn)); },
};
return vtable;
@@ -71,12 +77,12 @@ private:
static const VTable& GetInlineVTable() {
static const VTable vtable = {
[](void* fn, Args... args) {
- union { void* p; Fn f; } pun = { fn };
- return pun.f(args...);
+ union { void** p; Fn* f; } pun = { &fn };
+ return (*pun.f)(Forward(args)...);
},
[](void* fn) {
- union { void* p; Fn f; } pun = { fn };
- pun.f.~Fn();
+ union { void** p; Fn* f; } pun = { &fn };
+ (*pun.f).~Fn();
(void)(pun.f); // Otherwise, when ~Fn() is trivial, MSVC complains pun is unused.
}
};
@@ -92,7 +98,5 @@ private:
// - is it worth moving fCall out of the VTable into SkFunction itself to avoid the indirection?
// - should constructors be implicit?
// - make SkFunction copyable
-// - emulate std::forward for moveable functors (e.g. lambdas)
-// - forward args too?
#endif//SkFunction_DEFINED
« no previous file with comments | « no previous file | tests/FunctionTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698