|
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