C++ Template Metaprogramming
Solutions to the exercises throughout the book
Loading...
Searching...
No Matches
exercise-5-7.hpp
Go to the documentation of this file.
1// ===-- chapter-5/exercise-5-7.hpp ----------------------- -*- C++ -*- --=== //
9#ifndef EXERCISE_5_7
10#define EXERCISE_5_7
11
12#include "exercise-5-6.hpp"
13
14#include <boost/mpl/pop_back.hpp>
15#include <boost/mpl/push_back.hpp>
16
17
33namespace exercise_5_7 {
34
37
39template <typename S>
41{
42 typedef boost::mpl::bidirectional_iterator_tag category;
43};
44
53template <typename T, typename Next>
55 : boost::mpl::void_
56{
58
59 typedef boost::mpl::void_ next;
60 typedef boost::mpl::void_ prev;
61};
62
68template <typename T, size_t N, typename Next>
69struct dimensions_b_impl<T[N], Next>
70 : boost::mpl::int_<N>
71{
73
74 typedef Next next;
75 typedef typename
76 boost::mpl::if_<
77 boost::is_array<T>,
79 boost::mpl::void_
80 >::type prev;
81};
82
96template <typename T>
97struct dimensions_b : dimensions_b_impl<T, boost::mpl::void_> { };
98
109template <typename S, typename S_Prev>
111 : begin_impl_traversal<S_Prev, typename S_Prev::prev> { };
112
114template <typename S>
115struct begin_impl_traversal<S, boost::mpl::void_>
116{
117 typedef S type;
118};
119
120} // namespace exercise_5_7
121
122
123namespace boost {
124namespace mpl {
125
128
129// Implementation metaclasses:
130
132template<>
133struct begin_impl<exercise_5_7::dimensions_b_tag>
134{
135 template <typename S>
136 struct apply
137 {
140 S,
141 typename S::prev>::type
143 };
144};
145
147template<>
148struct end_impl<exercise_5_7::dimensions_b_tag>
149{
150 template <typename S>
151 struct apply
152 {
154 };
155};
156
158template<>
159struct pop_back_impl<exercise_5_7::dimensions_b_tag>
160{
161 template <typename S> struct apply;
162
163 template <typename T, size_t N>
164 struct apply< exercise_5_7::dimensions_b<T[N]> >
165 {
167 };
168};
169
171template<>
172struct push_back_impl<exercise_5_7::dimensions_b_tag>
173{
174 template <typename S, size_t N>
175 struct apply_num { };
176
177 // We only work with dimensions_b types...
178 template <typename T, size_t N>
179 struct apply_num< exercise_5_7::dimensions_b<T>, N>
180 {
182 };
183
185 template <typename S, typename Elem>
186 struct apply : apply_num<S, Elem::value> { };
187};
188
189// Metafunction specializations
190
192template <typename S>
193struct deref< exercise_5_7::dimensions_b_iterator<S> > : S { };
194
196template <typename S>
197struct next< exercise_5_7::dimensions_b_iterator<S> >
198{
200};
201
203template <typename S>
204struct prior< exercise_5_7::dimensions_b_iterator<S> >
205{
207};
208
210
211} // namespace mpl
212} // namespace boost
213
214#endif // EXERCISE_5_7
Solution to Exercise 5-6.
Exists to inject functionality into the Boost MPL namespace.
Exists to inject functionality into the Boost namespace.
Encapsulate solution for Exercise 5-7.
exercise_5_7::dimensions_b_iterator< typename exercise_5_7::begin_impl_traversal< S, typename S::prev >::type > type
exercise_5_7::dimensions_b_iterator< boost::mpl::void_ > type
exercise_5_7::dimensions_b_iterator< typename S::next > type
exercise_5_7::dimensions_b_iterator< typename S::prev > type
begin_impl_traversal walks the list to find the beginning
boost::mpl::if_< boost::is_array< T >, dimensions_b_impl< T, dimensions_b_impl< T[N], Next > >, boost::mpl::void_ >::type prev
Implement the dimensions_b sequence.
Define a bi-directional iterator for our dimensions_b sequence.
boost::mpl::bidirectional_iterator_tag category
A tag for tag-dispatched sequence metafunctions.
Represent the dimensions in an array type as a sequence of numbers.