|
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