C++ Template Metaprogramming
Solutions to the exercises throughout the book
Loading...
Searching...
No Matches
chapter-5.cpp
Go to the documentation of this file.
1// ===-- chapter-5/chapter-5.cpp -------------------------- -*- C++ -*- --=== //
9#include "chapter-5-tiny.hpp"
10#include "exercise-5-1.hpp"
11#include "exercise-5-6.hpp"
12#include "exercise-5-7.hpp"
13#include "exercise-5-8.hpp"
14#include "exercise-5-9.hpp"
15#include "exercise-5-10.hpp"
16
17#include <boost/mpl/vector.hpp>
18using namespace boost::mpl::placeholders;
19
20#include <stdio.h>
21
22#define PARANOID_DEBUG_TEST
23
24
40namespace test_5_1 {
41using namespace exercise_5_1;
42
43typedef boost::mpl::vector_c<int, 1, 2, 3, 4> testVec;
44
46BOOST_STATIC_ASSERT((boost::mpl::equal<
48 boost::mpl::vector_c<int, 2, 4, 3, 4> >::value));
49
50} // namespace test_5_1
51
52
55namespace test_5_8 {
56using namespace exercise_5_8;
57
58typedef boost::mpl::advance_c<
59 boost::mpl::begin<exercise_5_8::fibonacci_series>::type,
60 6>::type i;
61BOOST_STATIC_ASSERT(boost::mpl::deref<i>::type::value == 8);
62
63typedef boost::mpl::advance_c<i, 4>::type j;
64BOOST_STATIC_ASSERT(boost::mpl::deref<j>::type::value == 55);
65
66} // namespace test_5_8
67
68
71namespace test_5_10 {
72using namespace exercise_5_10;
73
85typedef chapter5::tree<
86 double,
88 char
90
104typedef chapter5::tree<
105 double,
107 short,
108 long,
110 >,
112 int,
113 void_,
114 char>
116
117#ifdef PARANOID_DEBUG_TEST
118typedef boost::mpl::begin< inorder_view<tree_seq_hard> >::type tmp1;
119typedef boost::mpl::deref<tmp1>::type tmp1d;
120BOOST_STATIC_ASSERT((boost::is_same<long, tmp1d>::value));
121
122typedef boost::mpl::next<tmp1>::type tmp2;
123typedef boost::mpl::deref<tmp2>::type tmp2d;
124BOOST_STATIC_ASSERT((boost::is_same<short, tmp2d>::value));
125
126typedef boost::mpl::next<tmp2>::type tmp3;
127typedef boost::mpl::deref<tmp3>::type tmp3d;
128BOOST_STATIC_ASSERT((boost::is_same<void*, tmp3d>::value));
129
130typedef boost::mpl::next<tmp3>::type tmp4;
131typedef boost::mpl::deref<tmp4>::type tmp4d;
132BOOST_STATIC_ASSERT((boost::is_same<float, tmp4d>::value));
133
134typedef boost::mpl::next<tmp4>::type tmp5;
135typedef boost::mpl::deref<tmp5>::type tmp5d;
136BOOST_STATIC_ASSERT((boost::is_same<double, tmp5d>::value));
137
138typedef boost::mpl::next<tmp5>::type tmp6;
139typedef boost::mpl::deref<tmp6>::type tmp6d;
140BOOST_STATIC_ASSERT((boost::is_same<int, tmp6d>::value));
141
142typedef boost::mpl::next<tmp6>::type tmp7;
143typedef boost::mpl::deref<tmp7>::type tmp7d;
144BOOST_STATIC_ASSERT((boost::is_same<char, tmp7d>::value));
145
146typedef boost::mpl::next<tmp7>::type tmp8;
147typedef boost::mpl::end< inorder_view<tree_seq_hard> >::type tmp_end;
148BOOST_STATIC_ASSERT((boost::is_same<tmp_end, tmp8>::value));
149#endif // PARANOID_DEBUG_TEST
150
152 boost::mpl::equal<
154 boost::mpl::vector<int, void*, long, double, char>,
155 boost::is_same<_1, _2>
156 >::value));
157
159 boost::mpl::equal<
161 boost::mpl::vector<long, short, void*, float, double, int, char>,
162 boost::is_same<_1, _2>
163 >::value));
164
165} // namespace test_5_10
166
167
168namespace {
169
184static void test_exercise_5_0()
185{
186#ifdef CHAPTER_5_TINY
187 using namespace chapter5;
188
189 typedef tiny<int, char, float> v1;
190 boost::mpl::deref< boost::mpl::begin<v1>::type >::type const i1 = 5;
191 boost::mpl::at< v1, boost::mpl::int_<1> >::type const c1 = 'a';
192 boost::mpl::deref<
193 boost::mpl::prior< boost::mpl::end<v1>::type >::type
194 >::type const f1 = 2.5;
195
196 printf("i1: (%lu,%i); c1: (%lu,%c); f1: (%lu,%f)\n",
197 sizeof(i1), i1,
198 sizeof(c1), c1,
199 sizeof(f1), f1);
200
201 typedef boost::mpl::clear<v1>::type v2;
202 BOOST_STATIC_ASSERT((boost::is_same<v2::t0, none>::value));
203 BOOST_STATIC_ASSERT((boost::is_same<v2::t1, none>::value));
204 BOOST_STATIC_ASSERT((boost::is_same<v2::t2, none>::value));
205
206 typedef boost::mpl::push_front<v2, double>::type v3;
207 typedef boost::mpl::push_back<v3, int>::type v4;
208
209 BOOST_STATIC_ASSERT((boost::mpl::equal< v4, tiny<double,int> >::value));
210#endif
211}
212
215static void test_exercise_5_3()
216{
217#ifdef CHAPTER_5_TINY
218 using namespace chapter5;
219
220 typedef tiny<int> v1;
221 BOOST_STATIC_ASSERT((boost::is_same<v1::t0, int>::value));
222 BOOST_STATIC_ASSERT((boost::is_same<v1::t1, none>::value));
223 BOOST_STATIC_ASSERT((boost::is_same<v1::t2, none>::value));
224 BOOST_STATIC_ASSERT((boost::is_same<tiny<int>, v1>::value));
225
226 typedef boost::mpl::insert<v1, boost::mpl::begin<v1>::type, float>::type v2;
227 BOOST_STATIC_ASSERT((boost::is_same<tiny<float, int>, v2>::value));
228
229 typedef boost::mpl::insert<v2, boost::mpl::end<v2>::type, char>::type v3;
230 BOOST_STATIC_ASSERT((boost::is_same<tiny<float, int, char>, v3>::value));
231
232 // Should be an error:
233 // typedef boost::mpl::insert<v2, boost::mpl::end<v3>::type, char>::type v4;
234#endif
235}
236
239static void test_exercise_5_5()
240{
241#ifdef CHAPTER_5_TINY
242 using namespace boost;
243 using namespace boost::mpl;
244 using namespace chapter5;
245
246 typedef tiny<int, float, char> v1;
247 typedef begin<v1>::type pos0;
248 typedef next<pos0>::type pos1;
249 typedef next<pos1>::type pos2;
250 typedef end<v1>::type posEnd;
251
253 is_same< erase<v1, pos0>::type, tiny<float, char> >::value));
255 is_same< erase<v1, pos1>::type, tiny<int, char> >::value));
257 is_same< erase<v1, pos2>::type, tiny<int, float> >::value));
258
260 is_same< erase<v1, pos0, pos1>::type, tiny<float, char> >::value));
262 is_same< erase<v1, pos0, pos2>::type, tiny<char> >::value));
264 is_same< erase<v1, pos0, posEnd>::type, tiny<> >::value));
266 is_same< erase<v1, pos1, posEnd>::type, tiny<int> >::value));
268 is_same< erase<v1, pos2, posEnd>::type, tiny<int, float> >::value));
269
271 is_same< pop_front<v1>::type, tiny<float, char> >::value));
273 is_same< pop_back<v1>::type, tiny<int, float> >::value));
274#endif
275}
276
279static void test_exercise_5_6()
280{
281#ifdef EXERCISE_5_6
282 namespace mpl = boost::mpl;
283
285 printf("%lu entries: (%lu, %lu, %lu)\n",
286 mpl::size<seq>::value,
287 mpl::at_c<seq,0>::type::value,
288 mpl::at_c<seq,1>::type::value,
289 mpl::at_c<seq,2>::type::value);
290
291
292 // Note: I think the book's asserts are backwards. I've changed the
293 // requirement. See 5-7 for the list implemented as asked...
294 BOOST_STATIC_ASSERT((mpl::size<seq>::value == 3));
295 BOOST_STATIC_ASSERT((mpl::at_c<seq,0>::type::value == 10));
296 BOOST_STATIC_ASSERT((mpl::at_c<seq,1>::type::value == 5));
297 BOOST_STATIC_ASSERT((mpl::at_c<seq,2>::type::value == 2));
298#endif
299}
300
303static void test_exercise_5_7()
304{
305#ifdef EXERCISE_5_7
306 namespace mpl = boost::mpl;
307
309 typedef mpl::begin<dim1>::type dim_it1;
310
311 BOOST_STATIC_ASSERT((mpl::deref<dim_it1>::value == 2));
312
313 printf("%lu entries: (%i, %i, %i)\n",
314 mpl::size<dim1>::value,
315 mpl::at_c<dim1,0>::type::value,
316 mpl::at_c<dim1,1>::type::value,
317 mpl::at_c<dim1,2>::type::value);
318
319 BOOST_STATIC_ASSERT((mpl::size<dim1>::value == 3));
320 BOOST_STATIC_ASSERT((mpl::at_c<dim1,0>::type::value == 2));
321 BOOST_STATIC_ASSERT((mpl::at_c<dim1,1>::type::value == 5));
322 BOOST_STATIC_ASSERT((mpl::at_c<dim1,2>::type::value == 10));
323
324 typedef mpl::push_back< dim1, mpl::int_<3> >::type dim2;
325 BOOST_STATIC_ASSERT((mpl::size<dim2>::value == 4));
326 BOOST_STATIC_ASSERT((mpl::at_c<dim2,3>::type::value == 3));
327
328 typedef mpl::pop_back<dim1>::type dim3;
329 BOOST_STATIC_ASSERT((mpl::size<dim3>::value == 2));
330#endif
331}
332
335
336#ifdef EXERCISE_5_9
346template <typename CurFibIt, size_t Count>
347struct print_fibonacci
348{
350 typedef print_fibonacci<
351 typename boost::mpl::next<CurFibIt>::type,
352 Count+1> next;
353
356 void print() const
357 {
358 printf("%i ", boost::mpl::deref<CurFibIt>::type::value);
359 next const i;
360 i.print();
361 }
362};
363
365template <typename CurFibIt>
366struct print_fibonacci<CurFibIt, sMaxFibForInt32>
367{
369 void print() const
370 {
371 printf("%i ", boost::mpl::deref<CurFibIt>::type::value);
372 }
373};
374#endif
375
378{
379#ifdef EXERCISE_5_9
381
382 typedef print_fibonacci<
383 boost::mpl::begin<fibonacci_series>::type,
384 0
385 > printer;
386
387 printf("\nFibonacci: { ");
388 {
389 printer const p;
390 p.print();
391 }
392 printf("}\n");
393#endif
394}
395
397
398} // namespace <anon>
399
400int main()
401{
407
409 return 0;
410}
Define a tiny sequence with modifications from examples in Chapter 5.
int main()
Definition: chapter-5.cpp:400
BOOST_STATIC_ASSERT((boost::is_same< t5, expected_t5 >::value))
Solution to Exercise 5-10.
Solution to Exercise 5-1.
Solution to Exercise 5-6.
Solution to Exercise 5-7.
Solution to Exercise 5-8.
Solution to Exercise 5-9.
static size_t const sMaxFibForInt32
For a 32-bit signed integer, the max Fibonacci sequence seems to be this.
static void test_exercise_5_0()
Tests for Exercise 5-0.
Definition: chapter-5.cpp:184
static void test_exercise_5_3()
Tests for Exercise 5-3.
Definition: chapter-5.cpp:215
static void test_exercise_5_5()
Tests for Exercise 5-5.
Definition: chapter-5.cpp:239
static void test_exercise_5_6()
Tests for Exercise 5-6.
Definition: chapter-5.cpp:279
static void test_exercise_5_7()
Tests for Exercise 5-7.
Definition: chapter-5.cpp:303
static void print_fibonacci_series()
Give us a nice subroutine to tie Fibonacci seq printout all together.
Definition: chapter-5.cpp:377
Exists to inject functionality into the Boost MPL namespace.
Exists to inject functionality into the Boost namespace.
Provide utilities availble to all Chapter 5 solutions.
Encapsulate solution for Exercise 5-10.
Encapsulate solution for Exercise 5-1.
Encapsulate solution for Exercise 5-8.
Tests functionality from Exercise 5-10.
Definition: chapter-5.cpp:71
boost::mpl::next< tmp2 >::type tmp3
Definition: chapter-5.cpp:126
boost::mpl::next< tmp7 >::type tmp8
Definition: chapter-5.cpp:146
boost::mpl::next< tmp3 >::type tmp4
Definition: chapter-5.cpp:130
boost::mpl::deref< tmp3 >::type tmp3d
Definition: chapter-5.cpp:127
boost::mpl::deref< tmp5 >::type tmp5d
Definition: chapter-5.cpp:135
chapter5::tree< double, chapter5::tree< void *, int, long >, char > tree_seq
A test tree.
Definition: chapter-5.cpp:89
boost::mpl::next< tmp6 >::type tmp7
Definition: chapter-5.cpp:142
boost::mpl::begin< inorder_view< tree_seq_hard > >::type tmp1
Definition: chapter-5.cpp:118
boost::mpl::deref< tmp6 >::type tmp6d
Definition: chapter-5.cpp:139
boost::mpl::next< tmp4 >::type tmp5
Definition: chapter-5.cpp:134
boost::mpl::deref< tmp2 >::type tmp2d
Definition: chapter-5.cpp:123
BOOST_STATIC_ASSERT((boost::is_same< long, tmp1d >::value))
boost::mpl::end< inorder_view< tree_seq_hard > >::type tmp_end
Definition: chapter-5.cpp:147
boost::mpl::deref< tmp1 >::type tmp1d
Definition: chapter-5.cpp:119
boost::mpl::deref< tmp7 >::type tmp7d
Definition: chapter-5.cpp:143
chapter5::tree< double, chapter5::tree< short, long, chapter5::tree< float, void * > >, chapter5::tree< int, void_, char > > tree_seq_hard
A more involved test tree.
Definition: chapter-5.cpp:115
boost::mpl::next< tmp5 >::type tmp6
Definition: chapter-5.cpp:138
boost::mpl::deref< tmp4 >::type tmp4d
Definition: chapter-5.cpp:131
boost::mpl::next< tmp1 >::type tmp2
Definition: chapter-5.cpp:122
Tests functionality from Exercise 5-1.
Definition: chapter-5.cpp:40
BOOST_STATIC_ASSERT((boost::mpl::equal< testVec2, boost::mpl::vector_c< int, 2, 4, 3, 4 > >::value))
boost::mpl::vector_c< int, 1, 2, 3, 4 > testVec
Definition: chapter-5.cpp:43
double_first_half< testVec >::type testVec2
Definition: chapter-5.cpp:45
Tests functionality from Exercise 5-8.
Definition: chapter-5.cpp:55
boost::mpl::advance_c< i, 4 >::type j
Definition: chapter-5.cpp:63
BOOST_STATIC_ASSERT(boost::mpl::deref< i >::type::value==8)
boost::mpl::advance_c< boost::mpl::begin< exercise_5_8::fibonacci_series >::type, 6 >::type i
Definition: chapter-5.cpp:60
A small, random-access sequence type.
A basic type to represent a binary tree.
Compels iterators to traverse the tree "in order".
Double the values in the first half of the given sequence.
Represent the dimensions in an array type as a sequence of numbers.
Represent the dimensions in an array type as a sequence of numbers.
The Fibonacci series for use with Boost MPL sequences.