$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [GSoC][MPL11] Post C++Now update
From: Louis Dionne (ldionne.2_at_[hidden])
Date: 2014-05-20 14:06:56
Eric Niebler <eniebler <at> boost.org> writes:
>
> On 05/19/2014 10:28 AM, Louis Dionne wrote:
> > Type-only predicate
> > -------------------
> > struct odd {
> > template <typename T>
> > constexpr auto operator()(T t) const { return t % int_<2>; }
> > };
> >
> > static_assert(std::is_same<
> > decltype(any(odd{}, list(int_<1>, int_<2>))),
> > Bool<true>
> > >::value, "");
> >
>
> What does it look like to have a compile-time list containing void? Or
> an array type? Or a function type (i.e., not a pointer to function)? Or
> an abstract type?
static_assert(
fmap(trait::add_pointer, list_t<void, int(), char[10]>)
==
list_t<void*, int(*)(), char(*)[10]>
, "");
static_assert(
head(fmap(trait::add_pointer, list_t<void, int, char>))
==
type<void*>
, "");
static_assert(std::is_same<
decltype(
head(fmap(trait::add_pointer, list_t<void, int, char>))
)::type,
void*
>::value, "");
Here's how it works. We provide the following helper for convenience:
template <typename ...Xs>
constexpr auto list_t = list(type<Xs>...);
where type<T> is a constexpr variable template of type Type<T>. Type<T>
provides a nested ::type alias to T and also provides adapted versions of
the type_traits as constexpr functions. For example, it is possible to write
static_assert(trait::add_pointer(type<T>) == type<T*>, "");
static_assert(std::is_same<decltype(type<T*>)::type, T*>::value, "");
Note that type<T> == type<U> is (roughly) equivalent to std::is_same<T, U>.
The way I see it is that we're trying to represent types as constexpr objects.
When trying to do that, a natural question is: what are the "methods" of these
objects? What are the operations that we can do on those objects? The answer
to that is "whatever operation we can do on a type", which correspond exactly
to the type_traits. So type_traits end up being the API of objects of type
Type<...>, which are nothing but a special case of compile-time-manipulable
objects. When we see things this way, it seems natural to think of the MPL as
a special case of heterogeneous constexpr computation.
There is still one problem that has to do with ADL (it is not limited
to type<>):
template <bool b = false>
struct invalid { static_assert(b, "can't instantiate invalid<>"); };
static_assert(type<invalid<>> != type<void>, "");
This is going to assert in invalid<> because the ADL required by != will
trigger the instantiation of invalid<> . One obvious workaround is to
provide named operators like not_equal, but real operators provide a
large plus for legibility. If someone has an idea, please let me know.
Regards,
Louis Dionne