Skip to content

Instantly share code, notes, and snippets.

@isc30
Last active November 30, 2022 12:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save isc30/fab67e5956fe8f2097bed84ebc42c1e8 to your computer and use it in GitHub Desktop.
Save isc30/fab67e5956fe8f2097bed84ebc42c1e8 to your computer and use it in GitHub Desktop.
template-based wrapper for any callable with signature + metadata traits
#pragma once
#include <type_traits>
#include <functional>
template<typename TCallable, typename TSignature>
constexpr bool is_callable_as_v = std::is_constructible<std::function<TSignature>, TCallable>::value;
template<
typename TCallable,
typename TSignature,
typename = std::enable_if_t<is_callable_as_v<TCallable, TSignature>>>
using Callable = TCallable;
template<typename TCallable>
struct CallableMetadata
: CallableMetadata<decltype(&TCallable::operator())>
{
};
template<class TClass, typename TReturn, typename... TArgs>
struct CallableMetadata<TReturn(TClass::*)(TArgs...)>
{
using class_t = TClass;
using return_t = TReturn;
using args_tuple_t = std::tuple<TArgs...>;
using ptr_t = TReturn(*)(TArgs...);
// Beware! this function makes a copy of the closure! and of the arguments when called!
static ptr_t generatePointer(const TClass& closure)
{
static TClass staticClosureCopy = closure;
return [](TArgs... args)
{
return staticClosureCopy(args...);
};
}
};
template<class TClass, typename TReturn, typename... TArgs>
struct CallableMetadata<TReturn(TClass::*)(TArgs...) const>
{
using class_t = TClass;
using return_t = TReturn;
using args_tuple_t = std::tuple<TArgs...>;
using ptr_t = TReturn(*)(TArgs...) const;
// Beware! this function makes a copy of the closure! and of the arguments when called!
static ptr_t generatePointer(const TClass& closure)
{
static TClass staticClosureCopy = closure;
return [](TArgs... args)
{
return staticClosureCopy(args...);
};
}
};
// Beware! this function makes a copy of the closure! and of the arguments when called!
template<typename TCallable>
auto* callableToPointer(const TCallable& callable)
{
return CallableMetadata<TCallable>::generatePointer(callable);
}
Copy link

ghost commented Sep 27, 2021

Clang 12 is complaining:

error: pointer to function type cannot have 'const' qualifier

on line 47

I removed the "const" qualifier, and it seems to work, but maybe I am missing something?

@isc30
Copy link
Author

isc30 commented Nov 30, 2022

I have no idea tbh, i wrote this a long time ago

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment