Created
August 7, 2022 11:20
-
-
Save klemens-morgenstern/12d05dc62c17c969ca9015a7ebee6085 to your computer and use it in GitHub Desktop.
function-describe attempt
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
#include <boost/describe.hpp> | |
#include <boost/preprocessor.hpp> | |
#include <utility> | |
#include <boost/mp11.hpp> | |
namespace boost::describe | |
{ | |
namespace detail { | |
template<typename Ptr, Ptr Func> | |
struct describe_function_tag {}; | |
template<typename ... Args, typename Return> | |
constexpr auto cast_helper(Return (*p)(Args...)) -> Return (*)(Args...) | |
{ | |
return p; | |
} | |
template<typename T> | |
struct interpret_helper | |
{ | |
using type = T; | |
template<typename U> | |
constexpr interpret_helper<T> operator=(U &&) const; | |
}; | |
} | |
template<typename T, T (*Ptr)()> | |
auto tag_invoke(detail::describe_function_tag<T(*)(), Ptr>, T (*)()) | |
{ | |
return boost::mp11::mp_list<>{}; | |
} | |
template<typename Ptr, Ptr Func> | |
auto describe_function() | |
{ | |
return tag_invoke(detail::describe_function_tag<Ptr, Func>{}, static_cast<Ptr>(Func)); | |
} | |
} | |
#define BOOST_DESCRIBE_FUNCTION_TAG_IMPL(Type, ...) ::boost::describe::detail::interpret_helper<Type>{} | |
#define BOOST_DESCRIBE_FUNCTION_TAG_STEP(i, _ , Value) \ | |
BOOST_PP_COMMA_IF(BOOST_PP_SUB(i, 1)) decltype( BOOST_DESCRIBE_FUNCTION_TAG_IMPL Value)::type | |
#define BOOST_DESCRIBE_FUNCTION_STEP_DESCRIPTOR_IMPL_2(Type, Name) \ | |
struct Name ## _t \ | |
{ \ | |
using type = Type; \ | |
constexpr static auto name() -> const char (&)[sizeof(#Name)] { return #Name; } \ | |
constexpr static bool has_default() { return false; }\ | |
} Name; | |
#define BOOST_DESCRIBE_FUNCTION_STEP_DESCRIPTOR_IMPL_3(Type, Name, Default) \ | |
struct Name ## _t \ | |
{ \ | |
using type = Type; \ | |
constexpr static auto name() -> const char (&)[sizeof(#Name)] { return #Name; }\ | |
static decltype(Default) default_value() {return Default; } \ | |
constexpr static bool has_default() { return true; }\ | |
};; | |
#define BOOST_DESCRIBE_FUNCTION_STEP_DESCRIPTOR_IMPL(...) \ | |
BOOST_PP_OVERLOAD(BOOST_DESCRIBE_FUNCTION_STEP_DESCRIPTOR_IMPL_, __VA_ARGS__)(__VA_ARGS__) | |
#define BOOST_DESCRIBE_FUNCTION_STEP_DESCRIPTOR_STEP(i, _ , Value) \ | |
BOOST_DESCRIBE_FUNCTION_STEP_DESCRIPTOR_IMPL Value ; | |
#define BOOST_DESCRIBE_FUNCTION_DEDUCE_TAG_DECL(Invoked...) \ | |
::boost::describe::detail::describe_function_tag<decltype(Invoked), Invoked>, decltype(Invoked) | |
#define BOOST_DESCRIBE_FUNCTION_STEP_LIST_IMPL(...) BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM(1, __VA_ARGS__), _t) | |
#define BOOST_DESCRIBE_FUNCTION_STEP_LIST_STEP(i, _, Value) \ | |
BOOST_PP_COMMA_IF(BOOST_PP_SUB(i, 1)) BOOST_DESCRIBE_FUNCTION_STEP_LIST_IMPL Value | |
#define BOOST_DESCRIBE_FUNCTION_IMPL(Name, Signature) \ | |
auto tag_invoke(BOOST_DESCRIBE_FUNCTION_DEDUCE_TAG_DECL( \ | |
::boost::describe::detail::cast_helper< BOOST_PP_LIST_FOR_EACH(BOOST_DESCRIBE_FUNCTION_TAG_STEP, _, Signature) >(&Name) )) \ | |
{ \ | |
BOOST_PP_LIST_FOR_EACH(BOOST_DESCRIBE_FUNCTION_STEP_DESCRIPTOR_STEP, _, Signature) \ | |
return ::boost::mp11::mp_list< BOOST_PP_LIST_FOR_EACH(BOOST_DESCRIBE_FUNCTION_STEP_LIST_STEP, _, Signature) >{}; \ | |
} \ | |
#define BOOST_DESCRIBE_FUNCTION(Name, Signature...) BOOST_DESCRIBE_FUNCTION_IMPL(Name, BOOST_PP_VARIADIC_TO_LIST(Signature)) | |
#define BOOST_DESCRIBE_FUNCTION_DEFINE_3(Type, Name, _) Type Name | |
#define BOOST_DESCRIBE_FUNCTION_DEFINE_2(Type, Name) Type Name | |
#define BOOST_DESCRIBE_FUNCTION_DEFINE(...) \ | |
BOOST_PP_OVERLOAD(BOOST_DESCRIBE_FUNCTION_DEFINE_, __VA_ARGS__)(__VA_ARGS__) | |
#define BOOST_DESCRIBE_FUNCTION_DEFINE_STEP(i, _ , Value) \ | |
BOOST_PP_COMMA_IF(BOOST_PP_SUB(i, 1)) BOOST_DESCRIBE_FUNCTION_DEFINE Value | |
#define BOOST_DECLARE_FUNCTION_IMPL(Name, Signature) \ | |
Name ( BOOST_PP_LIST_FOR_EACH(BOOST_DESCRIBE_FUNCTION_DEFINE_STEP, _, Signature) ); \ | |
BOOST_DESCRIBE_FUNCTION_IMPL(Name, Signature); | |
#define BOOST_DECLARE_FUNCTION(Name, Signature...) \ | |
BOOST_DECLARE_FUNCTION_IMPL(Name, BOOST_PP_VARIADIC_TO_LIST(Signature)) | |
int test_func(double value, const char * description = "default"); | |
BOOST_DESCRIBE_FUNCTION(test_func, (double, value), (const char *, description, "default")); | |
int BOOST_DECLARE_FUNCTION(test_func2, (double, value), (const char *, description, "default")); | |
void foobar() | |
{ | |
boost::describe::describe_function<decltype(&test_func), &test_func>(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment