Hello,
I would like a Metafunction similar to the one created by
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF but that would detect nested
template members rather than nested typedefs and classes. It would
allow you to do something like the following:
#include <utility>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/has_template_xxx.hpp>
#include <boost/utility/result_of.hpp>
// Create has_template_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_TEMPLATE_XXX_TRAIT_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_template_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);
}
The attached patch implements this. Apply with 'patch -p0 <
djw_has_template.patch' from the boost root directory. It's based on
the implementation of BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF and works
basically the same way. The patch creates two files
boost/mpl/has_template_xxx.hpp and
boost/mpl/aux_/config/has_template_xxx.hpp. Similarly to has_xxx, when
the maco BOOST_MPL_CFG_NO_HAS_TEMPLATE_XXX is defined the
has_template_xxx::value is always false or a user supplied default. At
this time, I'm unable to write all the various compiler workarounds
that boost/mpl/has_xxx.hpp includes. BOOST_MPL_CFG_NO_HAS_TEMPLATE_XXX
is defined for every workaround mentioned in boost/mpl/has_xxx.hpp.
I've tested it with gcc 3.3, 3.4, 4.0, and 4.1 and it seems to work
fine. If there's any interest, let me know and I'll supply
documentation and tests.
Thanks!
Daniel Walker
--- /dev/null 2006-02-24 11:01:30.000000000 -0500
+++ boost/mpl/has_template_xxx.hpp 2007-03-16 16:27:46.000000000 -0400
@@ -0,0 +1,81 @@
+
+#ifndef BOOST_MPL_HAS_TEMPLATE_XXX_HPP_INCLUDED
+#define BOOST_MPL_HAS_TEMPLATE_XXX_HPP_INCLUDED
+
+// Copyright Daniel Walker 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+//
http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/mpl/bool.hpp>
+
+#include <boost/mpl/aux_/config/has_template_xxx.hpp>
+#include <boost/mpl/aux_/config/msvc_typename.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/type_wrapper.hpp>
+#include <boost/mpl/aux_/yes_no.hpp>
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_HAS_TEMPLATE_XXX)
+
+// Create boolean unary Metafunction to detect a nested template
+// members with n template parameters. This implementation is based on
+// the implementation of BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF from David
+// Abrahams and Aleksey Gurtovoy.
+# define BOOST_MPL_HAS_TEMPLATE_XXX_TRAIT_NAMED_DEF(trait, name, n, default_) \
+template<typename T \
+ BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename U) \
+ , typename fallback_ = boost::mpl::bool_<default_> > \
+struct trait { \
+ struct gcc_3_2_wknd \
+ { \
+ template< typename U > \
+ static boost::mpl::aux::yes_tag test( \
+ boost::mpl::aux::type_wrapper<U> const volatile* \
+ , boost::mpl::aux::type_wrapper< \
+ BOOST_MSVC_TYPENAME U::template name< \
+ BOOST_PP_ENUM_PARAMS(n, U) \
+ > \
+ >* = 0 \
+ ); \
+ \
+ static boost::mpl::aux::no_tag test(...); \
+ }; \
+ \
+ typedef boost::mpl::aux::type_wrapper<T> t_; \
+ BOOST_STATIC_CONSTANT(bool, value = \
+ sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) \
+ == sizeof(boost::mpl::aux::yes_tag) \
+ ); \
+ typedef boost::mpl::bool_<value> type; \
+}; \
+/**/
+
+#else // BOOST_MPL_CFG_NO_HAS_TEMPLATE_XXX
+
+// placeholder implementation
+
+# define BOOST_MPL_HAS_TEMPLATE_XXX_TRAIT_NAMED_DEF(trait, name, n, default_) \
+template< typename T \
+ BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename U) \
+ , typename fallback_ = boost::mpl::bool_<default_> > \
+struct trait \
+{ \
+ BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
+ typedef fallback_ type; \
+}; \
+/**/
+
+#endif // BOOST_MPL_CFG_NO_HAS_TEMPLATE_XXX
+
+# define BOOST_MPL_HAS_TEMPLATE_XXX_TRAIT_DEF(name, n) \
+ BOOST_MPL_HAS_TEMPLATE_XXX_TRAIT_NAMED_DEF( \
+ BOOST_PP_CAT(has_template_, name), name, n, false \
+ ) \
+/**/
+
+#endif // BOOST_MPL_HAS_TEMPLATE_XXX_HPP_INCLUDED
--- /dev/null 2006-02-24 11:01:30.000000000 -0500
+++ boost/mpl/aux_/config/has_template_xxx.hpp 2007-03-16 15:58:30.000000000 -0400
@@ -0,0 +1,26 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_HAS_TEMPLATE_XXX_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_HAS_TEMPLATE_XXX_HPP_INCLUDED
+
+// Copyright Daniel Walker 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+//
http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/mpl/aux_/config/overload_resolution.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_HAS_TEMPLATE_XXX) \
+ && ( defined(BOOST_MPL_CFG_BROKEN_OVERLOAD_RESOLUTION) \
+ || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
+ || BOOST_WORKAROUND(__IBMCPP__, <= 700) \
+ || BOOST_WORKAROUND(__GNUC__, <= 2) \
+ || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \
+ )
+
+# define BOOST_MPL_CFG_NO_HAS_TEMPLATE_XXX
+
+#endif // BOOST_MPL_CFG_NO_HAS_TEMPLATE_XXX
+
+#endif // BOOST_MPL_AUX_CONFIG_HAS_TEMPLATE_XXX_HPP_INCLUDED
_______________________________________________
Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost