Boost logo

Boost :

Subject: Re: [boost] [parameter] named template parameters
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-11-03 14:53:30


On Thu, Nov 3, 2011 at 2:32 PM, Jeffrey Lee Hellrung, Jr.
<jeffrey.hellrung_at_[hidden]> wrote:
> On Thu, Nov 3, 2011 at 11:05 AM, Lorenzo Caminiti <lorcaminiti_at_[hidden]>wrote:
>
>> 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):
>>
> [...]
>
>> 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>
>>
> [...]
>
> This is what I figured you had in mind, and I don't see a problem with it
> technically.  This isn't something I'd encourage for typical use cases,
> though, as I'd imagine it would make compiler error messages even more
> unwieldy :)

I have to decide how Boost.Contract macros are going to expand to
support named template parameters. In Boost.Parameter you have to
program the code above by hand so you can chose to use extra template
parameters (as shown above) or typedefs (as shown in the
Boost.Parameter docs) to declare the named parameters ClassType, etc.
However, when I make the CONTRACT_CLASS macro expand the
Boost.Parameter code then I have to chose one of the approach and
stick with it. I'd chose the approach above (extra template params)
because it supports using the named template parameters within the
class declarations (e.g., base classes) as usual for template
parameters unless there is some major drawn back.

Also, for symmetry with named function parameters, I will provide
Boost.Contract macros that define the template parameter keyword
prefixing them with _ by default (_ClassType) and allowing to
optionally specify the passing template parameter name (PassClassType)
and tag namespace (exactly like the BOOST_PARAMETER_NAME does for
named function params) unless there's a real reason for not supporting
such symmetry (symmetry that I'd expect in principle as a user).

P.S. Boost.Contract named parameters will also strictly enforce that a
"in" parameter is passed by const (reference), while "out" and "in
out" params are passed by non-const (reference).

Thanks.
--Lorenzo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk