
Hello, I've attached a rewrite of the patch I previously submitted that includes documentation and new tests in MPL's test suite. Apply with 'patch -p0 < djw_has_xxx_template.patch' from the boost root directory. This implementation is based on comp.lang.c++.moderated USENET postings from Rani Sharoni (2002-03-17, http://tinyurl.com/2u2a9f) and Aleksey Gurtovoy (2002-03-19, http://tinyurl.com/376y7c), the current has_xxx implementation (especially ideas in the msvc 8.0 implementation from Daniel Wallin, I believe), the 3rd code example in section 14.2.8 of the standard, and the discussion on this thread (especially postings from Guillaume Melquiond who pointed out to me the need for a seperate "substitute" template). Also, thanks to Aleksey Gurtovoy and David Abrahams for implementing has_xxx in the first place and especially for including citations of the USENET discussions in has_xxx.hpp. They were invaluable. By testing combinations of different members, member names, member types, and member template arities, I have 142 individual tests (i.e. assertions) for detecting member templates. Here is the pass/fail rate for the compilers I tested. gcc 3.4, 4.0, 4.1 - 142/142 gcc 3.3 - 139/142 msvc 7.1, 8.0: 142/142 comeau 4.3.8 alpha online: 93/142 (I had to run it through the preprocessor and then paste it on the website's form) The tests that fail on gcc 3.3 are for rejecting member templates with the correct name but incorrect number of parameters. Comeau also cannot do this and additionally cannot reject members with the correct name that aren't templates (typedefs and structs) and cannot detect member templates with the correct name but no required parameters (all parameters have defaults). Other changes from my previous patch include: 1) changed the name of BOOST_MPL_HAS_TEMPLATE_XXX_TRAIT_DEF to BOOST_MPL_HAS_XXX_TEMPLATE_DEF, same for NAMED_DEF version. It's more concise. Also, by default the name of the generated metafunction is a concatination of 'has_' and the name of the nested template rather than 'has_template_' and the name of the nested template. This is also done for brievity's sake. 2) included the macro definitions in has_xxx.hpp rather than creating new files. These are closely related, and at some point in the future the implementations for has_xxx for nested types and has_xxx for nested templates could be folded together to improve code reuse. 3) created the following new documentation files - libs/mpl/doc/src/refmanual/CFG_NO_HAS_TEMPLATE_XXX.rst - libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst - libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst I wasn't sure how to generate the HTML and pdf manuals. 4) added the tests to has_xxx.cpp and no_has_xxx.cpp I'm assuming this is too late to be considered for 1.34, so I built the patch off the cvs trunk rather than RC_1_34_0. I replaced my previous patch on SF patch tracker with the current one. As for future work: 1) Though the two most common compilers, gcc 4 and msvc 7.1/8.0, pass all the tests, it would be nice to have work arounds so that all compilers pass all the tests. 2) I believe this can be extended along the lines of John Madsen's comp.lang.c++.moderated posting (1999-11-12, http://tinyurl.com/2wqorl) to test for other sorts of members by creating new substitute templates for SFINAE. I made an initial try at detecting member data and had some success. If there's interest I could look into extending has_xxx for member templates into a more complete set of compile time type introspection metafunctions... something like has_member_data, has_member_function, has_member_type, has_member_template. The last two metafunction would supersede the currect has_xxx and my has_xxx for templates. Let me know if you have trouble applying the patch or if you have suggests to improve this. Thanks! Daniel P.S. The example of using BOOST_MPL_HAS_XXX_TEMPLATE_DEF that I posted with my original patch should now look like the following (if you want to copy and past it for a quick test). #include <utility> #include <boost/mpl/assert.hpp> #include <boost/mpl/has_xxx.hpp> #include <boost/utility/result_of.hpp> // Create has_result to detect nested members like // template<class T> struct result {}. // The first macro argument is the member name and the second argument // is the number of template parameters. BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result, 1) struct pair_maker { template<typename F> struct result; template<typename F, typename Arg0, typename Arg1> struct result<F(Arg0, Arg1)> { typedef std::pair<Arg0, Arg1> type; }; template<typename Arg0, typename Arg1> typename result<pair_maker(Arg0, Arg1)>::type operator()(Arg0 a0, Arg1 a1) const { return std::make_pair(a0, a1); } }; int main() { using namespace boost; typedef char value_type; BOOST_MPL_ASSERT(( has_result< pair_maker, pair_maker(value_type, value_type) > )); typedef result_of< pair_maker(value_type, value_type)
::type result_type;
value_type x, y; pair_maker f; result_type result = f(x, y); }