Skip to content

Commit acc3cab

Browse files
author
Oguzhan Katli
committed
final touches
1 parent bc40efa commit acc3cab

File tree

5 files changed

+173
-19
lines changed

5 files changed

+173
-19
lines changed

src/1-Inheritance/diamond_problem.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ namespace diamondproblem {
159159
} // namespace problem
160160
} // namespace diamondproblem
161161

162+
// https://gcc.godbolt.org/z/4xaeM5KK8
162163
ELEMENT_CODE(DiamondProblemExample) {
163164
using namespace diamondproblem;
164165
problem::demonstrate();

src/3-Static/static_usage.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace StaticUsage {
2121
};
2222
}
2323

24+
// https://gcc.godbolt.org/z/G19zvG6YP
2425
ELEMENT_CODE(StaticUsageExample)
2526
{
2627
using namespace StaticUsage;

src/5-Templates/template_crtp_usage.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,37 @@
33

44
namespace traits
55
{
6+
7+
namespace base
8+
{
9+
class Line
10+
{
11+
public:
12+
int draw() const { return 5; }
13+
};
14+
15+
class Circle
16+
{
17+
public:
18+
int draw() const { return 6; }
19+
};
20+
21+
template <typename Shape>
22+
void drawShape(const Shape& obj)
23+
{
24+
obj.draw(); // call draw() according to type of object
25+
}
26+
27+
void usage()
28+
{
29+
Line l;
30+
Circle c, c1, c2;
31+
32+
drawShape(l); //drawShape<Line>(Shape&) => Line::draw()
33+
drawShape(c1); //drawShape<Circle>(Shape&) => Circle::draw()
34+
}
35+
}
36+
637
namespace problem {
738
// common abstract base class GeoObj for geometric objects
839
class GeoObj {

src/5-Templates/template_traits.cpp

Lines changed: 133 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,151 @@ namespace template_traits
66
namespace problem
77
{
88
const unsigned max_chunk = 100;
9-
//
9+
10+
// works for ascii only
1011
class stream_buffer
1112
{
1213
public:
13-
stream_buffer(const std::string& input) {
14-
buff = new char[input.size()];
15-
std::memcpy(buff, input.c_str(), input.size());
14+
// ...
15+
// return the next character or EOF
16+
int sgetc() {
17+
return EOF;
1618
}
19+
};
1720

18-
~stream_buffer()
21+
// works when unicode
22+
class stream_buffer_unicode
23+
{
24+
public:
25+
// ...
26+
// return the next character or EOF
27+
wint_t sgetc() {
28+
return WEOF;
29+
}
30+
};
31+
32+
33+
void demonstrate()
34+
{
35+
#if UNICODE
36+
stream_buffer_unicode buffer;
37+
// get buffer and process
38+
wint_t ch;
39+
while ((ch = buffer.sgetc()) != WEOF)
1940
{
20-
delete buff;
41+
// process buffer
42+
putwchar(ch);
2143
}
44+
#else
45+
stream_buffer buffer;
46+
// get buffer and process
47+
int ch;
48+
while ((ch = buffer.sgetc()) != EOF)
49+
{
50+
// process buffer
51+
putchar(ch);
52+
}
53+
#endif
54+
}
55+
56+
} // namespace problem
57+
58+
namespace solution
59+
{
60+
template <typename CharT>
61+
struct char_traits { };
62+
// specialization for ascii chars
63+
template <>
64+
struct char_traits<char> {
65+
using char_type = char;
66+
using int_type = int;
67+
static inline int_type eof() { return EOF; }
68+
};
69+
// specialization for unicode chars
70+
template <>
71+
struct char_traits<wchar_t> {
72+
using char_type = wchar_t;
73+
using int_type = wint_t;
74+
static inline int_type eof() { return WEOF; }
75+
};
2276

77+
// now we can support different char representations by
78+
// using trait helpers
79+
template <typename CharT>
80+
class basic_stream_buffer
81+
{
82+
public:
83+
using traits_type = char_traits<CharT>;
84+
using int_type = traits_type::int_type;
2385
// ...
24-
int sgetc(); // return the next character or EOF
25-
int sgetn(char *, int N); // get N characters from buffer
26-
private:
27-
char *buff;
86+
static int_type eof() { return traits_type::eof(); }
87+
// return the next character or EOF
88+
int_type sgetc() {
89+
return traits_type::eof();
90+
}
2891
};
2992

30-
} // namespace problem
93+
#if UNICODE
94+
using basic_stream = basic_stream_buffer<wchar_t>;
95+
#else
96+
using basic_stream = basic_stream_buffer<char>;
97+
#endif
98+
void demonstrate()
99+
{
100+
basic_stream buffer;
101+
// get buffer and process
102+
basic_stream::int_type ch;
103+
while ((ch = buffer.sgetc()) != basic_stream::eof())
104+
{
105+
// process buffer
106+
putchar(ch);
107+
}
108+
}
109+
} // namespace solution
110+
111+
namespace type_traits
112+
{
113+
114+
template <typename Type>
115+
struct is_integer {
116+
static const bool val = false;
117+
};
118+
119+
template <>
120+
struct is_integer<int> {
121+
static const bool val = true;
122+
};
123+
124+
template <>
125+
struct is_integer<unsigned int> {
126+
static const bool val = true;
127+
};
128+
/*
129+
The simplest solution to compile-time assertions (Van Horn 1997), and one that works in C as well as in
130+
C++, relies on the fact that a zero-length array is illegal.
131+
*/
132+
#define STATIC_CHECK(expr) { char unnamed[(expr) ? 1 : 0]; }
133+
134+
template <typename T>
135+
void will_work_for_only_integer_types(T a, T b)
136+
{
137+
STATIC_CHECK(is_integer<T>::val);
138+
}
139+
140+
#include <type_traits>
141+
142+
template <typename T,
143+
typename = std::enable_if_t<std::is_integral<T>::value>>
144+
T will_work_for_only_integer_types_cpp11(T a, T b)
145+
{
146+
return a + b;
147+
}
148+
149+
150+
} // namespace type_traits
31151
}
32152

33-
ELEMENT_CODE(TemplateTraits) {
153+
ELEMENT_CODE(TemplateTraits)
154+
{
34155

35156
}

src/7-CustomComparators/custom_comparator.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010
#include <set>
1111
#include <type_traits>
1212

13-
class STMValueComparator {
13+
class ValueComparator {
1414
private:
1515
bool bUseCompEpsl;
1616
double dEpsl;
1717
public:
18-
explicit STMValueComparator(double epsl = 0) : dEpsl(epsl) {
18+
explicit ValueComparator(double epsl = 0) : dEpsl(epsl) {
1919
bUseCompEpsl = dEpsl == 0 ? false : true;
2020
}
2121
template <class T,
22-
typename = typename std::enable_if_t<std::is_floating_point<T>::value>>
23-
bool operator()(const T& lhs, const T& rhs) const {
22+
typename = typename std::enable_if_t<std::is_floating_point_v<T>>>
23+
bool operator()(const T& lhs, const T& rhs) const {
2424
if (bUseCompEpsl)
2525
return (std::fabs(lhs - rhs) > static_cast<T>(dEpsl)) &&
2626
(lhs < rhs);
@@ -114,23 +114,23 @@ ELEMENT_CODE(CustomComparatorNeedExample) {
114114
ELEMENT_CODE(CustomComparatorExample) {
115115

116116
{
117-
std::map<float, int, STMValueComparator> mm; // use numeric limit epsilon
117+
std::map<float, int, ValueComparator> mm; // use numeric limit epsilon
118118
mm[1.0] = 1;
119119
mm[2.0] = 2;
120120
mm[3.0] = 3;
121121
auto f = mm.find(1.0);
122122
}
123123

124124
{
125-
std::map<float, int, STMValueComparator> mm(STMValueComparator(1.1));
125+
std::map<float, int, ValueComparator> mm(ValueComparator(1.1));
126126
mm[1.0] = 1;
127127
mm[2.0] = 2;
128128
mm[3.0] = 3;
129129
auto f = mm.find(1.0);
130130
}
131131

132132
{
133-
std::map<int, int, STMValueComparator> mm(STMValueComparator(0));
133+
std::map<int, int, ValueComparator> mm(ValueComparator(0));
134134
mm[1] = 1;
135135
mm[2] = 2;
136136
mm[3] = 3;

0 commit comments

Comments
 (0)