Boost logo

Boost :

From: vicente.botet (vicente.botet_at_[hidden])
Date: 2008-07-18 04:58:23


----- Original Message -----
From: "David Abrahams" <dave_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Wednesday, July 16, 2008 4:57 AM
Subject: Re: [boost] [flyweight][parameter] is there an interest in
thistemplate parameter expresion

>> I'm doing a Locally Unique Identifier generator library. The DSL
>> grammar is quite complex, so the use of optional class parameters
>> seams unavoidable. I have started to use the Boost.Parameter Library
>> as the Boost.Flyweight does.
>
> I'm not familiar with Flyweight.

You don't have to.

>> The flyweight class that takes 5 optional parameters and is currently
>> declared as follows
>>
>> <code>
>> template<
>> typename T,
>> typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5
>> /**/>
>
> I think there must be defaults for these arguments, probably
> parameter::void_, yes?

Yes, there is a fwd file declaring it.

<snip>
>> BOOST_STATIC_ASSERT((
>
> Should use one of the MPL assertions, but anyway...

Correct, we use already mpl.

<snip>
>> I have made abstraction of the common structure of this code resulting
>> on a 'expr' class.
>> The boost::dsl::expr class has three parameters:
>> * a tag for the expression
>> * a vector of parameters specification, each one been either mandatory
>> or optional, and containing a tag, a predicate stating if a parameter
>> corresponds to the tag, and a default value for the optionals
>> * a vector of the current parameters
>>
>> The parameter associated to a given tag can be obtained using the get
>> template function. For example to get the tracking parameter we can
>> use:
>>
>> typename base_type::template get<tracking<> >::type
>>
>> All the implementation details are encapsulated on the expre class.
>>
>> The flyweight class can then be rewriten as:
>>
>> <code>
> <schnipp>
>> </code>
>>
>> BOOST_FLYWEIGHT_BASE is used to avoid repeating the long template
>> expression
>
> Rewriting so I can grok it...
>
> template <
> class T
> , class Arg1, class Arg2, class Arg3, class Arg4,class Arg5
>>
> struct flyweight_base
> {
> typedef dsl::expr<
> flyweight<T>
> , mpl::vector<
> dsl::optional<tag<>, detail::is_tag<mpl::_>, mpl::na >
> , dsl::optional<tracking<>, is_tracking<mpl::_>, refcounted >
> , dsl::optional<factory<>, is_factory<mpl::_>,
> hashed_factory<> >
> , dsl::optional<locking<>, is_locking<mpl::_>, simple_locking
> >,
> , dsl::optional<holder<>, is_holder<mpl::_>, static_holder >
> >
> , mpl::vector<Arg1,Arg2,Arg3,Arg4,Arg5>
> > type;
> };
>
>
> template<
> typename T,
> typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5
>>
> class flyweight : public flyweight_base<T,Arg1,Arg2,Arg3,Arg4,Arg5>::type
> {
> typedef flyweight_base<T,Arg1,Arg2,Arg3,Arg4,Arg5>::type base_type;
>
> typedef typename base_type::template get< tag<> >::type tag_type;
> typedef typename base_type::template get< tracking<> >::type
> tracking_policy;
> typedef typename base_type::template get< factory<> >::type
> factory_specifier;
> typedef typename base_type::template get< locking<> >::type
> locking_policy;
> typedef typename base_type::template get< holder<> >::type
> holder_specifier;
> // ...
> };

This is better.

> So, what benefit, exactly, is the framework providing (e.g. is it
> providing the equivalent of the static assertion in the original code?),

Well, the framework allows the user to express the mapping from the tags to
the current named parameter, with its type and default parameter in a more
declarative and condensed way, at least, this was my goal. The parameter
mapping provides a template get function to recover the current value
associated to a named patameter.
If there some parameters that do not match any of the parameters
specification an static assertion produce a compile error.

> and what is the purpose of using derivation above?

Very good point. It is now clear to me that the derivation is an overuse, so
we don't need any more the macro neither the flyweight_base.

template<
    typename T,
    typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5
>
class flyweight {
    typedef dsl::expr<
        flyweight<T>
      , mpl::vector<
            dsl::optional<tag<>, detail::is_tag<mpl::_>, mpl::na >
          , dsl::optional<tracking<>, is_tracking<mpl::_>, refcounted >
          , dsl::optional<factory<>, is_factory<mpl::_>, hashed_factory<>
>
          , dsl::optional<locking<>, is_locking<mpl::_>, simple_locking
>,
          , dsl::optional<holder<>, is_holder<mpl::_>, static_holder >
>
      , mpl::vector<Arg1,Arg2,Arg3,Arg4,Arg5>
> base_type;

    typedef typename base_type::template get< tag<> >::type tag_type;
    typedef typename base_type::template get< tracking<> >::type
tracking_policy;
    typedef typename base_type::template get< factory<> >::type
    factory_specifier;
    typedef typename base_type::template get< locking<> >::type
locking_policy;
    typedef typename base_type::template get< holder<> >::type
holder_specifier;
 // ...
 };

>> I would like to know if there is an interest in such a class, and if
>> it could be added to the parameters library?
>
> Anything that makes declaring parameter-enabled classes simpler would be
> a welcome addition. However, I'm not yet sure what this is doing ;-)

Simplify the use of named parameters. Well the name expr is not a good one.
It creates a mapping from the tags to the current values passed as named
template parameters checking for bad parameters. Maybe parameters_map is a
better name, any suggestion is wellcome.

Thanks for your comments,

Vicente


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