Boost logo

Boost :

Subject: Re: [boost] is_range metafunction
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2008-10-06 21:30:32


On Mon, Oct 6, 2008 at 7:02 AM, Joel Falcou <joel.falcou_at_[hidden]> wrote:
> Mathias Gaunard a écrit :
>>
>> As of today, in GCC 4.4, you can do something equivalent but have to be
>> significantly more verbose:
>>
>> template<typename T, size_t Cond>
>> struct foo_type
>> {
>> typedef decltype(((T*)0)->foo()) type;
>> };
>>
>> template<typename T>
>> typename foo_type<T, sizeof(((T*)0)->foo() > 0)>::type foo(T&& t)
>> {
>> return t.foo();
>> }
>>
>> (You cannot put decltype directly in the return type because of name
>> mangling issues)
>
> Can't this be packaged into some macro like BOOST_HAS_XXX ?

Yeah, that's kind of what I was getting at by a compile time eval or
is_compilable. But those are misnomers. You're not checking validity
for whole blocks or statements, just single expressions with a given
type. But yeah, you could wrap the general boilerplate in a
preprocessor metafunction and maybe call it something like
BOOST_HAS_EXPRESSION.

Of course, the expressions I'm interested in would check for a
concept, for example, an expression like
function_requires<ForwardRange<T> >(). So for a boolean metafunction
that checks if a type models some concept, the final C++0x code (for
platforms without concept language support) would be something like:

template<class ConceptCeck, class T>
struct has_concept {
    typedef char (&yes)[1];
    typedef char (&no)[2];

    template<typename T>
    static no test(...);

    template<typename T>
    static yes test(T* t)
        -> decltype(function_requires<ConceptCheck<T> >());

public:
    static const bool value
        = sizeof(test<T>(0)) == sizeof(yes);
    typedef boost::mpl::bool_<value> type;
};

BOOST_MPL_ASSERT((has_concept<ForwardRange, vector<int> >));

For platforms with concept language support, you would use CRFINAE
instead of expression SFINAE on the two test() functions. At least,
this is the general idea. I assume something like this would work...

Daniel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk