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 16:15:36

On Sun, Jul 17, 2011 at 12:35 PM, Edward Diener <eldiener_at_[hidden]>wrote:

> On 7/17/2011 2:22 PM, Jeffrey Lee Hellrung, Jr. wrote:
>> Well, if the naming scheme is simple (I think it is), I don't think we
>> have
>> to worry about the metafunction provider nor the metafunction user not
>> understanding the naming scheme. Have users been requesting these GEN
>> macros? Are the GEN macros targeted toward the metafunction provider (who
>> should know what identifiers he's injecting into the namespace) or the
>> metafunction user (who will need to read documentation either way to get
>> the
>> name of the metafunction)? I don't really see the point, and I now refer
>> you to my comment about "less is more" at the top.
> The GEN macros are targeted at the metafunction user. If people really feel
> it is easier reading the documentation and looking at the way that
> metafunction names are generated than to just repeat the metafunction macro,
> add _GEN to the end, and pass it element name to automatically generate the
> metafunction name, I may remove the GEN macros. I still think that using the
> equivalent GEN macro for each metafunction macro is a nice and easy way to
> get the refer to the name of the metafunction for each metafunction macro.

They'd have to read the documentation to figure out how to use the GEN
macros, too :) Also "reading the documentation and looking at the way that
metafunction names are generated" is 13 words worth work, while "repeat the
metafunction macro, add _GEN to the end, and pass it element name to
automatically generate the metafunction name" is 20 words worth work, so the
former is by far easier than the latter :)

I'll go with whatever the general consensus is which comes out of the

 They do supply a nested 'type', whose 'type::value' is the same as the
>>> 'value'. I have not documented this because the nested 'type' is
>>> unimportant
>>> in using the metafunctions. The metafunction generated by
>>> BOOST_TTI_MEMBER_TYPE(name) does have just a nested 'type', which is
>>> important and used.
>> Okay, as I hadn't looked yet at the implementation, I didn't know it had a
>> nested type. It *is* worth documenting, I think.
> OK, I can do it. Since I keep saying "metafunction" in the documentation I
> admit I am surprised that others did not assume that I am generation a real
> metafunction, ie. that it must have a nested 'type'.

That is a good point regarding your use of the term "metafunction". I think
it was only confusing because you mentioned the value member, hence one
concludes that the value member is the only part of the public API.

> I understand; perhaps I should've explicitly asked: Why are you limiting
>> it
>> to that particular query? Surely the metaprogrammer may want to check if
>> the typedef has other properties as well, no?
> What other properties can a typedef have ? In C++ it is just an alias
> 'name' for a type.

Sorry: "Surely the metaprogrammer may want to check if the type has other
properties as well, no?"

> - I think BOOST_TTI_HAS_MEMBER_FUNCTION can subsume
>>>> BOOST_TTI_HAS_COMP_MEMBER_****FUNCTION, since I think you could just
>>>> dispatch on
>>>> whether the first template parameter to the generated metafunction is a
>>>> pointer-to-member-function or not. Another convenient syntax may be
>>>> has_member_function_xxx< T, Return ( Arg0, Arg1 )>, so that all of the
>>>> following are equivalent:
>>>> has_member_function_xxx< Return (T::*)( Arg0, Arg1 )>
>>>> has_member_function_xxx< T, Return ( Arg0, Arg 1 )> // can
>>>> still
>>>> use lambda expressions for T, has similar format as other introspection
>>>> metafunctions
>>>> has_member_function_xxx< T, Return, boost::mpl::vector2<
>>>> Arg0,
>>>> Arg1
>>>> // ugliest, but most flexible with Boost.MPL
>>>>>> - Likewise, I think BOOST_TTI_HAS_STATIC_MEMBER_****FUNCTION can
>>>> subsume
>>>> BOOST_TTI_HAS_COMP_STATIC_****MEMBER_FUNCTION, and likewise I think the
>>>> syntax
>>>> has_static_member_function_****xxx< T, Return ( Arg0, Arg1 )> would
>>>> be
>>>> convenient.
>>>> - Although this doesn't have to do with condensing macros, it would
>>>> make
>>>> the library a little more consistent to allow pointer-to-member syntax
>>>> for
>>>> BOOST_TTI_HAS_MEMBER_DATA, e.g., has_member_data_xxx< U T::*>.
>>>> - Lastly, BOOST_TTI_HAS_STATIC_MEMBER_****FUNCTION( xxx ) can be
>>>> reexpressed
>>>> as BOOST_TTI_HAS_MEMBER_FUNCTION( static xxx ), and likewise for
>>> Figuring out the different template parameters and their number at
>>> compile-time may be possible. I will look into it.
>> Looks like it would be a simple matter of dispatching on
>> is_member_function_pointer, is_function, and is_member_object_pointer from
>> Boost.TypeTraits.
> It is little more complicated than that. The second parameter ( the first
> is the enclosing type ) in the non-composite form is the return type. A
> return type could be a member function pointer itself etc., right ?

I think you can dispatch based on
(a) the first template parameter is a member function pointer (or member
data pointer for MEMBER_DATA)
(b) otherwise, the first template parameter is the enclosing type
    (i) the second template parameter is a function type
    (ii) the second template parameter is a not a function type, in which
case it is the result type of the member function
        - the third parameter is a Boost.MPL sequence, in which case it
specifies the parameter types of the member function
        - the last parameter, if present, is the Boost.FunctionTypes tag

[And WTH (W = Why) am I getting random asterisks put in my replies???]

> Oops, I just found an inconsistency between your
>> terminology (member data) and Boost.TypeTraits (member object)...
> I am pretty comfortable with member data, but really I do not think there
> is any consistent name for this in C++ terminologies. Besides this has
> already been discussed in other TTI revew threads pretty extensively.

I am also fine with the TTI terminology, I just wish there was uniformity :/

> I also presume,
>> from your preceding comment, that checking compatible template signatures
>> is
>> not supported. E.g., I want to check if T::template tmpl<0> is
>> syntactically well-formed, which it would be if T had a nested template
>> declared as template< int, class = void> struct tmpl or template<
>> unsigned
>> int> struct tmpl, but I suspect that TTI does not provide the facilities
>> to
>> do this.
> No it does not provide such a possibility. Maybe it can be done but I do
> not think so right now that it is possible.

I seem to remember that the Boost.MPL metafunction-generating macro for
introspecting templates detected "variadic templates" (in this context, I
mean templates with only type parameters, some of which may be defaulted);
is this accurate? This is basically what the BOOST_TTI_HAS_TEMPLATE macro
detects, right? I should look through the implementation :/

Strangely enough, if gcc and VC++ were not broken one could test the
> instantiation of a nested function template.

Right, I read that section.

> Actually I had been creating code in a boost::tti::detail namespace, but
> when I drop generating a namespace I will have to come up with another
> scheme. I am glad you brought this up. I can still add some fixed
> boost::tti::detail functionality I am need via the header file inclusion.

Right, and maybe put the per-metafunction-specific stuff in the private
section of the metafunction, if possible... Although limited the macro
invocations to namespace scope isn't a huge limitation, I don't think.

- Jeff

Boost list run by bdawes at, gregod at, cpdaniel at, john at