Boost logo

Boost :

Subject: Re: [boost] [TTI] Review for The Type Traits Introspection library by Edward Diener **extended**
From: Edward Diener (eldiener_at_[hidden])
Date: 2011-07-17 18:18:37


On 7/17/2011 4:15 PM, Jeffrey Lee Hellrung, Jr. wrote:
> 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 thought it would be easier, given let's say macro

BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(name),

to refer to the metafunction name as

BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION_GEN(name)

than to remember it is:

'has_static_member_function_name'.

I admit I can be wrong about this but I really, really do not see what
harm those GEN macros can cause for those who want to use them instead.

>
> I'll go with whatever the general consensus is which comes out of the
> review.
>
> 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 understand now where you are going with this ( see my answer to your
other post ).

>
>
>> - 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
>>>>> BOOST_TTI_HAS_STATIC_MEMBER_****DATA.
>>>>>
>>>>>
>>>> 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)

This means switching the first two parameters when specifying the
composite syntax. I am not comfortable with that only because the
library regularizes on the notion that the first template parameter is
the enclosing type. Otherwise your idea below will work.

> (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
> type

I think I can get the arity of the template at compile time and work
with that instead to start.

>
> [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?

Yes.

> This is basically what the BOOST_TTI_HAS_TEMPLATE macro
> detects, right?

Yes, I am just reusing the MPL macro under the table.

> I should look through the implementation :/

Granted. I understand it and its technique pretty well, else I could not
have filtered out from it my exact template matching code.

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

I am glad to hear someone has read it. I was so happy to find that
method and then really disappointed when both gcc and VC++ proved
broken. I could still offer it for clang and other compilers when they
get fixed eventually.

I have gotten e-mail from gcc saying that the target for fixing it is
gcc-4.6.3. For Microsoft they are still in denial but Stephan Lavavej
told me he has reopened my bug report internally.

>
>
>> 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...

Yes. It is eminently doable. i just have to be correct and not cause any
problems. Not putting TTI in a namespace successfully will be my first
update to it once the dust clears after the review.

> Although limited the macro
> invocations to namespace scope isn't a huge limitation, I don't think.

Possibly, but someone has already expressed the fact that they may want
to use TTI within a class. I did not ask for a use case.

Eddie


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