Reputation: 3
I have metafunction FibIter. It computes Fibonacci number that correspond to number(parameter Iter) in Fibbonacci sequence. Then I'm using mpl::transform to create mpl::vector with Fibonacci sequence from 0 to N. I have written code:
template <typename F1, typename F2, typename Iter>
struct FibIter :
mpl::if_
<
mpl::equal_to <Iter, mpl::int_ <0> >,
F1,
FibIter <F2, mpl::plus<F1, F2>, mpl::minus <Iter, mpl::int_ <1> > >
>::type
{ };
const int N = 22;
typedef mpl::range_c <int, 0, 22> Numbers;
typedef
mpl::transform
<
Numbers,
FibIter <mpl::int_ <0>, mpl::int_ <1>, mpl::_ >,
mpl::back_inserter
<
mpl::vector <>
>
>::type
FibSeq;
But, it's not good. Because every number in FibSeq computes again and again from 0. I want to create mpl::vector before FibIter and push_back numbers recursively, inside FibIter definition. How can I do it? Please, Help.
Upvotes: 0
Views: 78
Reputation: 51555
MPL and metaprogramming in general relies on recusion - you probably already know that. However transform
isn't suited for that. Pose your problem in recusion, eg.
// Untested!!!!
template<int N>
struct fib {
// guard against bad N value
BOOST_STATIC_ASSERT((N > 1));
// previous f(0:N-1) values
typedef typename fib<N-1>::vector previous;
// current value, f(N) = f(N-1) + f(N-2)
static const int value = (
mpl::at_c<previous, N-1>::type::value +
mpl::at_c<previous, N-2>::type::value
);
// append f(N) to F(0:N-1)
typedef typename mpl::push_back<previous, mpl::int_<value> >::type vector;
};
// corner case, N=0
template<>
struct fib<0> {
static const int value = 0;
typedef mpl::vector_c<int,0> vector;
};
// corner case, N=1
template<>
struct fib<1> {
static const int value = 1;
typedef mpl::vector_c<int,0,1> vector;
};
BOOST_STATIC_ASSERT(( mpl::back< typename fib<10>::vector >::type::value == 55 ));
Upvotes: 1