Boost logo

Boost :

Subject: Re: [boost] "Simple C++11 metaprogramming"
From: Peter Dimov (lists_at_[hidden])
Date: 2015-06-04 19:30:17

Eric Niebler wrote:

> I made Meta SFINAE-friendly on a lark and found it useful in practice.
> (See this thread[*] where Louis and I compared common_type implementations
> with Meta and Hana.)
> [*]

Having a SFINAE-friendly fold helps, but here's my implementation of this

// common_type

template<class...> struct common_type
    using type_not_present = void***[];

template<class T> struct common_type<T>: std::decay<T>

template<class T1, class T2, class... T>
    using common_type_impl =
    common_type<decltype(declval<bool>()? declval<T1>(): declval<T2>()),

template<class T1, class T2, class...T>
    struct common_type<T1, T2, T...>:
    eval_or_default<common_type<>, common_type_impl, T1, T2, T...>

#include <iostream>
#include <typeinfo>

int main()
    std::cout << typeid( common_type<char volatile[], void*, int const[],
void*>::type ).name() << std::endl;
    std::cout << typeid( common_type<char, float, int*,
double>::type_not_present ).name() << std::endl;

where eval_or_default<Def, F, T...> checks is_evaluable<F, T...> (from Bruno
Dutra's earlier message) and returns F<T...> if evaluable, Def if not.

Getting it right was a bit tricky, but I find the final result quite
readable. (This implements the specification in the latest C++17 draft.)

Boost list run by bdawes at, gregod at, cpdaniel at, john at