OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkFunction_DEFINED | 8 #ifndef SkFunction_DEFINED |
9 #define SkFunction_DEFINED | 9 #define SkFunction_DEFINED |
10 | 10 |
11 // TODO: document | 11 // TODO: document |
12 | 12 |
13 #include "SkTypes.h" | 13 #include "SkTypes.h" |
14 #include "SkTLogic.h" | 14 #include "SkTLogic.h" |
15 | 15 |
16 template <typename> class SkFunction; | 16 template <typename> class SkFunction; |
17 | 17 |
18 template <typename R, typename... Args> | 18 template <typename R, typename... Args> |
19 class SkFunction<R(Args...)> : SkNoncopyable { | 19 class SkFunction<R(Args...)> : SkNoncopyable { |
20 public: | 20 public: |
21 explicit SkFunction(R (*fn)(Args...)) : fVTable(GetFunctionPointerVTable())
{ | 21 SkFunction(R (*fn)(Args...)) : fVTable(GetFunctionPointerVTable()) { |
22 // We've been passed a function pointer. We'll just store it. | 22 // We've been passed a function pointer. We'll just store it. |
23 fFunction = reinterpret_cast<void*>(fn); | 23 fFunction = reinterpret_cast<void*>(fn); |
24 } | 24 } |
25 | 25 |
26 template <typename Fn> | 26 template <typename Fn> |
27 explicit SkFunction(Fn fn, SK_WHEN_C((sizeof(Fn) > sizeof(void*)), void*) =
nullptr) | 27 SkFunction(Fn fn, SK_WHEN_C((sizeof(Fn) > sizeof(void*)), void*) = nullptr) |
28 : fVTable(GetOutlineVTable<Fn>()) { | 28 : fVTable(GetOutlineVTable<Fn>()) { |
29 // We've got a functor larger than a pointer. We've go to copy it onto
the heap. | 29 // We've got a functor larger than a pointer. We've go to copy it onto
the heap. |
30 fFunction = SkNEW_ARGS(Fn, (Forward(fn))); | 30 fFunction = SkNEW_ARGS(Fn, (Forward(fn))); |
31 } | 31 } |
32 | 32 |
33 template <typename Fn> | 33 template <typename Fn> |
34 explicit SkFunction(Fn fn, SK_WHEN_C((sizeof(Fn) <= sizeof(void*)), void*) =
nullptr) | 34 SkFunction(Fn fn, SK_WHEN_C((sizeof(Fn) <= sizeof(void*)), void*) = nullptr) |
35 : fVTable(GetInlineVTable<Fn>()) { | 35 : fVTable(GetInlineVTable<Fn>()) { |
36 // We've got a functor that fits in a pointer. We copy it right inline. | 36 // We've got a functor that fits in a pointer. We copy it right inline. |
37 fFunction = NULL; // Quiets a (spurious) warning that fFunction might b
e uninitialized. | 37 fFunction = NULL; // Quiets a (spurious) warning that fFunction might b
e uninitialized. |
38 SkNEW_PLACEMENT_ARGS(&fFunction, Fn, (Forward(fn))); | 38 SkNEW_PLACEMENT_ARGS(&fFunction, Fn, (Forward(fn))); |
39 } | 39 } |
40 | 40 |
41 ~SkFunction() { fVTable.fCleanUp(fFunction); } | 41 ~SkFunction() { fVTable.fCleanUp(fFunction); } |
42 | 42 |
43 R operator()(Args... args) { return fVTable.fCall(fFunction, Forward(args)..
.); } | 43 R operator()(Args... args) { return fVTable.fCall(fFunction, Forward(args)..
.); } |
44 | 44 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 return vtable; | 89 return vtable; |
90 } | 90 } |
91 | 91 |
92 | 92 |
93 void* fFunction; // A function pointer, a pointer to a functor, or an
inlined functor. | 93 void* fFunction; // A function pointer, a pointer to a functor, or an
inlined functor. |
94 const VTable& fVTable; // How to call, delete (and one day copy, move) fFun
ction. | 94 const VTable& fVTable; // How to call, delete (and one day copy, move) fFun
ction. |
95 }; | 95 }; |
96 | 96 |
97 // TODO: | 97 // TODO: |
98 // - is it worth moving fCall out of the VTable into SkFunction itself to avoi
d the indirection? | 98 // - is it worth moving fCall out of the VTable into SkFunction itself to avoi
d the indirection? |
99 // - should constructors be implicit? | |
100 // - make SkFunction copyable | 99 // - make SkFunction copyable |
101 | 100 |
102 #endif//SkFunction_DEFINED | 101 #endif//SkFunction_DEFINED |
OLD | NEW |