[flyweight][parameter] is there an interest in this template parameter expresion

Hello, 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. 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
class flyweight { private: typedef parameter::parameters< parameter::optional< parameter::deduced<tag<> >, detail::is_tag<boost::mpl::_> >, parameter::optional< parameter::deduced<tracking<> >, is_tracking<boost::mpl::_> >, parameter::optional< parameter::deduced<factory<> >, is_factory<boost::mpl::_> >, parameter::optional< parameter::deduced<locking<> >, is_locking<boost::mpl::_> >, parameter::optional< parameter::deduced<holder<> >, is_holder<boost::mpl::_> >
signature;
typedef typename signature::bind< Arg1,Arg2,Arg3,Arg4,Arg5
::type args; typedef typename parameter::binding< args,tag<>,mpl::na ::type tag_type; typedef typename parameter::binding< args,tracking<>,refcounted ::type tracking_policy; typedef typename parameter::binding< args,factory<>,hashed_factory<> ::type factory_specifier; typedef typename parameter::binding< args,locking<>,simple_locking ::type locking_policy; typedef typename parameter::binding< args,holder<>,static_holder ::type holder_specifier;
typedef parameter::parameters< parameter::optional< parameter::deduced< detail::unmatched_arg >, mpl::not_< mpl::or_< detail::is_tag<boost::mpl::_>, is_tracking<boost::mpl::_>, is_factory<boost::mpl::_>, is_locking<boost::mpl::_>, is_holder<boost::mpl::_> > > >
unmatched_signature;
typedef typename unmatched_signature::bind< Arg1,Arg2,Arg3,Arg4,Arg5
::type unmatched_args; typedef typename parameter::binding< unmatched_args,detail::unmatched_arg, detail::unmatched_arg ::type unmatched_arg_detected; BOOST_STATIC_ASSERT(( /* You have passed a type in the specification of a flyweight type that * could not be interpreted as a valid argument. */ is_same<unmatched_arg_detected,detail::unmatched_arg>::value)); ... </code>
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> #define BOOST_FLYWEIGHT_BASE 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> > template< typename T, typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5
class flyweight : public BOOST_FLYWEIGHT_BASE { typedef BOOST_FLYWEIGHT_BASE base_type; #undef BOOST_FLYWEIGHT_BASE 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; // ... }; </code> BOOST_FLYWEIGHT_BASE is used to avoid repeating the long template expression I would like to know if there is an interest in such a class, and if it could be added to the parameters library? Of course, any improvements are welcome. The expr.hpp and expr_pp.hpp files are attached. The class is able to manage with a variable number of parameters (BOOST_DSL_EXPR_ARITY) when BOOST_DSL_EXPR_PP is defined or up to 3 otherwise. Best Regards Vicente Juan Botet Escriba P.S. The variadic template code is not correct.

Adding or_seq.hpp file. Vicente

on Mon Jul 14 2008, "vicente.botet" <vicente.botet-AT-wanadoo.fr> wrote:
Hello,
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.
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?
,
,
,
,
class flyweight { private: typedef parameter::parameters< parameter::optional< parameter::deduced<tag<> >, detail::is_tag<boost::mpl::_> parameter::optional< parameter::deduced<tracking<> >, is_tracking<boost::mpl::_> parameter::optional< parameter::deduced<factory<> >, is_factory<boost::mpl::_> parameter::optional< parameter::deduced<locking<> >, is_locking<boost::mpl::_> parameter::optional< parameter::deduced<holder<> >, is_holder<boost::mpl::_>
signature;
typedef typename signature::bind< Arg1,Arg2,Arg3,Arg4,Arg5
::type args; typedef typename parameter::binding< args,tag<>,mpl::na ::type tag_type; typedef typename parameter::binding< args,tracking<>,refcounted ::type tracking_policy; typedef typename parameter::binding< args,factory<>,hashed_factory<> ::type factory_specifier; typedef typename parameter::binding< args,locking<>,simple_locking ::type locking_policy; typedef typename parameter::binding< args,holder<>,static_holder ::type holder_specifier;
typedef parameter::parameters< parameter::optional< parameter::deduced< detail::unmatched_arg >, mpl::not_< mpl::or_< detail::is_tag<boost::mpl::_>, is_tracking<boost::mpl::_>, is_factory<boost::mpl::_>, is_locking<boost::mpl::_>, is_holder<boost::mpl::_> > >
unmatched_signature;
typedef typename unmatched_signature::bind< Arg1,Arg2,Arg3,Arg4,Arg5
::type unmatched_args; typedef typename parameter::binding< unmatched_args,detail::unmatched_arg, detail::unmatched_arg ::type unmatched_arg_detected; BOOST_STATIC_ASSERT((
Should use one of the MPL assertions, but anyway...
/* You have passed a type in the specification of a flyweight type that * could not be interpreted as a valid argument. */ is_same<unmatched_arg_detected,detail::unmatched_arg>::value)); ... </code>
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; // ... }; So, what benefit, exactly, is the framework providing (e.g. is it providing the equivalent of the static assertion in the original code?), and what is the purpose of using derivation above?
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 ;-) -- Dave Abrahams BoostPro Computing http://www.boostpro.com

----- 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

Robert Jones escribió:
On Wed, Jul 16, 2008 at 3:57 AM, David Abrahams <dave@boostpro.com> wrote:
I'm not familiar with Flyweight.
Nor am I, in fact I can find little mention of it all. Is there any documentation about it? Where can I find it?
Online docs: http://svn.boost.org/svn/boost/sandbox/flyweight/libs/flyweight/doc/index.ht... Tarball: http://www.boostpro.com/vault/index.php?direction=0&order=&directory=Patterns This lib was accepted at the beginning of the year, but it was subjected to heavy and constructive criticism by some reviewers: as a consequence, I plan to modify the design substantially before including it into Boost and cannot find the time to do it. I hope this summer will be the time. Best, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

on Mon Jul 14 2008, "vicente.botet" <vicente.botet-AT-wanadoo.fr> wrote:
The expr.hpp and expr_pp.hpp files are attached. The class is able to manage with a variable number of parameters (BOOST_DSL_EXPR_ARITY) when BOOST_DSL_EXPR_PP is defined or up to 3 otherwise. ... P.S. The variadic template code is not correct.
This code is much too complex for me to analyze. It would help a lot if you'd strip out any non-correct code, to start with. One thing I can say up front is that compilation times are a concern and any ease-of-use wrapper should avoid increasing them too much. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

----- Original Message ----- From: "David Abrahams" <dave@boostpro.com> To: <boost@lists.boost.org> Sent: Wednesday, July 16, 2008 4:59 AM Subject: Re: [boost] [flyweight][parameter] is there an interest in thistemplate parameter expresion
This code is much too complex for me to analyze. It would help a lot if you'd strip out any non-correct code, to start with.
One thing I can say up front is that compilation times are a concern and any ease-of-use wrapper should avoid increasing them too much.
Hi, I have attached the files striping any code not needed (and the flyweitht.hpp modified - need BOOST_USE_DSL_EXPR to be defined) You are right, the compilation time is important. I expect the transformations I'm doing can be improved, but my knowledge of the metaprogramming (mpl) is not too deep. I have done the test for the flyweight library (compiling 19 files) WITH BOOST_USE_DSL_EXPR real 1m3.184s user 0m0.015s sys 0m0.015s real 1m3.324s user 0m0.015s sys 0m0.031s WITHOUT BOOST_USE_DSL_EXPR real 0m48.828s user 0m0.046s sys 0m0.000s real 0m48.382s user 0m0.015s sys 0m0.031s The compilation takes more that 30% with this wrapper. Vicente
participants (4)
-
David Abrahams
-
joaquin@tid.es
-
Robert Jones
-
vicente.botet