// (by Ariel Badichi) #include <boost/static_assert.hpp> #include <boost/mpl/begin.hpp> #include <boost/mpl/end.hpp> #include <boost/mpl/deref.hpp> #include <boost/mpl/next.hpp> #include <boost/mpl/prior.hpp> #include <boost/mpl/iterator_tags.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/size.hpp> #include <boost/mpl/back.hpp>
namespace mpl = boost::mpl;
template<int N> struct fibonacci_gen;
template<> struct fibonacci_gen<1> : mpl::int_<1> {};
template<> struct fibonacci_gen<0> : mpl::int_<0> {};
template<int N> struct fibonacci_gen : mpl::plus< typename fibonacci_gen<N - 1>::type, typename fibonacci_gen<N - 2>::type > { };
struct fibonacci_series_tag {};
template<typename N> struct fibonacci_series_iterator { typedef mpl::bidirectional_iterator_tag category; typedef fibonacci_series_iterator<typename mpl::next<N>::type> next; typedef fibonacci_series_iterator<typename mpl::prior<N>::type> prior; };
template<int Size> struct fibonacci_series { typedef fibonacci_series_tag tag; typedef mpl::int_<Size> size; };
namespace boost { namespace mpl { template<> struct begin_impl<fibonacci_series_tag> { template<typename Sequence> struct apply { typedef fibonacci_series_iterator<mpl::int_<0> > type; }; };
template<> struct end_impl<fibonacci_series_tag> { template<typename Sequence> struct apply { typedef fibonacci_series_iterator< typename Sequence::size > type; }; };
template<typename N> struct deref<fibonacci_series_iterator<N> > : fibonacci_gen<N::value> {};
template<> struct size_impl<fibonacci_series_tag> { template<typename Sequence> struct apply : Sequence::size {}; }; } }
int main() { typedef fibonacci_series<8> seq; BOOST_STATIC_ASSERT(mpl::size<seq>::value == 8); // The result in the exercise is incorrect. BOOST_STATIC_ASSERT(mpl::back<seq>::type::value == 13); return 0; }