|
Boost : |
Subject: Re: [boost] [parameter] named template parameters
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-11-03 14:05:38
On Wed, Nov 2, 2011 at 6:46 PM, Jeffrey Lee Hellrung, Jr.
<jeffrey.hellrung_at_[hidden]> wrote:
> On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti_at_[hidden]>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 :/
OK, let me try again (I tested the formatting of the code below
sending an email to myself and it showed up fine):
#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 {};
/** @todo to be consistent w/ PARAM_NAME, these macros should generate
_ClassType, etc with leading _ be default and in tag namespace by
default */
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<
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::_>
>
>::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>, py::Copyable<boost::noncopyable> > x1;
/** @todo use std::auto_ptr instead of boost::shared_ptr */
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.
Yes but these all sound like implementation reasons to me. If the
parameter name keywords need the leading _ for functions, as a library
users I'd expect the template parameters to follow the same
convention. Why should a user expect template parameter name keywords
to follow a different convention than function parameter name
keywords?
> 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 :/
Thanks!
--Lorenzo
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk