Boost logo

Boost Users :

Subject: Re: [Boost-users] [fusion] problems with accumulate metafunction
From: Christopher Schmidt (mr.chr.schmidt_at_[hidden])
Date: 2010-02-10 10:07:16


Benedetto Proietti schrieb:
> Greetings.
>
> I am kind of newbie to Boost.Fusion.
>
> I have a sequence of "Field"s:
>
> typedef fusion::vector<
> Field<int, 3, Check1, ..>,
> Field<float, 8, Check2, ..>,
> Field<MyString, 2, Check3, ..>,
> ...
>> MySequence;
>
> Each "Field" knows how to (de)serialize, has some checking policy and a
> few more little stuff.
> "Field" also has a "int" property "TypeSize":
>
> static const int TypeSize = somevalue_known_at_compile_time;
>
>
> I'd like to traverse the type "MySequence" and get the sum of all the
> sizes at compile time.
> Like:
> Field<int,3,Check1>::TypeSize + Field<float, 8, Check2>::TypeSize +
> Field<MyString,2,Check3>::TypeSize + ... ;
>
> I tried playing with fusion::accumulate and mpl<int_> but couldn't do it.
> There's no much documentation/examples about fusion (correct me if I am
> wrong please).
> How can I get the accumulated sum of Field<...>::TypeSize of all the
> members in "MySequence"?
[snip]

An implementation based upon MPL's fold is easier than one based upon
Fusion's equivalent. That way you do not need to deal with ref-qualified
arguments.

#include <boost/fusion/mpl.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/placeholders.hpp>

template<int Size>
struct my_type
{
        typedef boost::mpl::int_<Size> size;
};

template<typename T>
struct get_size:T::size{};

typedef boost::fusion::vector<my_type<1>,my_type<2>,my_type<3> > vec;
typedef boost::mpl::fold<
        vec,
        boost::mpl::int_<0>,
        boost::mpl::plus<boost::mpl::_1, get_size<boost::mpl::_2> >
>::type sum;

char is_correct[sum::value - 6 ? 0 : 1];

A fusion-only implementation probably looks like this:

#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/type_traits/remove_reference.hpp>

template<int Size>
struct my_type
{
        typedef boost::mpl::int_<Size> size;
};

struct accumulator
{
        template<typename Sig>
        struct result;

        template<typename Self, typename State, typename T>
        struct result<Self(State, T)>:
                boost::mpl::plus<
                        typename boost::remove_reference<State>::type,
                        typename boost::remove_reference<T>::type::size
>
        {};

        template<typename State, typename T>
        typename result<accumulator const&(State,T)>::type
        operator()(State,T)const;
};

typedef boost::fusion::vector<my_type<1>,my_type<2>,my_type<3> > vec;
typedef boost::fusion::result_of::fold<
        vec,
        boost::mpl::int_<0>,
        accumulator
>::type sum;

char is_correct[sum::value - 6 ? 0 : 1];

Both snippets are untested!

-Christopher


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net