|
@@ -64,9 +64,12 @@ class delegate;
|
|
|
*/
|
|
*/
|
|
|
template<typename Ret, typename... Args>
|
|
template<typename Ret, typename... Args>
|
|
|
class delegate<Ret(Args...)> {
|
|
class delegate<Ret(Args...)> {
|
|
|
|
|
+ using return_type = std::remove_const_t<Ret>;
|
|
|
|
|
+ using delegate_type = return_type(const void *, Args...);
|
|
|
|
|
+
|
|
|
template<auto Candidate, std::size_t... Index>
|
|
template<auto Candidate, std::size_t... Index>
|
|
|
[[nodiscard]] auto wrap(std::index_sequence<Index...>) noexcept {
|
|
[[nodiscard]] auto wrap(std::index_sequence<Index...>) noexcept {
|
|
|
- return [](const void *, Args... args) -> Ret {
|
|
|
|
|
|
|
+ return [](const void *, Args... args) -> return_type {
|
|
|
[[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
|
|
[[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
|
|
|
[[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
|
|
[[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
|
|
|
return static_cast<Ret>(std::invoke(Candidate, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
|
|
return static_cast<Ret>(std::invoke(Candidate, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
|
|
@@ -75,7 +78,7 @@ class delegate<Ret(Args...)> {
|
|
|
|
|
|
|
|
template<auto Candidate, typename Type, std::size_t... Index>
|
|
template<auto Candidate, typename Type, std::size_t... Index>
|
|
|
[[nodiscard]] auto wrap(Type &, std::index_sequence<Index...>) noexcept {
|
|
[[nodiscard]] auto wrap(Type &, std::index_sequence<Index...>) noexcept {
|
|
|
- return [](const void *payload, Args... args) -> Ret {
|
|
|
|
|
|
|
+ return [](const void *payload, Args... args) -> return_type {
|
|
|
Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
|
|
Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
|
|
|
[[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
|
|
[[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
|
|
|
[[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type &, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
|
|
[[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type &, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
|
|
@@ -85,7 +88,7 @@ class delegate<Ret(Args...)> {
|
|
|
|
|
|
|
|
template<auto Candidate, typename Type, std::size_t... Index>
|
|
template<auto Candidate, typename Type, std::size_t... Index>
|
|
|
[[nodiscard]] auto wrap(Type *, std::index_sequence<Index...>) noexcept {
|
|
[[nodiscard]] auto wrap(Type *, std::index_sequence<Index...>) noexcept {
|
|
|
- return [](const void *payload, Args... args) -> Ret {
|
|
|
|
|
|
|
+ return [](const void *payload, Args... args) -> return_type {
|
|
|
Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
|
|
Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
|
|
|
[[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
|
|
[[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
|
|
|
[[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type *, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
|
|
[[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type *, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
|
|
@@ -134,7 +137,7 @@ public:
|
|
|
instance = nullptr;
|
|
instance = nullptr;
|
|
|
|
|
|
|
|
if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
|
|
if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
|
|
|
- fn = [](const void *, Args... args) -> Ret {
|
|
|
|
|
|
|
+ fn = [](const void *, Args... args) -> return_type {
|
|
|
return Ret(std::invoke(Candidate, std::forward<Args>(args)...));
|
|
return Ret(std::invoke(Candidate, std::forward<Args>(args)...));
|
|
|
};
|
|
};
|
|
|
} else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
|
|
} else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
|
|
@@ -164,7 +167,7 @@ public:
|
|
|
instance = &value_or_instance;
|
|
instance = &value_or_instance;
|
|
|
|
|
|
|
|
if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>) {
|
|
if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>) {
|
|
|
- fn = [](const void *payload, Args... args) -> Ret {
|
|
|
|
|
|
|
+ fn = [](const void *payload, Args... args) -> return_type {
|
|
|
Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
|
|
Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
|
|
|
return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
|
|
return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
|
|
|
};
|
|
};
|
|
@@ -188,7 +191,7 @@ public:
|
|
|
instance = value_or_instance;
|
|
instance = value_or_instance;
|
|
|
|
|
|
|
|
if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, Args...>) {
|
|
if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, Args...>) {
|
|
|
- fn = [](const void *payload, Args... args) -> Ret {
|
|
|
|
|
|
|
+ fn = [](const void *payload, Args... args) -> return_type {
|
|
|
Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
|
|
Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
|
|
|
return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
|
|
return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
|
|
|
};
|
|
};
|
|
@@ -279,7 +282,7 @@ public:
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
const void *instance{};
|
|
const void *instance{};
|
|
|
- function_type *fn{};
|
|
|
|
|
|
|
+ delegate_type *fn{};
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|