
Boost : 
Subject: Re: [boost] [mpl] is there a or_seq like logical metafunction?
From: Larry Evans (cppljevans_at_[hidden])
Date: 20090215 15:48:20
On 02/15/09 13:29, Steven Watanabe wrote:
> AMDG
>
> Larry Evans wrote:
>>> This "optimization" was ineffective. There were
>>> 303 instantiations vs. the 297 in the original
>>> version :( .
>>
>> Changing equal to is_same (and making adjustments to where
>> ::type is placed) resulted in just 185 instantiations!
>
> If you really must optimize this to death...
Well, the mpl and fusion people have spent
a lot of effort on it; so, I figure it must
be worth while.
>
> #include <boost/mpl/next.hpp>
> #include <boost/mpl/deref.hpp>
> #include <boost/mpl/begin.hpp>
> #include <boost/mpl/end.hpp>
> #include <boost/mpl/and.hpp>
> /* Calculate the mpl::and_ of a sequence of nullary logical
> metafunctions.*/
> template<class Begin, class End>
> struct and_iter : boost::mpl::and_<
> typename boost::mpl::deref<Begin>::type,
> and_iter<typename boost::mpl::next<Begin>::type, End>
> > {};
>
> template<class End>
> struct and_iter<End, End> : boost::mpl::false_ {};
>
> template <typename Seq>
> struct and_seq : and_iter<typename boost::mpl::begin<Seq>::type,
> typename boost::mpl::end<Seq>::type> {};
>
So, in summary, the and_ifops::if_ test has been replaced
with the and_iter specialization of <End, End>, and
the laziness is achieved by use of and_; however,
why not just use eval_if to achieve the laziness:
{and_seq_eval_if_iter.cpp
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/eval_if.hpp>
/* Calculate the mpl::and_ of a sequence of nullary logical
metafunctions.*/
template<class Begin, class End>
struct and_iter : boost::mpl::eval_if_<
typename boost::mpl::deref<Begin>::type,
and_iter<typename boost::mpl::next<Begin>::type, End>,
boost::mpl::false_
> {};
template<class End>
struct and_iter<End, End> : boost::mpl::false_ {};
template <typename Seq>
struct and_seq : and_iter<typename boost::mpl::begin<Seq>::type,
typename boost::mpl::end<Seq>::type> {};
#include <and_seq_instances.hpp>
{end_seq_eval_if_iter.cpp
This shaved off a few instantiations (128 vs. 163 on my machine).
BTW, Steven, do you know how to get timing? I've tried the following
but nothing is output:
#the following modelled after timerule from:
#
#
http://beta.boost.org/doc/tools/jam/jam/language.html#jam.language.variables.builtins.actionrule
#
rule timingrule ( args * : target : start end user system )
{
echo $(start) $(end) ;
}
#the following modelling on:
#
#
http://www.boost.org/doc/tools/jam/jam/language.html#jam.language.variables
#
__TIMING_RULE__ on and_seq_whiletime = timingrule ;
compile and_seq_while.cpp
: <include>.
<link>static
: and_seq_whiletime
;
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk