
On Thu, Nov 3, 2011 at 2:32 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Thu, Nov 3, 2011 at 11:05 AM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
On Wed, Nov 2, 2011 at 6:46 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
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 :/
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