| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  * Copyright 2015 Google Inc. | 
|  | 3  * | 
|  | 4  * Use of this source code is governed by a BSD-style license that can be | 
|  | 5  * found in the LICENSE file. | 
|  | 6  */ | 
|  | 7 | 
|  | 8 #ifndef SkFunction_DEFINED | 
|  | 9 #define SkFunction_DEFINED | 
|  | 10 | 
|  | 11 // TODO: document | 
|  | 12 | 
|  | 13 #include "SkTypes.h" | 
|  | 14 | 
|  | 15 template <typename> class SkFunction; | 
|  | 16 | 
|  | 17 template <typename R, typename... Args> | 
|  | 18 class SkFunction<R(Args...)> : SkNoncopyable { | 
|  | 19 public: | 
|  | 20     explicit SkFunction(R (*fn)(Args...)) : fVTable(GetFunctionPointerVTable()) 
    { | 
|  | 21         // We've been passed a function pointer.  We'll just store it. | 
|  | 22         fFunction = reinterpret_cast<void*>(fn); | 
|  | 23     } | 
|  | 24 | 
|  | 25     template <typename Fn> | 
|  | 26     explicit SkFunction(Fn fn) : fVTable(GetVTable<Fn>()) { | 
|  | 27         // We've got a functor.  The basic thing we can always do is copy it ont
    o the heap. | 
|  | 28         fFunction = SkNEW_ARGS(Fn, (fn)); | 
|  | 29     } | 
|  | 30 | 
|  | 31     ~SkFunction() { fVTable.fDelete(fFunction); } | 
|  | 32 | 
|  | 33     R operator()(Args... args) { return fVTable.fCall(fFunction, args...); } | 
|  | 34 | 
|  | 35 private: | 
|  | 36     struct VTable { | 
|  | 37         R (*fCall)(void*, Args...); | 
|  | 38         void (*fDelete)(void*); | 
|  | 39     }; | 
|  | 40 | 
|  | 41     static const VTable& GetFunctionPointerVTable() { | 
|  | 42         static const VTable vtable = { | 
|  | 43             [](void* fn, Args... args) { return reinterpret_cast<R(*)(Args...)>(
    fn)(args...); }, | 
|  | 44             [](void*) { /* Don't delete function pointers. */ }, | 
|  | 45         }; | 
|  | 46         return vtable; | 
|  | 47     } | 
|  | 48 | 
|  | 49     template <typename Fn> | 
|  | 50     static const VTable& GetVTable() { | 
|  | 51         static const VTable vtable = { | 
|  | 52             [](void* fn, Args... args) { return (*static_cast<Fn*>(fn))(args...)
    ; }, | 
|  | 53             [](void* fn) { SkDELETE(static_cast<Fn*>(fn)); }, | 
|  | 54         }; | 
|  | 55         return vtable; | 
|  | 56     } | 
|  | 57 | 
|  | 58     void* fFunction;        // Either a function pointer, or a pointer to a func
    tor. | 
|  | 59     const VTable& fVTable;  // How to call, delete (and one day copy, move) fFun
    ction. | 
|  | 60 }; | 
|  | 61 | 
|  | 62 // TODO: | 
|  | 63 //   - is it worth moving fCall out of the VTable into SkFunction itself to avoi
    d the indirection? | 
|  | 64 //   - should constructors be implicit? | 
|  | 65 //   - make SkFunction copyable | 
|  | 66 //   - emulate std::forward for moveable functors (e.g. lambdas) | 
|  | 67 //   - forward args too? | 
|  | 68 //   - implement small-object optimization to store functors inline | 
|  | 69 | 
|  | 70 #endif//SkFunction_DEFINED | 
| OLD | NEW | 
|---|