C++ Template Metaprogramming
Solutions to the exercises throughout the book
Loading...
Searching...
No Matches
chapter-2.cpp
Go to the documentation of this file.
1// ===-- chapter-2/chapter-2.cpp -------------------------- -*- C++ -*- --=== //
20#include "exercise-2-0.hpp"
21#include "exercise-2-3.hpp"
22#if __cplusplus >= 202002L
23# include "c++20/exercise-2-1.hpp"
24# include "c++20/exercise-2-2.hpp"
25# include "c++20/exercise-2-4.hpp"
26# include "c++20/exercise-2-5.hpp"
27#else
28# include "exercise-2-1.hpp"
29# include "exercise-2-2.hpp"
30# include "exercise-2-4.hpp"
31# include "exercise-2-5.hpp"
32#endif
33
34#include <boost/type_traits/is_same.hpp>
35
36#include <cxxabi.h>
37
38#include <iostream>
39#include <typeinfo>
40
41
43// Testing / main()
45
46namespace {
47
48struct TestA { virtual ~TestA() {} };
49struct TestB : TestA {};
50
51static char const *demangle(char const *const name)
52{
53 static char buf[1024]; // Not re-entrant, but quick-and-dirty.
54
55 size_t size = sizeof(buf)/sizeof(*buf);
56 int status;
57
58 char const *const res = abi::__cxa_demangle(name, buf, &size, &status);
59 return status != 0 ? NULL : res;
60}
61
64static void test_exercise_2_0()
65{
66#ifdef EXERCISE_2_0
67 using namespace exercise_2_0;
68 int z = 5;
69
72 std::cout << "Neither x: " << x << ", nor y: " << y
73 << " are interesting.\n";
74
75 std::cout <<
76 boost::is_same<add_const_ref<int>::type, int const&>::value << '\n';
77 std::cout <<
78 boost::is_same<add_const_ref<int&>::type, int&>::value << '\n';
79 std::cout <<
80 boost::is_same<add_const_ref<int&>::type, int const&>::value << '\n';
81 std::cout <<
82 boost::is_same<
83 add_const_ref<int const&>::type, int const&>::value << '\n';
84 std::cout <<
85 boost::is_same<
86 add_const_ref<int const>::type, int const&>::value << '\n';
87#endif
88}
89
92static void test_exercise_2_1()
93{
94#ifdef EXERCISE_2_1
95 using namespace exercise_2_1;
96 std::cout
97 << boost::is_same<
99 int*>::value
100 << '\n';
101 std::cout
102 << boost::is_same<
104 long*[10]>::value
105 << '\n';
106 std::cout
107 << boost::is_same<
108 replace_type<char& (*)(), char&, long&>::type,
109 long& (*)()>::value
110 << '\n';
111 std::cout
112 << boost::is_same<
113 replace_type<char& (*)(char&), char&, long&>::type,
114 long& (*)(long&)>::value
115 << '\n';
116# if __cplusplus >= 202002L // Test C++20 variadic template method.
117 std::cout
118 << boost::is_same<
119 replace_type<char& (*)(char&, int, char*), char&, long&>::type,
120 long& (*)(long&, int, char*)>::value
121 << '\n';
122 std::cout
123 << boost::is_same<
124 replace_type<float& (*)(char&, float*, float, float[5]),
125 float, long>::type,
126 long& (*)(char&, long*, long, long[5])>::value
127 << '\n';
128# endif
129# if NEGATIVE_TEST
130 // This is an error in the current design:
131 std::cout
132 << boost::is_same<
133 replace_type<char& (*)(char&), float, long&>::type,
134 long& (*)(long&)>::value
135 << '\n';
136# endif
137#endif
138}
139
142static void test_exercise_2_2()
143{
144#ifdef EXERCISE_2_2
145 using namespace exercise_2_2;
146 TestB b;
147 TestA *a_ptr = &b;
148 TestB *b_ptr = polymorphic_downcast<TestB*>(a_ptr);
149
150 std::cout << "Address of b_ptr = " << static_cast<void*>(b_ptr) << '\n';
151
152 TestA& a_ref = b;
153 TestB& b_ref = polymorphic_downcast<TestB&>(a_ref);
154 std::cout << "Address of b_ref = " << static_cast<void*>(&b_ref) << '\n';
155#endif
156}
157
160static void test_exercise_2_3()
161{
162#ifdef EXERCISE_2_3
163 // ************************** TO-DO
164#endif
165}
166
169static void test_exercise_2_4()
170{
171#ifdef EXERCISE_2_4
172 using namespace exercise_2_4;
173 // prints "int"
174 std::cout << type_descriptor<int>() << '\n';
175
176 // prints "char*"
177 std::cout << type_descriptor<char*>() << '\n';
178
179 // prints "short int[5]"
180 std::cout << type_descriptor<short[5]>() << '\n';
181
182 // prints "long int const*&"
183 std::cout << type_descriptor<long const*&>() << '\n';
184
185 // prints "char*()"
186 std::cout << type_descriptor<char*()>() << '\n';
187
188 // prints "char*()"
189 std::cout << type_descriptor<char*(*)()>() << '\n';
190#endif
191}
192
195static void test_exercise_2_5()
196{
197#ifdef EXERCISE_2_5
198 using namespace exercise_2_5;
199 std::cout << type_descriptor_eng<char*(*[])()>() << '\n';
200#endif
201}
202
203} // namespace <anon>
204
205
206int main()
207{
208 std::cout << demangle(typeid(int*).name()) << '\n';
209
216 return 0;
217}
Solution to Exercise 2-1 (C++20).
Solution to Exercise 2-2 (C++20).
Solution to Exercise 2-4 (C++20).
Solution to Exercise 2-5 (C++20).
int main()
Definition: chapter-2.cpp:206
Solution to Exercise 2-0.
Solution to Exercise 2-1.
Solution to Exercise 2-2.
Solution to Exercise 2-3.
Solution to Exercise 2-4.
Solution to Exercise 2-5.
static void test_exercise_2_0()
Tests for Exercise 2-0.
Definition: chapter-2.cpp:64
static void test_exercise_2_1()
Tests for Exercise 2-1.
Definition: chapter-2.cpp:92
static void test_exercise_2_2()
Tests for Exercise 2-2.
Definition: chapter-2.cpp:142
static void test_exercise_2_3()
Tests for Exercise 2-3.
Definition: chapter-2.cpp:160
static void test_exercise_2_4()
Tests for Exercise 2-4.
Definition: chapter-2.cpp:169
static void test_exercise_2_5()
Tests for Exercise 2-5.
Definition: chapter-2.cpp:195
static char const * demangle(char const *const name)
Definition: chapter-2.cpp:51
Encapsulate solution for Exercise 2-0.
Encapsulate solution for Exercise 2-1.
Encapsulate solution for Exercise 2-2.
Encapsulate solution for Exercise 2-4.
Encapsulate solution for Exercise 2-5.
Given an arbitrary compound type, replace nested types.