$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] "Simple C++11 metaprogramming"
From: Peter Dimov (lists_at_[hidden])
Date: 2015-06-05 09:23:13
Eric Niebler wrote:
> If a user defines a specialization for common_type<MyInt, int>, it won't 
> get used when computing common_type<MyInt, int, int>. I think that would 
> complicate your implementation somewhat.
It does. I now need a SFINAE-friendly defer in addition to eval_or_default.
// 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>
    using builtin_common_type =
    decltype(declval<bool>()? declval<T1>(): declval<T2>());
template<class T1, class T2>
    struct common_type<T1, T2>:
    mp_if_c<
        std::is_same<T1, std::decay_t<T1>>::value
        && std::is_same<T2, std::decay_t<T2>>::value,
        mp_defer<builtin_common_type, T1, T2>,
        common_type<std::decay_t<T1>, std::decay_t<T2>>>
{
};
template<class T1, class T2, class... T>
    using common_type_impl =
    common_type<typename common_type<T1, T2>::type, T...>;
template<class T1, class T2, class...T>
    struct common_type<T1, T2, T...>:
    eval_or_default<common_type<>, common_type_impl, T1, T2, T...>
{
};
mp_defer was before just
template<template<class...> class F, class... T> struct mp_defer
{
    using type = F<T...>;
};
but now has to be
// mp_defer
struct empty
{
};
template<template<class...> class F, class... T> struct mp_defer_impl
{
    using type = F<T...>;
};
template<template<class...> class F, class... T>
    using mp_defer =
    mp_if<is_evaluable<F, T...>, mp_defer_impl<F, T...>, empty>;
> I like the mutual recursion between common_type and common_type_impl, but 
> really you've just implemented fold, and it
would be better to have fold as a separate reusable algorithm. I see that 
you've isolated the SFINAE-friendliness in your library to the 
eval_or_default utility. It's an interesting choice, but I think it's why 
you can't use a fold here, am I right?
I can use a fold if the fold is SFINAE-friendly, yes. But I'm not yet 
convinced that it has to be. This would imply making all algorithms 
SFINAE-friendly, or making fold an exception, or adding both 
SFINAE/non-SFINAE variants of some. None of those sounds appealing.