Boost logo

Boost :

Subject: Re: [boost] [mpl] is there a or_seq like logical metafunction?
From: Larry Evans (cppljevans_at_[hidden])
Date: 2009-02-15 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 time-rule from:
#
#
http://beta.boost.org/doc/tools/jam/jam/language.html#jam.language.variables.builtins.actionrule
#
rule timing-rule ( 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_while-time = timing-rule ;
compile and_seq_while.cpp
   : <include>.
     <link>static
   : and_seq_while-time
   ;


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