
----- Original Message ----- From: "David Abrahams" <dave@boostpro.com> To: <boost@lists.boost.org> 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