[Home]CPPTM Answers - Exercise 5-9

BOOST WIKI | RecentChanges | Preferences | Page List | Links List

No diff available--this is the first major revision. (no other diffs)
See errata for correction to exercise

 // (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;
 }

BOOST WIKI | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited March 28, 2005 7:35 am (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers