Boost logo

Boost :

Subject: Re: [boost] [TTI] Review for The Type Traits Introspection library by Edward Diener **extended**
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2011-07-17 01:25:02


On Sat, Jul 16, 2011 at 9:56 PM, Jeffrey Lee Hellrung, Jr. <
jeffrey.hellrung_at_[hidden]> wrote:

> On Sat, Jul 16, 2011 at 7:58 PM, Jeffrey Lee Hellrung, Jr. <
> jeffrey.hellrung_at_[hidden]> wrote:
> [...]
>
>> * I don't see a compelling use case for "has type with check", where
>> "check" checks if the type is the same as some given type. I would think it
>> would be more useful for "check" to evaluate some Boost.MPL metafunction
>> (and the old behavior is arguably clearer now: boost::is_same< U,
>> boost::mpl::_1 >), and then you can roll this functionality into the "no
>> check" TTI metafunction by defaulting the MPL metafunction template
>> parameter to boost::mpl::always< boost::true_type > (or similar). Indeed, I
>> *think* this would remove the need for BOOST_TTI_MEMBER_TYPE for the use
>> case you present (see below).
>>
> [...]
>
> I wanted to elaborate on this idea to see if, indeed, I can solve the same
> problems outlined in the sections "Nested Types" and "Using the Nullary Type
> Metafunctions" with little additional syntactic burden.
>
> Concretely, I'm proposing that
>
> BOOST_TTI_HAS_TYPE( name )
>
> generates a metafunction has_type_'name' such that
>
> has_type_'name'<T>::value == true iff T has a nested 'name' type
> has_type_'name'<T,P>::value == true iff T has a nested 'name' type *and*
> boost::mpl::apply1< P, T::'name' >::type::value == true
>
[...]

> I'll investigate the use case(s) given in the section "Using the Nullary
> Type Metafunctions" in a separate post.
>

And here I am again. This time, our class structure looks like (reformatted
with comments removed):

struct T
{
    struct BType
    {
        template< class, class, int, class template< class > class, class
long >
        struct ManyParameters
        { };

        struct CType
        {
            template< class >
            struct AMemberTemplate
            { };

            struct DType
            {
                typedef double ADoubleType;

                template< class, class, int, short, class, template< class,
int > class, class >
                struct MoreParameters
                { };

                int IntFunction(short) const
                { return 0; }

                static short DSMember;

                static int SIntFunction(long, double)
                { return 2; }
            };
        };
    };

    BType IntBT;
};

We assume the following declarations:

BOOST_TTI_HAS_TYPE( BType )
BOOST_TTI_HAS_TYPE( CType )
BOOST_TTI_HAS_TYPE( DType )

using boost::mpl::_1;
using boost::mpl::lambda;

This would be how one would express the first two queries in the section
"Using the Nullary Type Metafunctions" via my above proposed change to
BOOST_TTI_HAS_TYPE.

(a) Does T have a nested type called 'DType' within 'BType::CType'?

has_type_BType<
    T,
    has_type_CType<
        _1,
        typename lambda< has_type_DType< _1 > >::type
>
>::value

(b) Does T have a nested typedef called 'ADoubleType' within
'BType::CType::DType' whose type is a 'double'?

BOOST_TTI_HAS_TYPE( ADoubleType )
using boost::is_same;

has_type_BType<
    T,
    has_type_CType<
        _1,
        typename lambda< has_type_DType<
            _1,
            typename lambda< has_type_ADoubleType<
                _1,
                typename lambda< is_same< _1, double > >::type
> >::type
> >::type
>
>

I think the remaining queries look very similar and I don't foresee any
difficulty in constructing them. Like my previous post, some repetitive
constructs can be refactored into a separate template if you find yourself
making multiple queries on a deeply nested type.

I also think this syntax additionally has the advantage of directly
reflecting the hierarchy of types you're querying, rather than reversing
it. I.e., has_type_BType above is at the outermost level of the query and
has_type_ADoubleType is at the innermost level of the query; on the other
hand, using BOOST_TTI_MEMBER_TYPE or the nullary metafunctions appears to
put the innermost type you're querying at the outermost level and vice
versa.

- Jeff


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