Boost logo

Boost :

From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2008-03-12 18:05:27


Max Motovilov wrote:
>>> I am not sure if this approach can be generalized to an arbitrary number
>>> of sequences. Perhaps it can be, by making the whole thing a recursive
>>> template instead of 3 separate ones. I'd try it just to see which
>>> version results in simpler code (gut feeling: the recursive template)
>>> and in faster compilation times (gut feeling: my current implementation)
>>> but customers and management are jointly snapping at my heels...
>>>
>
> Against my better instincts I got drawn into this exercise... and I am
> now officially stumped. Since we have this thread, perhaps one of the
> MPL gurus would chime in. Here's the [entire!] code that uses the
> accumulator idiom:
>
> ===================================================================
>
> template< typename S, typename A> struct product_view_ex :
> public if_<
> typename empty<S>::type,
> typename push_front< S, A >::type,
> transform_view<
> typename front<S>::type,
> product_view_ex<
> typename pop_front<S>::type,
> push_front<A,_1>
> >
> >
> >::type
> {
> typedef product_view_ex type;
> };
>
> template< typename S> struct product_view :
> public if_<
> typename empty<S>::type,
> S,
> product_view_ex<
> S,
> typename clear<S>::type
> >
> >::type
> {
> typedef product_view type;
> };
>
> ===================================================================
>
> The problem is that "if_< typename empty<S>::type ...." appears to
> always evaluate its "else" clause. Or, in other words [I think]
> empty<S>::type never evaluates as false_, even when the type of S is
> clearly an empty sequence (vector0<>) according to compiler messages. I
> am definitely missing something, but what?
>

The problem is that even when the sequence is empty, the
pop_front<S>::type will
still be evaluated. The if_ is working correctly, it's just that the
compiler doesn't
"know" about mpl::if_ and has to work out the template arguments even if
they are not used.

The following is still not quite right but it's closer.

#include <boost/mpl/if.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/transform_view.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/clear.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/copy.hpp>

using namespace boost::mpl;
namespace mpl = boost::mpl;

template< typename S, typename A>
struct product_view_ex;

template< typename S, typename A>
struct product_view_ex_impl :
    public
        transform_view<
            typename front<S>::type,
            product_view_ex<
                typename pop_front<S>::type,
                 push_front<A,_1>
>
>
{
};

template< typename S, typename A>
struct product_view_ex :
    public eval_if<empty<S>,
        push_front< S, A >,
        product_view_ex_impl<S, A>
>
{
};

template< typename S>
struct product_view :
    public if_<
        typename empty<S>::type,
        S,
        product_view_ex<
            S,
            typename clear<S>::type
>
>::type
{
    typedef product_view type;
};

template<class T>
struct print {};

int main() {
    typedef product_view<mpl::vector<mpl::range_c<int, 0, 2>,
mpl::range_c<int, 3, 5> > > view;
    typedef print<mpl::fold<view, vector0<>, mpl::copy<_2,
mpl::back_inserter<_1> > >::type>::type type;
}

In Christ,
Steven Watanabe


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