Created
August 8, 2020 11:19
-
-
Save sleepy-monax/58d64208c60c54a538c358deb2684bba to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <libutils/OwnPtr.h> | |
template <typename> | |
class Callback; | |
template <typename Out, typename... In> | |
class Callback<Out(In...)> | |
{ | |
private: | |
class AbstractCallbackWrapper | |
{ | |
public: | |
virtual ~AbstractCallbackWrapper() {} | |
virtual Out call(In...) const = 0; | |
}; | |
template <typename T> | |
class CallbackWrapper final : public AbstractCallbackWrapper | |
{ | |
private: | |
T _callback; | |
public: | |
CallbackWrapper(T &&callback) : _callback(move(callback)) {} | |
CallbackWrapper(const CallbackWrapper &) = delete; | |
CallbackWrapper &operator=(const CallbackWrapper &) = delete; | |
Out call(In... in) const { return _callback(forward<In>(in)...); } | |
}; | |
OwnPtr<AbstractCallbackWrapper> _wrapper; | |
public: | |
Callback(nullptr_t) : _wrapper(nullptr) {} | |
template <typename CallbackType> | |
Callback(CallbackType &&other) : _wrapper(own<CallbackWrapper<CallbackType>>(move(other))) {} | |
template <typename CallbackType> | |
Callback(CallbackType other) : _wrapper(own<CallbackWrapper<CallbackType>>(move(other))) {} | |
Callback(Callback &&other) : _wrapper(other._wrapper) {} | |
~Callback() {} | |
Callback &operator=(nullptr_t) | |
{ | |
_wrapper = nullptr; | |
return *this; | |
} | |
template <typename CallbackType> | |
Callback &operator=(CallbackType &&other) | |
{ | |
_wrapper = own<CallbackWrapper<CallbackType>>(other); | |
return *this; | |
} | |
Callback &operator=(Callback &&other) | |
{ | |
_wrapper = other._wrapper; | |
return *this; | |
} | |
Out operator()(In... in) const | |
{ | |
assert(_wrapper); | |
return _wrapper->call(forward<In>(in)...); | |
} | |
operator bool() const { return _wrapper == nullptr; } | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment