Section 5.13.  Exercises
Team LiB
Previous Section Next Section

5.13. Exercises

5-0.

Write a test program that exercises the parts of tiny we've implemented. Try to arrange your program so that it will only compile if the tests succeed.

5-1.

Write a metafunction double_first_half that takes a Random Access Sequence of integral constant wrappers of length N as an argument, and returns a copy with the first N/2 elements doubled in value, such that the following is true:



   mpl::equal<


       double_first_half< mpl::vector_c<int,1,2,3,4> >::type


     , mpl::vector_c<int,2,4,3,4>


   >::type::value

5-2.

Note that push_back won't compile if its tiny argument already has three elements. How can we get the same guarantees for push_front?

5-3.

Drawing on the example of our push_back implementation, implement insert for tiny sequences. Refactor the implementation of push_back so that it shares more code with insert.

5-4.

How could we reduce the number of template instantiations required by our implementation of push_back? (Hint: Look at our implementation of end in section 5.11.5 again.) How does that interact with the refactoring in the previous exercise?

5-5.

Implement the pop_front, pop_back, and erase algorithms for tiny.

5-6.

Write a sequence adapter template called dimensions that, when instantiated on an array type, presents the array's dimensions as a forward, non-extensible sequence:



    typedef dimensions<char [10][5][2]> seq;


    BOOST_STATIC_ASSERT( mpl::size<seq>::value == 3 );


    BOOST_STATIC_ASSERT(( mpl::at_c<seq,0>::type::value == 2 ));


    BOOST_STATIC_ASSERT(( mpl::at_c<seq,1>::type::value == 5 ));


    BOOST_STATIC_ASSERT(( mpl::at_c<seq,2>::type::value == 10 ));



Consider using the type traits library facilities to simplify the implementation.

5-7.

Modify the dimensions sequence adapter from exercise 5-6 to provide bidirectional iterators and push_back and pop_back operations.

5-8.

Write a fibonacci_series class that represents an infinite forward sequence of Fibonacci numbers:



   typedef mpl::lower_bound< fibonacci_series, int_<10> >::type n;


   BOOST_STATIC_ASSERT( n::value == 8 );





   typedef mpl::lower_bound< fibonacci_series, int_<50> >::type m;


   BOOST_STATIC_ASSERT( m::value == 34 );



Each element of the Fibonacci series is the sum of the previous two elements. The series begins 0, 1, 1, 2, 3, 5, 8, 13....

5-9.

Modify the fibonacci_series sequence from exercise 5-8 to be limited by a maximum number of elements in the series. Make the sequence's iterators bidirectional:



   typedef fibonacci_series<8> seq;


   BOOST_STATIC_ASSERT( mpl::size<seq>::value == 8 );


   BOOST_STATIC_ASSERT( mpl::back<seq>::type::value == 21 );

5-10*.

Write a tree class template for composing compile-time binary tree data structures:



   typedef tree<                  //     double


         double                   //     /   \


       , tree<void*,int,long>     //   void* char


       , char                     //   /  \


       > tree_seq;                // int  long



Implement iterators for pre-order, in-order, and post-order traversal of the tree elements:



   BOOST_STATIC_ASSERT(( mpl::equal<


         preorder_view<tree_seq>


       , mpl::vector<double,void*,int,long,char>


       , boost::is_same<_1,_2>


       >::value ));





   BOOST_STATIC_ASSERT(( mpl::equal<


         inorder_view<tree_seq>


       , mpl::vector<int,void*,long,double,char>


       , boost::is_same<_1,_2>


       >::value ));





   BOOST_STATIC_ASSERT(( mpl::equal<


         postorder_view<tree_seq>


       , mpl::vector<int,long,void*,char,double>


       , boost::is_same<_1,_2>


       >::value ));



Important

Extend the tests from exercise 5-0 to cover the algorithms you implemented in exercises 5-3, 5-4, and 5-5.


    Team LiB
    Previous Section Next Section