
On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
Hello all (and especially Boost.Parameter's authors),
The Boost.Parameter docs suggest to implement parameter-enabled class templates using a series of typedes for the argument pack and the actual argument types. I think it is best to define extra template parameters with default values to old the argument pack Args and named template parameters ClassType, etc as shown below. This allows to use the named template parameters within the class declaration for example in a base class (boost::python::class_<ClassType, ...>) instead that just in the class definition.
Do you see any problem in using extra template parameter to define the argument pack and named template parameters?
I *think* I know what you're asking, and I *think* it's fine, but I basically didn't even try parsing the code below due to formatting :/
#include <boost/parameter.hpp>#include <boost/python/class.hpp>#include <boost/type_traits/is_class.hpp>#include <boost/type_traits/is_base_and_derived.hpp>#include <boost/mpl/is_sequence.hpp>#include <boost/mpl/placeholders.hpp>#include <boost/mpl/not.hpp>#include <boost/mpl/and.hpp>#include <boost/noncopyable.hpp>#include <boost/shared_ptr.hpp> namespace py { namespace detail { struct bases_tag {}; } template< class B0 = void, class B1 = void, class B2 = void >struct bases : detail::bases_tag {}; BOOST_PARAMETER_TEMPLATE_KEYWORD(ClassType)
BOOST_PARAMETER_TEMPLATE_KEYWORD(BaseList)BOOST_PARAMETER_TEMPLATE_KEYWORD(HeldType)BOOST_PARAMETER_TEMPLATE_KEYWORD(Copyable) template< typename Arg123X0 , typename Arg123X1 = boost::parameter::void_ , typename Arg123X2 = boost::parameter::void_ , typename Arg123X3 = boost::parameter::void_ , typename Args123 = typename boost::parameter::parameters< // IF(IS_EMPTY(DEFAULT(p)), required, optional) boost::parameter::required< tag::ClassType , boost::is_class<boost::mpl::_> > , boost::parameter::optional< // IF(IS_DEDUCED(p), deduced<tag::NAME(p)>, tag::NAME(p)) boost::parameter::deduced<tag::BaseList> // COMMA_IF(COMPL(IS_EMPTY(REQUIRES(p)))) REQUIRES(p) , boost::is_base_and_derived<detail::bases_tag, boost::mpl::_>
, boost::parameter::optional<
::bind<Arg123X0, Arg123X1, Arg123X2, Arg123X3>::type , typename ClassType = typename boost::parameter::value_type< Args123, tag::ClassType >::type , typename BaseList = typename boost::parameter::value_type< // ... COMMA_IF(COMPL(IS_EMPTY(DEFAULT(p)))) DEFAULT(p) >::type Args123, tag::BaseList, bases<> >::type , typename HeldType = typename boost::parameter::value_type< Args123, tag::HeldType, ClassType >::type , typename Copyable = typename boost::parameter::value_type< Args123, tag::Copyable, void ::type>struct class_ : boost::python::class_<ClassType, BaseList, HeldType, Copyable>{ typedef ClassType class_type; typedef BaseList base_list; typedef HeldType held_type; typedef Copyable copyable;}; } // namespace py struct b { virtual ~b() = 0; }; struct d : b { ~d() {} }; // Named parameters.typedef py::class_< py::ClassType<b>,
boost::parameter::deduced<tag::HeldType> , boost::mpl::not_< boost::mpl::or_< boost::is_base_and_derived<detail::bases_tag, boost::mpl::_> , boost::is_same<boost::noncopyable, boost::mpl::_> > > > , boost::parameter::optional< boost::parameter::deduced<tag::Copyable> , boost::is_same<boost::noncopyable, boost::mpl::_> > py::Copyable<boost::noncopyable> > x1;typedef py::class_< d, py::HeldType< boost::shared_ptr<d> >, py::BaseList< py::bases<b> > > x2;// Deduced parameters.typedef py::class_< b, boost::noncopyable > y1;typedef py::class_< d, boost::shared_ptr<d>, py::bases<b> > y2; A couple more things: 1) I thing that BOOST_PARAMETER_TEMPLATE_KEYWORD(ClassType) macro should define a symbol _ClassType to be used for the named parameter so to be consistent with the BOOST_PARAMETER_NAME(x) which defined _x to be used for the named function parameter. However, ClassType is defined without the leading _. What is the reason for this asymmetry?
The fact that each keyword is used in different contexts is enough justification for me to explain the asymmetry. I gathered the leading underscored prepended to function parameter keywords was motivated by a desire to prevent shadowing bugs (as per the rationale given in the documentation, if I remember correctly). No such problem arises with template parameter keywords, so the only justification I can think of to prepend template parameter keywords with an underscore is because that's what's done with function parameter keywords, which seems kind of weak. 2) I'd expect a macro that allows to specify tag and passing argument
name for template parameters BOOST_PARAMETER_TEMPLATE_KEYWORD((PassClassType, mytag) ClassType) as for BOOST_PARAMETER_NAME((pass_x, mytag) x) does for function parameters. Why is such a usage of BOOST_PARAMETER_TEMPLATE_KEYWORD not supported?
Not sure; really, I'm not familiar enough with the specifics of the above macros to be sure that I'm not sure, though :/ - Jeff