Skip to content

Instantly share code, notes, and snippets.

@notfoundry
Last active February 19, 2020 16:36
Show Gist options
  • Select an option

  • Save notfoundry/9ec3ebf9f6ffbc56505202226ec93359 to your computer and use it in GitHub Desktop.

Select an option

Save notfoundry/9ec3ebf9f6ffbc56505202226ec93359 to your computer and use it in GitHub Desktop.
Type-level lambda expressions for template metaprogramming in C++20
#include <boost/preprocessor/punctuation/is_begin_parens.hpp>
#include <boost/preprocessor/punctuation/remove_parens.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/variadic_seq_to_seq.hpp>
namespace metalambda {
template <auto T>
struct template_funcall_adapter {
template <class... Ts>
using f = decltype(T.template operator()<Ts...>());
};
}
#define METALAMBDA_RETURN(...) return __VA_ARGS__(); }>
#define METALAMBDA_RETURN_THUNK METALAMBDA_RETURN
#define METALAMBDA_GENERATE_LOCAL(r, data, elem) using BOOST_PP_REMOVE_PARENS(elem);
#define METALAMBDA_LOCALS(seq) BOOST_PP_SEQ_FOR_EACH(METALAMBDA_GENERATE_LOCAL, _, BOOST_PP_VARIADIC_SEQ_TO_SEQ(seq)) METALAMBDA_RETURN
#define METALAMBDA_DISPATCH_LOCALS_OR_PARAMS_IMPL(continuation, ...) continuation(__VA_ARGS__)
#define METALAMBDA_DISPATCH_LOCALS_OR_PARAMS(...) METALAMBDA_DISPATCH_LOCALS_OR_PARAMS_IMPL(BOOST_PP_IF(BOOST_PP_IS_BEGIN_PARENS(__VA_ARGS__), METALAMBDA_LOCALS, METALAMBDA_RETURN_THUNK), __VA_ARGS__)
#define METALAMBDA_PARAMS(...) ::metalambda::template_funcall_adapter<[]<__VA_ARGS__>(){ METALAMBDA_DISPATCH_LOCALS_OR_PARAMS
#define METALAMBDA(...) METALAMBDA_PARAMS(__VA_ARGS__)
#define II(...) METALAMBDA(__VA_ARGS__)
#define METALAMBDA_RETURN_AND_EVAL(...) return __VA_ARGS__(); }>::template f<>
#define LET(...) typename BOOST_PP_CAT(METALAMBDA(class = void)(__VA_ARGS__), _AND_EVAL)
#include <kvasir/mpl/mpl.hpp>
using size_lt = II(class T1, class T2)(kvasir::mpl::bool_<sizeof(T1) < sizeof(T2)>);
using int_long_list =
LET((x = int)(y = long))
(kvasir::mpl::list<x, y>);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment