C++ Template Metaprogramming
Solutions to the exercises throughout the book
Loading...
Searching...
No Matches
exercise-5-1.hpp
Go to the documentation of this file.
1// ===-- chapter-5/exercise-5-1.hpp ----------------------- -*- C++ -*- --=== //
9#ifndef EXERCISE_5_1
10#define EXERCISE_5_1
11
12#include <boost/static_assert.hpp>
13
14#include <boost/mpl/begin_end.hpp>
15#include <boost/mpl/deref.hpp>
16#include <boost/mpl/equal.hpp>
17#include <boost/mpl/greater_equal.hpp>
18#include <boost/mpl/push_back.hpp>
19#include <boost/mpl/times.hpp>
20#include <boost/mpl/vector_c.hpp>
21
22
43namespace exercise_5_1 {
44
56template <typename S, typename Res, typename Cur>
58{
59 // Better to break up the algorithm a bit and make things clearer...
60
62 typedef boost::mpl::distance<typename boost::mpl::begin<S>::type, Cur>
64
66 typedef boost::mpl::distance<Cur, typename boost::mpl::end<S>::type>
68
70 typedef
71 boost::mpl::eval_if<
72 boost::mpl::greater_equal<dist_to_begin, dist_to_end>,
73 boost::mpl::deref<Cur>,
74 boost::mpl::times<
75 typename boost::mpl::deref<Cur>::type,
76 boost::mpl::int_<2>
77 >
79
80public:
82 typedef
83 typename
84 boost::mpl::eval_if<
85 boost::is_same<Cur, typename boost::mpl::end<S>::type>,
86 Res,
88 S,
89 typename boost::mpl::push_back<
90 Res,
91 typename multiply_or_not::type
92 >::type,
93 typename boost::mpl::next<Cur>::type
94 >
96};
97
106// Interesting note: double_first_half results in the following (with
107// boost::mpl::vector_c<int, 1, 2, 3, 4> as input):
108//
109// boost::mpl::v_item<
110// mpl_::integral_c<int, 4>,
111// boost::mpl::v_item<
112// mpl_::integral_c<int, 3>,
113// boost::mpl::v_item<
114// mpl_::integral_c<int, 4>,
115// boost::mpl::v_item<
116// mpl_::integral_c<int, 2>,
117// boost::mpl::vector_c<int>,
118// 0>,
119// 0>,
120// 0>,
121// 0>
122// This is boost::mpl::equal to boost::mpl::vector_c<int, 2, 4, 3, 4>
123template <typename S>
126 S, boost::mpl::vector_c<int>, typename boost::mpl::begin<S>::type>
127{ };
128
129} // namespace exercise_5_1
130
131#endif
Represents a single iteration across the sequence.
boost::mpl::eval_if< boost::is_same< Cur, typenameboost::mpl::end< S >::type >, Res, double_first_half_impl< S, typenameboost::mpl::push_back< Res, typenamemultiply_or_not::type >::type, typenameboost::mpl::next< Cur >::type > >::type type
Produce a result and keep iterating until we reach the end.
boost::mpl::eval_if< boost::mpl::greater_equal< dist_to_begin, dist_to_end >, boost::mpl::deref< Cur >, boost::mpl::times< typename boost::mpl::deref< Cur >::type, boost::mpl::int_< 2 > > > multiply_or_not
Lazily decide what operation to use if we're past the midpoint.
boost::mpl::distance< typename boost::mpl::begin< S >::type, Cur > dist_to_begin
The distance from the beginning of the sequence to where we are.
boost::mpl::distance< Cur, typename boost::mpl::end< S >::type > dist_to_end
The distance from the end of the sequence to where we are.
Encapsulate solution for Exercise 5-1.
Double the values in the first half of the given sequence.