delegate: internal const correctness on return types

This commit is contained in:
Michele Caini
2024-10-11 19:06:18 +02:00
parent 031f340d62
commit aecdb84606

View File

@@ -64,9 +64,12 @@ class delegate;
*/
template<typename Ret, typename... 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>
[[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]] 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))...));
@@ -75,7 +78,7 @@ class delegate<Ret(Args...)> {
template<auto Candidate, typename Type, std::size_t... Index>
[[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));
[[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));
@@ -85,7 +88,7 @@ class delegate<Ret(Args...)> {
template<auto Candidate, typename Type, std::size_t... Index>
[[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));
[[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));
@@ -134,7 +137,7 @@ public:
instance = nullptr;
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)...));
};
} else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
@@ -164,7 +167,7 @@ public:
instance = &value_or_instance;
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));
return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
};
@@ -188,7 +191,7 @@ public:
instance = value_or_instance;
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));
return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
};
@@ -279,7 +282,7 @@ public:
private:
const void *instance{};
function_type *fn{};
delegate_type *fn{};
};
/**