From e225b7f8262df48ad4d7094bc295add3007b0649 Mon Sep 17 00:00:00 2001 From: peterbell10 Date: Mon, 11 Sep 2017 22:20:49 +0100 Subject: Replace ItemCallbacks with lambdas (#3993) --- src/FunctionRef.h | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/FunctionRef.h (limited to 'src/FunctionRef.h') diff --git a/src/FunctionRef.h b/src/FunctionRef.h new file mode 100644 index 000000000..8215fd0db --- /dev/null +++ b/src/FunctionRef.h @@ -0,0 +1,58 @@ + +#pragma once + +// Declared only so it can be partially specialized +template +class cFunctionRef; + +/** A light-weight, type-erased reference to a function object. +This is similar to a std::function but doesn't copy the function object +which means that mutable function objects will be modified for the caller +but would not be if using a std::function (See #3990 for implications of this). +A cFunctionRef has no empty state but is non-owning and so is safe to call +as long as the referred object is still alive. */ +template +class cFunctionRef +{ +public: + /** Construct from a function object. */ + template + cFunctionRef(FunctionObject && a_FunctionObject) + { + // Store an opaque reference to the object. + m_CallableData = &a_FunctionObject; + + // Along with a function that knows how to call the object. + m_CallFunction = &ObjectFunctionCaller; + } + + /** Call the referenced function object */ + Ret operator () (Args... a_Args) + { + return m_CallFunction(m_CallableData, std::forward(a_Args)...); + } + +private: + + /** Function that performs the call. */ + template + static Ret ObjectFunctionCaller(void * a_Callable, Args... a_Args) + { + // Convert opaque reference to the concrete type. + using ObjectPtr = typename std::add_pointer::type; + auto & Object = *static_cast(a_Callable); + + // Forward the call down to the object. + return Object(std::forward(a_Args)...); + } + + using cCallFunction = Ret(*)(void *, Args...); + + /** Type erased reference to a callable. */ + void * m_CallableData; + + /** Function that knows how to call the type erased reference. */ + cCallFunction m_CallFunction; +}; + + -- cgit v1.2.3