Casey
Casey

Reputation: 3

Using mpl::vector inside metafunction definition

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

Answers (1)

Anycorn
Anycorn

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

Related Questions