
On 7/17/2011 4:15 PM, Jeffrey Lee Hellrung, Jr. wrote:
On Sun, Jul 17, 2011 at 12:35 PM, Edward Diener<eldiener@tropicsoft.com>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