Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flip the order of X and Y in MACRO(X)(Y)

I have a C++ macro-based DSL that defines a macro like this:

#define RETURNS(...) \
    enable_if_t<__VA_ARGS__ WHEN

#define WHEN(...) \
    , EAT_ ## __VA_ARGS__ >

#define EAT_requires

This is for use like:

template<class T>
auto some_function(T t) ->
    RETURNS(int)
        (requires SomeConcept<T>)

Which expands to:

template<class T>
auto some_function(T t) ->
    enable_if_t<int, SomeConcept<T>>

(When C++20 concepts are enabled, this expands to a real requires clause.)

I would prefer the order of the parameters to be flipped. That is, I would like it to generate this:

template<class T>
auto some_function(T t) ->
    enable_if_t<SomeConcept<T>, int>

I think it's not possible. Can some clever PP hacker prove me wrong?

like image 778
Eric Niebler Avatar asked Feb 12 '19 20:02

Eric Niebler


2 Answers

If it is tolerable to omit an open paren, you can achieve it like this:

#define UNWRAP(...) __VA_ARGS__

#define RETURNS(...) \
    WHEN ((__VA_ARGS__),

#define WHEN(x, ...) \
    enable_if_t<EAT_ ## __VA_ARGS__, UNWRAP x>

#define EAT_requires

template<class T>
auto some_function(T t) ->
    RETURNS(pair<int, int>)
        requires SomeConcept<T, int>)

Input:

template<class T>
auto some_function(T t) ->
    RETURNS(pair<int, int>)
        requires SomeConcept<T, int>)

Output:

template<class T>
auto some_function(T t) ->
    enable_if_t< SomeConcept<T, int>, pair<int, int> >
like image 89
Nikita Kniazev Avatar answered Sep 29 '22 11:09

Nikita Kniazev


Why don't you just use something like

template<class T,bool B>
using reverse_enable_if_t=enable_if_t<B,T>;
like image 31
Joaquín M López Muñoz Avatar answered Sep 29 '22 11:09

Joaquín M López Muñoz