
On Sat, Jul 16, 2011 at 9:56 PM, Jeffrey Lee Hellrung, Jr. < jeffrey.hellrung@gmail.com> wrote:
On Sat, Jul 16, 2011 at 7:58 PM, Jeffrey Lee Hellrung, Jr. < jeffrey.hellrung@gmail.com> 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