37 | {
38 | void parse()
39 | {
40 | this->init(); // OK
41 | std::cout << "parse\n";
42 | }
43 | };
44 | ```
45 | ## Structure
46 |
47 | The source code for the book is organized per chapters. Each chapter has its own subfolder in the `src` folder. These subfolders are called `chapter_01`, `chapter_02`, etc. For most chapters, the code is found in a single source file, `main.cpp`. This file is organized in multiple namespaces, such as `n101`, `n102`, `n103` etc. for the first chapter, `n201`, `n202`, `n203` etc. for the second chapter and so on.
48 |
49 | ## Supported compilers
50 |
51 | All the code provided in the book is cross-platform. You can use any of the major compilers, MSVC, Clang, or GCC to compile the sources.
52 |
53 | You can also run snippets of code using compilers available online:
54 |
55 | - [Compiler Explorer](https://godbolt.org/)
56 | - [Wandbox](https://wandbox.org/)
57 | - [C++ Insights](https://cppinsights.io/)
58 |
59 | ## How to build
60 |
61 | You must have CMake to build the code.
62 |
63 | ### Example for creating a Visual Studio solution
64 |
65 | Run the following commands to create a solution for Visual Studio 2019:
66 |
67 | ```
68 | mkdir build
69 | cd build
70 | cmake -G "Visual Studio 16 2019" -A x64 ..
71 | ```
72 |
73 | Run the following commands to create a solution for Visual Studio 2022:
74 |
75 | ```
76 | mkdir build
77 | cd build
78 | cmake -G "Visual Studio 17 2022" -A x64 ..
79 | ```
80 |
81 | **Following is what you need for this book:**
82 | This book is for beginner-to-intermediate C++ developers who want to learn about template metaprogramming as well as advanced C++ developers looking to get up to speed with the new C++20 features related to templates and the the various idioms and patterns. Basic C++ coding experience is necessary to get started with this book.
83 |
84 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://packt.link/Un8j5).
85 |
86 | ### Related products
87 | * C++20 STL Cookbook [[Packt]](https://www.packtpub.com/product/c-20-stl-cookbook/9781803248714?utm_source=github&utm_medium=repository&utm_campaign=9781803248714) [[Amazon]](https://www.amazon.com/dp/1803248718)
88 |
89 | * CMake Best Practices [[Packt]](https://www.packtpub.com/product/cmake-best-practices/9781803239729?utm_source=github&utm_medium=repository&utm_campaign=9781803239729) [[Amazon]](https://www.amazon.com/dp/1803239727)
90 |
91 | ## Get to Know the Author
92 | **Marius Bancila**
93 | is a software engineer with two decades of experience in developing solutions for line of business applications and more. He is the author of Modern C++ Programming Cookbook and The Modern C++ Challenge. He works as a software architect and is focused on Microsoft technologies, mainly developing desktop applications with C++ and C#. He is passionate about sharing his technical expertise with others and, for that reason, he has been recognized as a Microsoft MVP for C++ and later developer technologies since 2006. Marius lives in Romania and is active in various online communities.
94 | ### Download a free PDF
95 |
96 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
97 | https://packt.link/free-ebook/9781803243450
98 |
--------------------------------------------------------------------------------
/src/chapter_01/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | file(GLOB headers *.h)
2 | add_executable(chapter_01 main.cpp ${headers})
--------------------------------------------------------------------------------
/src/chapter_01/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | namespace n101
4 | {
5 | int max(int const a, int const b)
6 | {
7 | return a > b ? a : b;
8 | }
9 |
10 | double max(double const a, double const b)
11 | {
12 | return a > b ? a : b;
13 | }
14 |
15 | using swap_fn = void(*)(void*, int const, int const);
16 | using compare_fn = bool(*)(void*, int const, int const);
17 |
18 | int partition(void* arr, int const low, int const high,
19 | compare_fn fcomp, swap_fn fswap)
20 | {
21 | int i = low - 1;
22 |
23 | for (int j = low; j <= high - 1; j++)
24 | {
25 | if (fcomp(arr, j, high))
26 | {
27 | i++;
28 | fswap(arr, i, j);
29 | }
30 | }
31 |
32 | fswap(arr, i + 1, high);
33 |
34 | return i + 1;
35 | }
36 |
37 | void quicksort(void* arr, int const low, int const high,
38 | compare_fn fcomp, swap_fn fswap)
39 | {
40 | if (low < high)
41 | {
42 | int const pi = partition(arr, low, high, fcomp, fswap);
43 | quicksort(arr, low, pi - 1, fcomp, fswap);
44 | quicksort(arr, pi + 1, high, fcomp, fswap);
45 | }
46 | }
47 |
48 | void swap_int(void* arr, int const i, int const j)
49 | {
50 | int* iarr = (int*)arr;
51 | int t = iarr[i];
52 | iarr[i] = iarr[j];
53 | iarr[j] = t;
54 | }
55 |
56 | bool less_int(void* arr, int const i, int const j)
57 | {
58 | int* iarr = (int*)arr;
59 | return iarr[i] <= iarr[j];
60 | }
61 |
62 | struct int_vector
63 | {
64 | int_vector();
65 |
66 | size_t size() const;
67 | size_t capacity() const;
68 | bool empty() const;
69 |
70 | void clear();
71 | void resize(size_t const size);
72 |
73 | void push_back(int value);
74 | void pop_back();
75 |
76 | int at(size_t const index) const;
77 | int operator[](size_t const index) const;
78 | private:
79 | int* data_;
80 | size_t size_;
81 | size_t capacity_;
82 | };
83 |
84 | constexpr char NewLine = '\n';
85 | constexpr wchar_t NewLineW = L'\n';
86 | constexpr char8_t NewLineU8 = u8'\n';
87 | constexpr char16_t NewLineU16 = u'\n';
88 | constexpr char32_t NewLineU32 = U'\n';
89 | }
90 |
91 | namespace n102
92 | {
93 | template
94 | T max(T const a, T const b)
95 | {
96 | return a > b ? a : b;
97 | }
98 |
99 | struct foo {};
100 |
101 | template
102 | void swap(T* a, T* b)
103 | {
104 | T t = *a;
105 | *a = *b;
106 | *b = t;
107 | }
108 |
109 | template
110 | int partition(T arr[], int const low, int const high)
111 | {
112 | T pivot = arr[high];
113 | int i = (low - 1);
114 |
115 | for (int j = low; j <= high - 1; j++)
116 | {
117 | if (arr[j] < pivot)
118 | {
119 | i++;
120 | swap(&arr[i], &arr[j]);
121 | }
122 | }
123 |
124 | swap(&arr[i + 1], &arr[high]);
125 |
126 | return i + 1;
127 | }
128 |
129 | template
130 | void quicksort(T arr[], int const low, int const high)
131 | {
132 | if (low < high)
133 | {
134 | int const pi = partition(arr, low, high);
135 | quicksort(arr, low, pi - 1);
136 | quicksort(arr, pi + 1, high);
137 | }
138 | }
139 |
140 | template
141 | struct vector
142 | {
143 | vector();
144 |
145 | size_t size() const;
146 | size_t capacity() const;
147 | bool empty() const;
148 |
149 | void clear();
150 | void resize(size_t const size);
151 |
152 | void push_back(T value);
153 | void pop_back();
154 |
155 | T at(size_t const index) const;
156 | T operator[](size_t const index) const;
157 | private:
158 | T* data_;
159 | size_t size_;
160 | size_t capacity_;
161 | };
162 |
163 | template
164 | constexpr T NewLine = T('\n');
165 | }
166 |
167 | int main()
168 | {
169 | {
170 | using namespace n101;
171 |
172 | int arr[] = { 13, 1, 8, 3, 5, 2, 1 };
173 | int n = sizeof(arr) / sizeof(arr[0]);
174 | quicksort(arr, 0, n - 1, less_int, swap_int);
175 | }
176 |
177 | {
178 | using namespace n102;
179 |
180 | max(1, 2); // OK, compares ints
181 | max(1.0, 2.0); // OK, compares doubles
182 |
183 | //foo f1, f2;
184 | //max(f1, f2); // Error, operator> not overloaded for foo
185 |
186 | max(1, 2);
187 | max(1.0, 2.0);
188 | //max(f1, f2);
189 | }
190 |
191 | {
192 | using namespace n102;
193 |
194 | int arr[] = { 13, 1, 8, 3, 5, 2, 1 };
195 | int n = sizeof(arr) / sizeof(arr[0]);
196 | quicksort(arr, 0, n - 1);
197 | }
198 |
199 | {
200 | using namespace n102;
201 |
202 | std::wstring test = L"demo";
203 | test += NewLine;
204 | std::wcout << test;
205 | }
206 | }
--------------------------------------------------------------------------------
/src/chapter_02/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | file(GLOB headers *.h)
2 | add_executable(chapter_02 source1.cpp source2.cpp main.cpp ${headers})
--------------------------------------------------------------------------------
/src/chapter_02/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include