--- /dev/null
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
--- /dev/null
+\r
+Microsoft Visual Studio Solution File, Format Version 12.00\r
+# Visual Studio Version 16\r
+VisualStudioVersion = 16.0.29806.167\r
+MinimumVisualStudioVersion = 10.0.40219.1\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sandbox", "Sandbox\Sandbox.vcxproj", "{1642C97D-ED86-4894-A9A9-0A2F265DBCDB}"\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|x64 = Debug|x64\r
+ Debug|x86 = Debug|x86\r
+ Release|x64 = Release|x64\r
+ Release|x86 = Release|x86\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {1642C97D-ED86-4894-A9A9-0A2F265DBCDB}.Debug|x64.ActiveCfg = Debug|x64\r
+ {1642C97D-ED86-4894-A9A9-0A2F265DBCDB}.Debug|x64.Build.0 = Debug|x64\r
+ {1642C97D-ED86-4894-A9A9-0A2F265DBCDB}.Debug|x86.ActiveCfg = Debug|Win32\r
+ {1642C97D-ED86-4894-A9A9-0A2F265DBCDB}.Debug|x86.Build.0 = Debug|Win32\r
+ {1642C97D-ED86-4894-A9A9-0A2F265DBCDB}.Release|x64.ActiveCfg = Release|x64\r
+ {1642C97D-ED86-4894-A9A9-0A2F265DBCDB}.Release|x64.Build.0 = Release|x64\r
+ {1642C97D-ED86-4894-A9A9-0A2F265DBCDB}.Release|x86.ActiveCfg = Release|Win32\r
+ {1642C97D-ED86-4894-A9A9-0A2F265DBCDB}.Release|x86.Build.0 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
+ EndGlobalSection\r
+ GlobalSection(ExtensibilityGlobals) = postSolution\r
+ SolutionGuid = {63BADAE9-45C6-45B3-9459-7911368E2F07}\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+#include "AggregateInitializations.h"\r
+\r
+#include <iostream>\r
+using namespace std;\r
+\r
+namespace AggregateInitializations\r
+{\r
+ struct B\r
+ {\r
+ double q;\r
+ };\r
+\r
+ struct S : B\r
+ {\r
+ int i;\r
+ float f;\r
+ };\r
+\r
+}\r
+\r
+void AggregateInitializations::tests()\r
+{\r
+ S s{ {42.123}, 1, 2.32f }; // Initialization of base class.\r
+ cout << "s.q = " << s.q << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+\r
+namespace AggregateInitializations\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+#include "Bind.h"\r
+\r
+#include <iostream>\r
+#include <functional>\r
+using namespace std;\r
+\r
+// https://en.cppreference.com/w/cpp/utility/functional/bind\r
+// Ep 15: https://www.youtube.com/watch?v=JtUZmkvroKg & https://www.youtube.com/watch?v=ZlHi8txU4aQ\r
+\r
+namespace Bind\r
+{\r
+ template <typename T>\r
+ void print(T i, const string& s)\r
+ {\r
+ cout << i << ' ' << s << endl;\r
+ }\r
+\r
+ void bind()\r
+ {\r
+ int i = 5;\r
+\r
+ // The given function must be a concrete one (the generic parameter of 'print' must be specified in this case).\r
+ // 'ref' is to create a standard reference to 'i'.\r
+ // the second parameter create a parameter in the new created function.\r
+ // 'bind' were originaly from the Boost library.\r
+ const auto f = bind(&print<int>, ref(i), placeholders::_1);\r
+\r
+ f("Hello");\r
+\r
+ i = 6;\r
+ f(", World");\r
+\r
+ function<void(const string&)> f2(f); // Create a 'std::function'.\r
+ i = 7;\r
+ f2("!");\r
+ }\r
+\r
+ // Prefer lambdas instead of bind.\r
+ void lambda()\r
+ {\r
+ // Swapping arguments.\r
+ const auto f = [](auto&& arg1, auto&& arg2)\r
+ {\r
+ // Perfect forwarding (not necessary).\r
+ print(forward<decltype(arg2)>(arg2), forward<decltype(arg1)>(arg1));\r
+ };\r
+\r
+ f("Hello", 42);\r
+ }\r
+}\r
+\r
+void Bind::tests()\r
+{\r
+ Bind::bind();\r
+ cout << "-----" << endl;\r
+ Bind::lambda();\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace Bind\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+#include "Concepts.h"\r
+\r
+#include <iostream>\r
+#include <functional>\r
+#include <cmath>\r
+#include <concepts>\r
+#include <type_traits>\r
+#include <vector>\r
+using namespace std;\r
+\r
+// From: "Demo Zoo: Zero Cost Abstractions in C++20, Rust, & Zig": https://www.youtube.com/watch?v=43X9ia-qpds\r
+\r
+namespace Concepts\r
+{\r
+ template<class Vec>\r
+ using Scalar = std::decay_t<decltype(Vec()[0])>;\r
+\r
+ template<class Vec>\r
+ concept FloatVec =\r
+ std::floating_point<Scalar<Vec>> &&\r
+ requires(Vec vec)\r
+ {\r
+ { vec.size() } -> std::integral;\r
+ };\r
+\r
+ template<FloatVec Vec>\r
+ auto norm(Vec vec) -> Scalar<Vec> // Should be 'norm(const Vec& vec)' but it doesn't work with VS 2019 16.6.3.\r
+ {\r
+ using Index = decltype(vec.size());\r
+ Scalar<Vec> result = 0;\r
+ for (Index i = 0; i < vec.size(); i += 1)\r
+ {\r
+ result += vec[i] * vec[i];\r
+ }\r
+ return std::sqrt(result);\r
+ }\r
+\r
+ struct Point2\r
+ {\r
+ float x = 0;\r
+ float y = 0;\r
+\r
+ auto size() -> int {\r
+ return 2;\r
+ }\r
+\r
+ auto operator[](int i) const -> float {\r
+ return i == 0 ? x : y;\r
+ }\r
+ };\r
+\r
+ float norm2(float x, float y)\r
+ {\r
+ return norm(Point2{ x, y });\r
+ }\r
+\r
+ double norm_nd(const std::vector<double>& a)\r
+ {\r
+ return norm(a);\r
+ }\r
+}\r
+\r
+void Concepts::tests()\r
+{\r
+ cout << "norm: " << norm_nd({ 1, 2, 3 }) << endl;\r
+ cout << "norm: " << norm2(3, 4) << endl;\r
+}\r
--- /dev/null
+#pragma once\r
+\r
+namespace Concepts\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+#include "ConstexprIf.h"\r
+\r
+#include <iostream>\r
+#include <type_traits>\r
+#include <limits>\r
+using namespace std;\r
+\r
+// Ep 18: https://www.youtube.com/watch?v=qHgM5UdzPQU\r
+\r
+namespace ConstexprIf\r
+{\r
+ template<typename T>\r
+ constexpr bool is_integral_has_a_big_max_limit()\r
+ {\r
+ if constexpr (is_integral<T>::value && !is_same<bool, T>::value) // Because 'bool' is an integral type.\r
+ {\r
+ // Here we can use a '&&' to put this condition in the first 'if' because template do not use short-cirtcuit boolean operators.\r
+ if constexpr (numeric_limits<T>::max() > numeric_limits<int>::max())\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ template<typename T>\r
+ auto print_type_info(const T& v)\r
+ {\r
+ if constexpr (is_integral_has_a_big_max_limit<T>())\r
+ return v + 1;\r
+ else if constexpr (is_floating_point<T>::value)\r
+ return v + 0.1;\r
+ else\r
+ return v;\r
+ }\r
+}\r
+\r
+void ConstexprIf::tests()\r
+{\r
+ cout << print_type_info(5) << endl;\r
+ cout << print_type_info(5LL) << endl;\r
+ cout << print_type_info(2.3) << endl;\r
+ cout << print_type_info("hello") << endl;\r
+ cout << print_type_info(true) << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace ConstexprIf\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+#include "CostOfUsingStatic.h"\r
+\r
+#include <iostream>\r
+using namespace std;\r
+\r
+// From: https://www.youtube.com/watch?v=B3WWsKFePiM\r
+\r
+namespace CostOfUsingStatic\r
+{\r
+ struct C\r
+ {\r
+ // This call is costy.\r
+ static const string& magic_static()\r
+ {\r
+ // Static variables are very costly.\r
+ // Each time a thread safe comparison must be executed.\r
+ static const string s = "bob";\r
+ return s;\r
+ }\r
+\r
+ const string& s = magic_static();\r
+\r
+ const string& magic_static_ref()\r
+ {\r
+ return s;\r
+ }\r
+ };\r
+}\r
+\r
+void CostOfUsingStatic::tests()\r
+{\r
+ C c;\r
+ size_t total_size = 0;\r
+\r
+ for (int i = 0; i < 2000000000; ++i)\r
+ {\r
+ total_size += c.magic_static_ref().size() + i; // It takes ~500 ms.\r
+ //total_size += C::magic_static().size() + i; // It takes ~1200 ms.\r
+ }\r
+\r
+ //return total_size;\r
+\r
+ cout << "total size: " << total_size << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace CostOfUsingStatic\r
+{\r
+ void tests();\r
+}\r
+\r
--- /dev/null
+#include "DefaultMethods.h"\r
+\r
+#include <iostream>\r
+using namespace std;\r
+\r
+namespace DefaultMethods\r
+{\r
+ class C\r
+ {\r
+ int a;\r
+\r
+ public:\r
+ // Default constructor (here we remove the default one).\r
+ C() = delete;\r
+\r
+ // Copy constructor.\r
+ C(const C& other);\r
+\r
+ // Move constructor.\r
+ C(C&& other) noexcept;\r
+\r
+ // A custom constructor.\r
+ C(int a);\r
+\r
+ // Copy-assignment operator.\r
+ C& operator=(const C& other);\r
+\r
+ // Move-assignment operator.\r
+ C& operator=(C&& other) noexcept;\r
+\r
+ ~C() noexcept;\r
+\r
+ int getA();\r
+ };\r
+\r
+ C::C(const C& other)\r
+ {\r
+ cout << "Copy ctor, other.a = " << other.a << endl;\r
+ this->a = other.a;\r
+ }\r
+\r
+ C::C(C&& other) noexcept\r
+ {\r
+ cout << "Move ctor, other.a = " << other.a << endl;\r
+ this->a = other.a;\r
+ other.a = 0;\r
+ }\r
+\r
+ C::C(int a)\r
+ : a{ a }\r
+ {\r
+ cout << "ctor, a = " << a << endl;\r
+ }\r
+\r
+ C& C::operator=(const C& other)\r
+ {\r
+ cout << "Copy assignment operator" << endl;\r
+ this->a = other.a;\r
+ return *this;\r
+ }\r
+\r
+ C& C::operator=(C&& other) noexcept\r
+ {\r
+ cout << "Move assignment operator" << endl;\r
+ this->a = other.a;\r
+ other.a = 0;\r
+ return *this;\r
+ }\r
+\r
+ C::~C() noexcept\r
+ {\r
+ cout << "Destructor, a = " << this->a << endl;\r
+ }\r
+\r
+ int C::getA()\r
+ {\r
+ return this->a;\r
+ }\r
+}\r
+\r
+void DefaultMethods::tests()\r
+{\r
+ // Use of universal initialization.\r
+ C c1{ 42 };\r
+\r
+ C c2 = move(c1); // Force to treat 'c1' as a right-hand value.\r
+ C c3{ c1 };\r
+ C c4{ 42 };\r
+ cout << "c1.a = " << c1.getA() << endl;\r
+ cout << "c2.a = " << c2.getA() << endl;\r
+ cout << "c3.a = " << c3.getA() << endl;\r
+ cout << "c4.a = " << c4.getA() << endl;\r
+\r
+ cout << "--- copy some values" << endl;\r
+ c1 = c2;\r
+ c2 = C{ 321 };\r
+ cout << "c1.a = " << c1.getA() << endl;\r
+ cout << "c2.a = " << c2.getA() << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace DefaultMethods\r
+{\r
+ void tests();\r
+}\r
+\r
+\r
--- /dev/null
+#include "FoldExpressions.h"\r
+\r
+#include <iostream>\r
+using namespace std;\r
+\r
+\r
+// Ep 20: https://www.youtube.com/watch?v=nhk8pF_SlTk\r
+// https://en.cppreference.com/w/cpp/language/fold\r
+\r
+namespace FoldExpressions\r
+{\r
+ // Old fashion (before C++17).\r
+ template<typename ... T>\r
+ auto sum(T ... t)\r
+ {\r
+ typename common_type<T...>::type result{};\r
+ initializer_list<int>{ (result += t, 0)... };\r
+ return result;\r
+ }\r
+\r
+ // With C++17.\r
+ template<typename ... T>\r
+ auto sum2(T ... t)\r
+ {\r
+ const double n = 5;\r
+ return (5 + ... + t);\r
+ }\r
+\r
+ template<typename ... T>\r
+ auto avg(T ... t)\r
+ {\r
+ return (t + ...) / sizeof...(t);\r
+ }\r
+}\r
+\r
+void FoldExpressions::tests()\r
+{\r
+ cout << sum(1, 2.2, 3, 4, 5) << endl;\r
+ cout << sum2(1, 2.2, 3, 4, 5) << endl;\r
+\r
+ cout << avg(1, 2.2, 3, 4, 5) << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace FoldExpressions\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+#include "FunctionsAsTemplate.h"\r
+\r
+#include <iostream>\r
+#include <map>\r
+using namespace std;\r
+\r
+#include "Types.h"\r
+\r
+namespace FunctionsAsTemplate\r
+{\r
+ template <i64(*f)(i64)>\r
+ i64 memoize(i64 x)\r
+ {\r
+ static std::map<i64, i64> cache;\r
+ auto i = cache.find(x);\r
+ if (i != cache.end())\r
+ return i->second;\r
+ else\r
+ return cache[x] = f(x);\r
+ }\r
+\r
+ i64 fib(i64 n) {\r
+ if (n < 2)\r
+ return n;\r
+ else\r
+ return memoize<fib>(n - 1) + memoize<fib>(n - 2);\r
+ }\r
+}\r
+\r
+void FunctionsAsTemplate::tests()\r
+{\r
+ i64 n = 80;\r
+ cout << "fib(" << n << ") = " << fib(n) << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace FunctionsAsTemplate\r
+{\r
+ void tests();\r
+}\r
+\r
--- /dev/null
+#include "IfAndSwitchInitStatements.h"\r
+\r
+#include <iostream>\r
+#include <vector>\r
+#include <algorithm>\r
+using namespace std;\r
+\r
+// Ep 21: https://www.youtube.com/watch?v=AiXU5EuLZgc\r
+\r
+namespace IfAndSwitchInitStatements\r
+{\r
+ vector<int> make_vec()\r
+ {\r
+ return { 1, 2, 3, 4 };\r
+ }\r
+}\r
+\r
+void IfAndSwitchInitStatements::tests()\r
+{\r
+ auto vec = make_vec();\r
+\r
+ // Same for 'switch' block.\r
+ if (const auto itr = find(vec.begin(), vec.end(), 2);\r
+ itr != vec.end())\r
+ {\r
+ *itr = 42;\r
+ }\r
+ else\r
+ {\r
+ vec.push_back(42);\r
+ }\r
+\r
+ // Declare an variable into a if condition allows to use this variable only in the if scope\r
+ // and will not get out of scope.\r
+ // Here we can reuse the name 'itr' previously used in the previous if statement.\r
+ if (const auto itr = find(vec.begin(), vec.end(), 3);\r
+ itr != vec.end())\r
+ {\r
+ *itr = 43;\r
+ }\r
+ else\r
+ {\r
+ vec.push_back(43);\r
+ }\r
+\r
+ for (auto i = vec.begin(); i != vec.end(); ++i)\r
+ {\r
+ if (i != vec.begin())\r
+ cout << ", ";\r
+ cout << *i;\r
+ }\r
+\r
+ cout << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace IfAndSwitchInitStatements\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+#include "Lambdas.h"\r
+\r
+#include <iostream>\r
+#include <string>\r
+#include <vector>\r
+#include <array>\r
+#include <variant>\r
+#include <algorithm>\r
+using namespace std;\r
+\r
+// Ep 32: https://www.youtube.com/watch?v=_CbBfuQQQI8\r
+// Ep 37: https://www.youtube.com/watch?v=_1X9D8Z5huA\r
+// Ep 40: https://www.youtube.com/watch?v=W-xTpqj31mI, not shown here, see 'VariadicUsing.cpp'.\r
+// Ep 41: https://www.youtube.com/watch?v=kmza9U_niq4 (constexpr Lambda Support)\r
+// Ep 49: https://www.youtube.com/watch?v=3wm5QzdddYc (Why Inherit From Lambdas?)\r
+\r
+namespace Lambdas\r
+{\r
+ // Identical to the lambda [](){ return 5; }.\r
+ struct Lambda\r
+ {\r
+ auto operator()() const\r
+ {\r
+ return 5;\r
+ }\r
+ };\r
+\r
+ /////\r
+\r
+ struct Color\r
+ {\r
+ uint8_t num;\r
+ uint8_t r;\r
+ uint8_t g;\r
+ uint8_t b;\r
+ double luma = 0.2126 * r + 0.7152 * g + 0.0722 * b;\r
+ };\r
+\r
+ ostream& operator<<(ostream& stream, const Color& color)\r
+ {\r
+ stream << "{ num = " << int(color.num) << ", r = " << int(color.r) << ", g = " << int(color.g) << ", b = " << int(color.b) << "}";\r
+ return stream;\r
+ }\r
+\r
+ template<typename Colors>\r
+ constexpr auto nearest_color(const Colors& colors, const uint8_t r, const uint8_t g, const uint8_t b)\r
+ {\r
+ return\r
+ *min_element(\r
+ begin(colors),\r
+ end(colors),\r
+ // Lambda in constexpr.\r
+ [r, g, b](const auto& lhs, const auto& rhs)\r
+ {\r
+ const auto square = [](auto t) { return t * t; };\r
+ return\r
+ square(lhs.r - r) + square(lhs.g - g) + square(lhs.b - b) <\r
+ square(rhs.r - r) + square(rhs.g - g) + square(rhs.b - b);\r
+ }\r
+ );\r
+ }\r
+\r
+ /////\r
+\r
+ // Merge types with subtyping.\r
+ template<typename ... B>\r
+ struct Visitor : B...\r
+ {\r
+ template<typename ... T>\r
+ Visitor(T&& ... t) : B(forward<T>(t))...\r
+ {\r
+ }\r
+ };\r
+\r
+ // Class template argument deduction: https://en.cppreference.com/w/cpp/language/class_template_argument_deduction\r
+ template<typename ... T>\r
+ Visitor(T...) -> Visitor<decay_t<T>...>;\r
+}\r
+\r
+void Lambdas::tests()\r
+{\r
+ // Parameter parenthesis can be omitted.\r
+ cout << [] { return 5; }() << endl;\r
+\r
+ cout << "/////" << endl;\r
+ /////\r
+\r
+ // Stateful lambda as a fibonnacci sequence.\r
+ auto l = [i = 0, j = 1]() mutable\r
+ {\r
+ i = exchange(j, j + i);\r
+ return i;\r
+ };\r
+\r
+ for (int i = 0; i < 10; i++)\r
+ cout << l() << endl;\r
+\r
+ cout << "/////" << endl;\r
+ /////\r
+\r
+ vector<Color> colors{ Color { 1, 10, 50, 200 }, Color { 2, 40, 10, 100 } , Color { 3, 250, 0, 70 } };\r
+ auto c = nearest_color(colors, 20, 40, 60);\r
+ cout << "color: " << c << endl;\r
+\r
+ cout << "/////" << endl;\r
+ /////\r
+\r
+ // Array of doubles and ints.\r
+ const auto aString{ "XYZ"s };\r
+ array<variant<double, int, string>, 6> a{ "ABC", 13.2, 3, 6.8, aString, 7 };\r
+\r
+ int intTotal = 0;\r
+ double doubleTotal = 0.0;\r
+ string allStrings;\r
+ Visitor visitor{\r
+ [&intTotal](const int i) { intTotal += i; },\r
+ [&doubleTotal](const double d) { doubleTotal += d; },\r
+ [&allStrings](const string& s) { allStrings.append(s); }\r
+ };\r
+\r
+ for_each(begin(a), end(a), [&visitor](const auto& v) { visit(visitor, v); });\r
+\r
+ cout << "intTotal = " << intTotal << ", doubleTotal = " << doubleTotal << ", allStrings = " << allStrings << endl;\r
+}\r
--- /dev/null
+#pragma once\r
+\r
+namespace Lambdas\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+#include "NextAndExchange.h"\r
+\r
+#include <iostream>\r
+#include <vector>\r
+#include <algorithm>\r
+using namespace std;\r
+\r
+namespace NextAndExchange\r
+{\r
+\r
+}\r
+\r
+void NextAndExchange::tests()\r
+{\r
+ // 'next'.\r
+ vector<int> v{ 42, 420, 2, 3, 4, 5, 6, 7 };\r
+ cout << "Is the list sorted? " << is_sorted(next(v.begin()), v.end()) << endl;\r
+\r
+ // 'exchange'.\r
+ auto a = 1;\r
+ auto b = exchange(a, 2);\r
+ cout << "a = " << a << ", b = " << b << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace NextAndExchange\r
+{\r
+ void tests();\r
+}\r
+\r
--- /dev/null
+#include "PointerToMember.h"\r
+\r
+#include <iostream>\r
+using namespace std;\r
+\r
+namespace PointerToMember\r
+{\r
+ struct Test {\r
+ int num;\r
+\r
+ Test(int n)\r
+ {\r
+ this->num = n;\r
+ }\r
+\r
+ void func()\r
+ {\r
+ cout << "func called, this->num = " << this->num << endl;\r
+ }\r
+ };\r
+\r
+ int Test::* ptr_num = &Test::num; // Pointer to a field of 'Test'.\r
+ void (Test::* ptr_func)() = &Test::func; // Pointer to a method of 'Test'.\r
+}\r
+\r
+void PointerToMember::tests()\r
+{\r
+ Test t{ 42 };\r
+ Test* pt = new Test{ 420 };\r
+\r
+ (t.*ptr_func)();\r
+ (pt->*ptr_func)();\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace PointerToMember\r
+{\r
+ void tests();\r
+}\r
+\r
--- /dev/null
+#include "ReadVarint.h"\r
+\r
+#include <iostream>\r
+using namespace std;\r
+\r
+// 'varint' is a way to encode integer in a variable number of byte. Using for serializing for example.\r
+// Partial implementation of https://developers.google.com/protocol-buffers/docs/encoding\r
+\r
+namespace ReadVarint\r
+{\r
+ void readUInt(const uint8_t*& p, uint32_t res, uint32_t& result)\r
+ {\r
+ for (uint32_t i = 2; i < 5; i++)\r
+ {\r
+ uint32_t byte = static_cast<uint8_t>(p[i]);\r
+ res += (byte - 1) << (7 * i);\r
+ if (byte < 128)\r
+ {\r
+ p += (size_t)i + 1;\r
+ result = res;\r
+ return;\r
+ }\r
+ }\r
+\r
+ for (uint32_t i = 5; i < 10; i++)\r
+ {\r
+ uint32_t byte = static_cast<uint8_t>(p[i]);\r
+ if (byte < 128)\r
+ {\r
+ p += (size_t)i + 1;\r
+ result = res;\r
+ return;\r
+ }\r
+ }\r
+\r
+ result = res;\r
+ }\r
+\r
+ void readUInt(const uint8_t*& p, uint32_t res32, uint64_t& result)\r
+ {\r
+ uint64_t res = res32;\r
+ for (uint32_t i = 2; i < 10; i++)\r
+ {\r
+ uint64_t byte = static_cast<uint8_t>(p[i]);\r
+ res += (byte - 1) << (7 * i);\r
+ if (byte < 128)\r
+ {\r
+ p += (size_t)i + 1;\r
+ result = res;\r
+ return;\r
+ }\r
+ }\r
+\r
+ result = 0;\r
+ }\r
+\r
+ template<typename T>\r
+ T readUInt(const uint8_t*& p)\r
+ {\r
+ p += 1; // Skip the first byte (type + field n°)\r
+\r
+ uint32_t res = p[0];\r
+ if (!(res & 0x80))\r
+ {\r
+ p += 1;\r
+ return res;\r
+ }\r
+\r
+ uint32_t byte = p[1];\r
+ res += (byte - 1) << 7;\r
+ if (!(byte & 0x80))\r
+ {\r
+ p += 2;\r
+ return res;\r
+ }\r
+\r
+ T result;\r
+ readUInt(p, res, result);\r
+ return result;\r
+ }\r
+}\r
+\r
+void ReadVarint::tests()\r
+{\r
+ const uint8_t bytes[] = {\r
+ 0x08, 0x03, // v1 = 3.\r
+ 0x10, 0xdf, 0xd0, 0x03, // v2 = 59487.\r
+\r
+ 0x1a, 0x0a, // v3 = 10.\r
+\r
+ 0x20, 0xb7, 0xac, 0xe5, 0x85, 0x08, 0x28, // v4 = 2159629879\r
+\r
+ 0xb4, 0xdb, 0x9b, 0xf0, 0xe6, 0x97, 0xb8, 0xc1, 0x59, 0x38 // v5 = 6449964724842327476\r
+ };\r
+\r
+ const uint8_t* p = bytes; // Pointer on const bytes.\r
+\r
+ auto v1 = readUInt<uint32_t>(p);\r
+ auto v2 = readUInt<uint32_t>(p);\r
+ auto v3 = readUInt<uint32_t>(p);\r
+ auto v4 = readUInt<uint64_t>(p);\r
+ auto v5 = readUInt<uint64_t>(p);\r
+\r
+ cout << "p = " << hex << (int)(*p) << dec << endl;\r
+\r
+ cout << "v1 = " << v1 << ", v2 = " << v2 << ", v3 = " << v3 << ", v4 = " << v4 << ", v5 = " << v5<< endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace ReadVarint\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup Label="ProjectConfigurations">\r
+ <ProjectConfiguration Include="Debug|Win32">\r
+ <Configuration>Debug</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ <ProjectConfiguration Include="Release|Win32">\r
+ <Configuration>Release</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ <ProjectConfiguration Include="Debug|x64">\r
+ <Configuration>Debug</Configuration>\r
+ <Platform>x64</Platform>\r
+ </ProjectConfiguration>\r
+ <ProjectConfiguration Include="Release|x64">\r
+ <Configuration>Release</Configuration>\r
+ <Platform>x64</Platform>\r
+ </ProjectConfiguration>\r
+ </ItemGroup>\r
+ <PropertyGroup Label="Globals">\r
+ <VCProjectVersion>16.0</VCProjectVersion>\r
+ <ProjectGuid>{1642C97D-ED86-4894-A9A9-0A2F265DBCDB}</ProjectGuid>\r
+ <Keyword>Win32Proj</Keyword>\r
+ <RootNamespace>Sandbox</RootNamespace>\r
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>true</UseDebugLibraries>\r
+ <PlatformToolset>v142</PlatformToolset>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>false</UseDebugLibraries>\r
+ <PlatformToolset>v142</PlatformToolset>\r
+ <WholeProgramOptimization>true</WholeProgramOptimization>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>true</UseDebugLibraries>\r
+ <PlatformToolset>v142</PlatformToolset>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>false</UseDebugLibraries>\r
+ <PlatformToolset>v142</PlatformToolset>\r
+ <WholeProgramOptimization>true</WholeProgramOptimization>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+ <ImportGroup Label="ExtensionSettings">\r
+ </ImportGroup>\r
+ <ImportGroup Label="Shared">\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <PropertyGroup Label="UserMacros" />\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <LinkIncremental>true</LinkIncremental>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+ <LinkIncremental>true</LinkIncremental>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <LinkIncremental>false</LinkIncremental>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+ <LinkIncremental>false</LinkIncremental>\r
+ </PropertyGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <ClCompile>\r
+ <PrecompiledHeader>\r
+ </PrecompiledHeader>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <SDLCheck>true</SDLCheck>\r
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <ConformanceMode>true</ConformanceMode>\r
+ <LanguageStandard>stdcpplatest</LanguageStandard>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+ <ClCompile>\r
+ <PrecompiledHeader>\r
+ </PrecompiledHeader>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <SDLCheck>true</SDLCheck>\r
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <ConformanceMode>true</ConformanceMode>\r
+ <LanguageStandard>stdcpplatest</LanguageStandard>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <ClCompile>\r
+ <PrecompiledHeader>\r
+ </PrecompiledHeader>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <FunctionLevelLinking>true</FunctionLevelLinking>\r
+ <IntrinsicFunctions>true</IntrinsicFunctions>\r
+ <SDLCheck>true</SDLCheck>\r
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <ConformanceMode>true</ConformanceMode>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+ <OptimizeReferences>true</OptimizeReferences>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+ <ClCompile>\r
+ <PrecompiledHeader>\r
+ </PrecompiledHeader>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <FunctionLevelLinking>true</FunctionLevelLinking>\r
+ <IntrinsicFunctions>true</IntrinsicFunctions>\r
+ <SDLCheck>true</SDLCheck>\r
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <ConformanceMode>true</ConformanceMode>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+ <OptimizeReferences>true</OptimizeReferences>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="AggregateInitializations.cpp" />\r
+ <ClCompile Include="Bind.cpp" />\r
+ <ClCompile Include="Concepts.cpp" />\r
+ <ClCompile Include="ConstexprIf.cpp" />\r
+ <ClCompile Include="CostOfUsingStatic.cpp" />\r
+ <ClCompile Include="DefaultMethods.cpp" />\r
+ <ClCompile Include="FoldExpressions.cpp" />\r
+ <ClCompile Include="FunctionsAsTemplate.cpp" />\r
+ <ClCompile Include="IfAndSwitchInitStatements.cpp" />\r
+ <ClCompile Include="Lambdas.cpp" />\r
+ <ClCompile Include="main.cpp" />\r
+ <ClCompile Include="NextAndExchange.cpp" />\r
+ <ClCompile Include="PointerToMember.cpp" />\r
+ <ClCompile Include="ReadVarint.cpp" />\r
+ <ClCompile Include="TemplateMetaProgramming.cpp" />\r
+ <ClCompile Include="Traits.cpp" />\r
+ <ClCompile Include="VariadicTemplates.cpp" />\r
+ <ClCompile Include="VariadicUsing.cpp" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="AggregateInitializations.h" />\r
+ <ClInclude Include="Bind.h" />\r
+ <ClInclude Include="Concepts.h" />\r
+ <ClInclude Include="ConstexprIf.h" />\r
+ <ClInclude Include="CostOfUsingStatic.h" />\r
+ <ClInclude Include="DefaultMethods.h" />\r
+ <ClInclude Include="FoldExpressions.h" />\r
+ <ClInclude Include="FunctionsAsTemplate.h" />\r
+ <ClInclude Include="IfAndSwitchInitStatements.h" />\r
+ <ClInclude Include="Lambdas.h" />\r
+ <ClInclude Include="NextAndExchange.h" />\r
+ <ClInclude Include="PointerToMember.h" />\r
+ <ClInclude Include="ReadVarint.h" />\r
+ <ClInclude Include="TemplateMetaProgramming.h" />\r
+ <ClInclude Include="Traits.h" />\r
+ <ClInclude Include="Types.h" />\r
+ <ClInclude Include="VariadicTemplates.h" />\r
+ <ClInclude Include="VariadicUsing.h" />\r
+ </ItemGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+ <ImportGroup Label="ExtensionTargets">\r
+ </ImportGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup>\r
+ <Filter Include="Source Files">\r
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+ </Filter>\r
+ <Filter Include="Header Files">\r
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>\r
+ </Filter>\r
+ <Filter Include="Resource Files">\r
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
+ </Filter>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="main.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="DefaultMethods.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="Traits.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="PointerToMember.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="FunctionsAsTemplate.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CostOfUsingStatic.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="TemplateMetaProgramming.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="NextAndExchange.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="Bind.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="ConstexprIf.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="FoldExpressions.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="IfAndSwitchInitStatements.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="AggregateInitializations.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="VariadicUsing.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="VariadicTemplates.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="Lambdas.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="ReadVarint.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="Concepts.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="DefaultMethods.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="Traits.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="PointerToMember.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="FunctionsAsTemplate.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="CostOfUsingStatic.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="TemplateMetaProgramming.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="Types.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="NextAndExchange.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="Bind.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="ConstexprIf.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="FoldExpressions.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="IfAndSwitchInitStatements.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="AggregateInitializations.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="VariadicUsing.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="VariadicTemplates.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="Lambdas.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="ReadVarint.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="Concepts.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ </ItemGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+#include "TemplateMetaProgramming.h"\r
+\r
+#include <iostream>\r
+#include <utility>\r
+#include <array>\r
+using namespace std;\r
+\r
+#include "Types.h"\r
+\r
+// See chapter 28 of "The C++ programming language".\r
+\r
+namespace TemplateMetaProgramming\r
+{\r
+ template<i64 I>\r
+ struct Fib\r
+ {\r
+ static const i64 val = Fib<I - 1>::val + Fib<I - 2>::val;\r
+ };\r
+\r
+ template<>\r
+ struct Fib<0>\r
+ {\r
+ static const i64 val = 0;\r
+ };\r
+\r
+ template<>\r
+ struct Fib<1>\r
+ {\r
+ static const i64 val = 1;\r
+ };\r
+\r
+ /////\r
+\r
+ template<i64 ... I>\r
+ i64 fib_impl(integer_sequence<i64, I...>, const i64 i)\r
+ {\r
+ constexpr array<i64, sizeof...(I)> a = { Fib<I>::val... };\r
+ return a[i];\r
+ }\r
+\r
+ i64 fib(const i64 i)\r
+ {\r
+ // Generate all fibonacci sequence from 0 to 80.\r
+ return fib_impl(make_integer_sequence<i64, 81>(), i);\r
+ }\r
+}\r
+\r
+void TemplateMetaProgramming::tests()\r
+{\r
+ constexpr i64 n = 80;\r
+ cout << "Compile time: fib(" << n << ") = " << Fib<n>::val << endl;\r
+\r
+ const i64 m = 80;\r
+ cout << "Run time: fib(" << m << ") = " << fib(m) << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace TemplateMetaProgramming\r
+{\r
+ void tests();\r
+}\r
+\r
--- /dev/null
+#include "Traits.h"\r
+\r
+#include <iostream>\r
+#include <type_traits>\r
+\r
+using namespace std;\r
+\r
+namespace Traits\r
+{\r
+ class C {};\r
+\r
+ /////\r
+\r
+ void algorithm_signed(int i) { /* [..] */ cout << "process a signed integer" << endl; }\r
+ void algorithm_unsigned(unsigned) { /* [..] */ cout << "process an unsigned integer" << endl; }\r
+\r
+ template <typename T>\r
+ void algorithm(T t)\r
+ {\r
+ if constexpr (is_signed<T>::value)\r
+ algorithm_signed(t);\r
+ else if constexpr (is_unsigned<T>::value)\r
+ algorithm_unsigned(t);\r
+ else\r
+ static_assert(is_signed<T>::value || is_unsigned<T>::value, "Must be signed or unsigned");\r
+ }\r
+\r
+ /////\r
+\r
+ template <typename T>\r
+ typename remove_reference<T>::type&& move(T&& arg)\r
+ {\r
+ return static_cast<typename remove_reference<T>::type&&>(arg);\r
+ }\r
+}\r
+\r
+void Traits::tests()\r
+{\r
+ cout << "Is the type 'C' a floating point?: " << is_floating_point<C>::value << endl;\r
+ cout << "Is the type 'float' a floating point?: " << is_floating_point<float>::value << endl;\r
+ cout << "Is the type 'int' a floating point?:" << is_floating_point<int>::value << endl;\r
+\r
+ algorithm(3);\r
+ algorithm(3U);\r
+ // algorithm("hello"); Do not compile.\r
+}\r
--- /dev/null
+#pragma once\r
+\r
+/*\r
+Type traits: conditional compilation based on generic type properties. Subset of template metaprogramming.\r
+\r
+From: https://www.internalpointers.com/post/quick-primer-type-traits-modern-cpp\r
+*/\r
+\r
+namespace Traits\r
+{\r
+ void tests();\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+using namespace std;\r
+\r
+using i64 = conditional_t<sizeof(long) == 8, long, long long>;
\ No newline at end of file
--- /dev/null
+#include "VariadicTemplates.h"\r
+\r
+#include <iostream>\r
+#include <vector>\r
+using namespace std;\r
+\r
+// Introduction to C++ Variadic Templates: https://kevinushey.github.io/blog/2016/01/27/introduction-to-c++-variadic-templates/\r
+// Using Variadic Templates cleanly: https://florianjw.de/en/variadic_templates.html\r
+// Variadic templates in C++ : https://eli.thegreenplace.net/2014/variadic-templates-in-c/\r
+\r
+namespace VariadicTemplates\r
+{\r
+ template <typename ... Ts> // Template parameter pack: multiple types (0 type can be given).\r
+ void ignore(Ts ... ts)\r
+ {\r
+ }\r
+\r
+ template <typename T>\r
+ double sum(T t)\r
+ {\r
+ return t;\r
+ }\r
+ template <typename T, typename ... Ts>\r
+ double sum(T t, Ts ... ts)\r
+ {\r
+ return t + sum(ts...);\r
+ }\r
+\r
+ template <typename T>\r
+ T square(T t)\r
+ {\r
+ return t * t;\r
+ }\r
+ template <typename T>\r
+ double power_sum(T t)\r
+ {\r
+ return t;\r
+ }\r
+ template <typename T, typename ... Ts>\r
+ double power_sum(T t, Ts ... ts)\r
+ {\r
+ return t + power_sum(square(ts)...);\r
+ }\r
+\r
+ /////\r
+\r
+ struct S\r
+ {\r
+ S(int a, double b)\r
+ : a(a), b(b)\r
+ {\r
+ cout << "Ctor" << endl;\r
+ }\r
+\r
+ S(const S& other)\r
+ : a(other.a), b(other.b)\r
+ {\r
+ cout << "Copy ctor" << endl;\r
+ }\r
+\r
+ // This move ctor isn't necessary because it does the same thing as the copy ctor.\r
+ S(S&& other) noexcept\r
+ : a(other.a), b(other.b)\r
+ {\r
+ cout << "Move ctor" << endl;\r
+ }\r
+\r
+ const int a;\r
+ const double b;\r
+ };\r
+\r
+ ostream& operator<<(ostream& os, const S& s)\r
+ {\r
+ os << "{ a = " << s.a << ", b = " << s.b << "}";\r
+ return os;\r
+ }\r
+\r
+ /////\r
+\r
+ template<typename ... Ts>\r
+ void ignore_return_values(Ts&&...) {}\r
+\r
+ template<typename ... Ts>\r
+ void increment_all(Ts& ... values)\r
+ {\r
+ ignore_return_values((++values)...);\r
+ }\r
+}\r
+\r
+void VariadicTemplates::tests()\r
+{\r
+ ignore(1, 2.0, true); // Types can be different.\r
+\r
+ cout << sum(1, 2, 3, 4) << endl;\r
+ cout << power_sum(1, 2, 3, 4) << endl;\r
+\r
+ /////\r
+\r
+ vector<S> v;\r
+ // 'emplace_back' use variadic template.\r
+ v.emplace_back(1, 1.5);\r
+ v.emplace_back(2, 1.6);\r
+ v.emplace_back(3, 1.7);\r
+\r
+ for (const auto& i : v)\r
+ cout << "element: " << i << endl;\r
+\r
+ /////\r
+\r
+ int i = 3;\r
+ double d = 4.5;\r
+ increment_all(i, d);\r
+ cout << i << ", " << d << endl;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace VariadicTemplates\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+#include "VariadicUsing.h"\r
+\r
+#include <iostream>\r
+using namespace std;\r
+\r
+// Ep 48: https://www.youtube.com/watch?v=1gNzhE-Tn40\r
+\r
+namespace VariadicUsing\r
+{\r
+ template<typename ... B>\r
+ struct Merged : B...\r
+ {\r
+ template<typename ... T>\r
+ Merged(T&& ... t) : B(forward<T>(t))...\r
+ {\r
+ }\r
+\r
+ using B::operator()...; // It seems not necessary.\r
+ };\r
+\r
+ // Class template argument deduction: https://en.cppreference.com/w/cpp/language/class_template_argument_deduction.\r
+ template<typename ... T>\r
+ Merged(T...) -> Merged<decay_t<T>...>;\r
+}\r
+\r
+void VariadicUsing::tests()\r
+{\r
+ // Lambda are standard type.\r
+ const auto l1 = []() { return 4; };\r
+ const auto l2 = [](const int i) { return i * 10; };\r
+\r
+ Merged merged(l1, l2, [](const double d) { return d * 3.2; });\r
+\r
+ cout << merged() << endl;\r
+ cout << merged(10) << endl;\r
+ cout << merged(10.5) << endl;\r
+}\r
--- /dev/null
+#pragma once\r
+\r
+namespace VariadicUsing\r
+{\r
+ void tests();\r
+};\r
+\r
--- /dev/null
+#include <iostream>\r
+#include <vector>\r
+#include <list>\r
+#include <chrono>\r
+using namespace std;\r
+\r
+#include "DefaultMethods.h"\r
+#include "Traits.h"\r
+#include "PointerToMember.h"\r
+#include "FunctionsAsTemplate.h"\r
+#include "CostOfUsingStatic.h"\r
+#include "TemplateMetaProgramming.h"\r
+#include "NextAndExchange.h"\r
+#include "Bind.h"\r
+#include "ConstexprIf.h"\r
+#include "FoldExpressions.h"\r
+#include "IfAndSwitchInitStatements.h"\r
+#include "AggregateInitializations.h"\r
+#include "VariadicUsing.h"\r
+#include "VariadicTemplates.h"\r
+#include "Lambdas.h"\r
+#include "ReadVarint.h"\r
+#include "Concepts.h"\r
+\r
+constexpr auto DEFAULT_METHODS_ENABLED = false;\r
+constexpr auto TRAITS_ENABLED = false;\r
+constexpr auto POINTER_TO_MEMBER = false;\r
+constexpr auto FUNCTIONS_AS_TEMPLATE = false;\r
+constexpr auto COST_OF_USING_STATIC = false;\r
+constexpr auto TEMPLATE_METAPROGRAMMING = false;\r
+constexpr auto NEXT_AND_EXCHANGE = false;\r
+constexpr auto BIND = false;\r
+constexpr auto CONSTEXPR_IF = false;\r
+constexpr auto FOLD_EXPRESSIONS = false;\r
+constexpr auto IF_AND_SWITCH_INIT_STATEMENTS = false;\r
+constexpr auto AGGREGATE_INITIALIZATIONS = false;\r
+constexpr auto VARIADIC_USING = false;\r
+constexpr auto VARIADIC_TEMPLATES = false;\r
+constexpr auto LAMBDAS = false;\r
+constexpr auto READ_VARINT = false;\r
+constexpr auto CONCEPTS = true;\r
+\r
+bool isLucky(int n)\r
+{\r
+ return n == 13;\r
+}\r
+\r
+// Forbid to be called with char or float (automatic conversion to 'int').\r
+bool isLucky(char) = delete;\r
+bool isLucky(double) = delete;\r
+\r
+struct Pod\r
+{\r
+ int a;\r
+ double b;\r
+};\r
+\r
+int main()\r
+{\r
+ // Do not forget that 'endl' call 'flush' as well. Never use 'endl' when writing a lot of data (into a file for example).\r
+ cout << "Sandbox C++" << endl;\r
+ cout << "-----------" << endl;\r
+\r
+ auto startTime = chrono::steady_clock::now();\r
+\r
+ if constexpr (DEFAULT_METHODS_ENABLED)\r
+ DefaultMethods::tests();\r
+\r
+ if constexpr (TRAITS_ENABLED)\r
+ Traits::tests();\r
+\r
+ if constexpr (POINTER_TO_MEMBER)\r
+ PointerToMember::tests();\r
+\r
+ if constexpr (FUNCTIONS_AS_TEMPLATE)\r
+ FunctionsAsTemplate::tests();\r
+\r
+ if constexpr (COST_OF_USING_STATIC)\r
+ CostOfUsingStatic::tests();\r
+\r
+ if constexpr (TEMPLATE_METAPROGRAMMING)\r
+ TemplateMetaProgramming::tests();\r
+\r
+ if constexpr (NEXT_AND_EXCHANGE)\r
+ NextAndExchange::tests();\r
+\r
+ if constexpr (BIND)\r
+ Bind::tests();\r
+\r
+ if constexpr (CONSTEXPR_IF)\r
+ ConstexprIf::tests();\r
+\r
+ if constexpr (FOLD_EXPRESSIONS)\r
+ FoldExpressions::tests();\r
+\r
+ if constexpr (IF_AND_SWITCH_INIT_STATEMENTS)\r
+ IfAndSwitchInitStatements::tests();\r
+\r
+ if constexpr (AGGREGATE_INITIALIZATIONS)\r
+ AggregateInitializations::tests();\r
+\r
+ if constexpr (VARIADIC_USING)\r
+ VariadicUsing::tests();\r
+\r
+ if constexpr (VARIADIC_TEMPLATES)\r
+ VariadicTemplates::tests();\r
+\r
+ if constexpr (LAMBDAS)\r
+ Lambdas::tests();\r
+\r
+ if constexpr (READ_VARINT)\r
+ ReadVarint::tests();\r
+\r
+ if constexpr (CONCEPTS)\r
+ Concepts::tests();\r
+\r
+ auto endTime = chrono::steady_clock::now();\r
+\r
+ cout << "-----------" << endl;\r
+ cout << "Elapsed time: " << chrono::duration_cast<chrono::milliseconds>(endTime - startTime).count() << " ms" << endl;\r
+\r
+ /*\r
+ cout << "Press ENTER to quit" << endl;\r
+ cin.ignore();\r
+ */\r
+}\r