#ifndef NALL_FUNCTION_HPP #define NALL_FUNCTION_HPP namespace nall { template class function; template class function { struct container { virtual R operator()(P... p) const = 0; virtual container* copy() const = 0; virtual ~container() {} } *callback; struct global : container { R (*function)(P...); R operator()(P... p) const { return function(std::forward

(p)...); } container* copy() const { return new global(function); } global(R (*function)(P...)) : function(function) {} }; template struct member : container { R (C::*function)(P...); C *object; R operator()(P... p) const { return (object->*function)(std::forward

(p)...); } container* copy() const { return new member(function, object); } member(R (C::*function)(P...), C *object) : function(function), object(object) {} }; template struct lambda : container { mutable L object; R operator()(P... p) const { return object(std::forward

(p)...); } container* copy() const { return new lambda(object); } lambda(const L& object) : object(object) {} }; public: operator bool() const { return callback; } R operator()(P... p) const { return (*callback)(std::forward

(p)...); } void reset() { if(callback) { delete callback; callback = nullptr; } } function& operator=(const function &source) { if(this != &source) { if(callback) { delete callback; callback = nullptr; } if(source.callback) callback = source.callback->copy(); } return *this; } function(const function &source) : callback(nullptr) { operator=(source); } function() : callback(nullptr) {} function(void *function) : callback(nullptr) { if(function) callback = new global((R (*)(P...))function); } function(R (*function)(P...)) { callback = new global(function); } template function(R (C::*function)(P...), C *object) { callback = new member(function, object); } template function(R (C::*function)(P...) const, C *object) { callback = new member((R (C::*)(P...))function, object); } template function(const L& object) { callback = new lambda(object); } ~function() { if(callback) delete callback; } }; } #endif