First commit master
authorGreg Burri <greg.burri@gmail.com>
Wed, 20 Jan 2021 09:55:20 +0000 (10:55 +0100)
committerGreg Burri <greg.burri@gmail.com>
Wed, 20 Jan 2021 09:55:20 +0000 (10:55 +0100)
40 files changed:
.gitignore [new file with mode: 0644]
Sandbox.sln [new file with mode: 0644]
Sandbox/AggregateInitializations.cpp [new file with mode: 0644]
Sandbox/AggregateInitializations.h [new file with mode: 0644]
Sandbox/Bind.cpp [new file with mode: 0644]
Sandbox/Bind.h [new file with mode: 0644]
Sandbox/Concepts.cpp [new file with mode: 0644]
Sandbox/Concepts.h [new file with mode: 0644]
Sandbox/ConstexprIf.cpp [new file with mode: 0644]
Sandbox/ConstexprIf.h [new file with mode: 0644]
Sandbox/CostOfUsingStatic.cpp [new file with mode: 0644]
Sandbox/CostOfUsingStatic.h [new file with mode: 0644]
Sandbox/DefaultMethods.cpp [new file with mode: 0644]
Sandbox/DefaultMethods.h [new file with mode: 0644]
Sandbox/FoldExpressions.cpp [new file with mode: 0644]
Sandbox/FoldExpressions.h [new file with mode: 0644]
Sandbox/FunctionsAsTemplate.cpp [new file with mode: 0644]
Sandbox/FunctionsAsTemplate.h [new file with mode: 0644]
Sandbox/IfAndSwitchInitStatements.cpp [new file with mode: 0644]
Sandbox/IfAndSwitchInitStatements.h [new file with mode: 0644]
Sandbox/Lambdas.cpp [new file with mode: 0644]
Sandbox/Lambdas.h [new file with mode: 0644]
Sandbox/NextAndExchange.cpp [new file with mode: 0644]
Sandbox/NextAndExchange.h [new file with mode: 0644]
Sandbox/PointerToMember.cpp [new file with mode: 0644]
Sandbox/PointerToMember.h [new file with mode: 0644]
Sandbox/ReadVarint.cpp [new file with mode: 0644]
Sandbox/ReadVarint.h [new file with mode: 0644]
Sandbox/Sandbox.vcxproj [new file with mode: 0644]
Sandbox/Sandbox.vcxproj.filters [new file with mode: 0644]
Sandbox/TemplateMetaProgramming.cpp [new file with mode: 0644]
Sandbox/TemplateMetaProgramming.h [new file with mode: 0644]
Sandbox/Traits.cpp [new file with mode: 0644]
Sandbox/Traits.h [new file with mode: 0644]
Sandbox/Types.h [new file with mode: 0644]
Sandbox/VariadicTemplates.cpp [new file with mode: 0644]
Sandbox/VariadicTemplates.h [new file with mode: 0644]
Sandbox/VariadicUsing.cpp [new file with mode: 0644]
Sandbox/VariadicUsing.h [new file with mode: 0644]
Sandbox/main.cpp [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..1ee5385
--- /dev/null
@@ -0,0 +1,362 @@
+## 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
diff --git a/Sandbox.sln b/Sandbox.sln
new file mode 100644 (file)
index 0000000..7e1b256
--- /dev/null
@@ -0,0 +1,31 @@
+\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
diff --git a/Sandbox/AggregateInitializations.cpp b/Sandbox/AggregateInitializations.cpp
new file mode 100644 (file)
index 0000000..02be415
--- /dev/null
@@ -0,0 +1,25 @@
+#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
diff --git a/Sandbox/AggregateInitializations.h b/Sandbox/AggregateInitializations.h
new file mode 100644 (file)
index 0000000..48a939e
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once\r
+\r
+\r
+namespace AggregateInitializations\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/Bind.cpp b/Sandbox/Bind.cpp
new file mode 100644 (file)
index 0000000..0724834
--- /dev/null
@@ -0,0 +1,57 @@
+#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
diff --git a/Sandbox/Bind.h b/Sandbox/Bind.h
new file mode 100644 (file)
index 0000000..f62ce59
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace Bind\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/Concepts.cpp b/Sandbox/Concepts.cpp
new file mode 100644 (file)
index 0000000..3e75c9b
--- /dev/null
@@ -0,0 +1,67 @@
+#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
diff --git a/Sandbox/Concepts.h b/Sandbox/Concepts.h
new file mode 100644 (file)
index 0000000..84d756f
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace Concepts\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/ConstexprIf.cpp b/Sandbox/ConstexprIf.cpp
new file mode 100644 (file)
index 0000000..f34d090
--- /dev/null
@@ -0,0 +1,44 @@
+#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
diff --git a/Sandbox/ConstexprIf.h b/Sandbox/ConstexprIf.h
new file mode 100644 (file)
index 0000000..605228b
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace ConstexprIf\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/CostOfUsingStatic.cpp b/Sandbox/CostOfUsingStatic.cpp
new file mode 100644 (file)
index 0000000..d6134a1
--- /dev/null
@@ -0,0 +1,44 @@
+#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
diff --git a/Sandbox/CostOfUsingStatic.h b/Sandbox/CostOfUsingStatic.h
new file mode 100644 (file)
index 0000000..7492e15
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace CostOfUsingStatic\r
+{\r
+    void tests();\r
+}\r
+\r
diff --git a/Sandbox/DefaultMethods.cpp b/Sandbox/DefaultMethods.cpp
new file mode 100644 (file)
index 0000000..aea349c
--- /dev/null
@@ -0,0 +1,99 @@
+#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
diff --git a/Sandbox/DefaultMethods.h b/Sandbox/DefaultMethods.h
new file mode 100644 (file)
index 0000000..c7f5459
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once\r
+\r
+namespace DefaultMethods\r
+{\r
+    void tests();\r
+}\r
+\r
+\r
diff --git a/Sandbox/FoldExpressions.cpp b/Sandbox/FoldExpressions.cpp
new file mode 100644 (file)
index 0000000..01c861e
--- /dev/null
@@ -0,0 +1,42 @@
+#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
diff --git a/Sandbox/FoldExpressions.h b/Sandbox/FoldExpressions.h
new file mode 100644 (file)
index 0000000..68859f9
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace FoldExpressions\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/FunctionsAsTemplate.cpp b/Sandbox/FunctionsAsTemplate.cpp
new file mode 100644 (file)
index 0000000..efa13af
--- /dev/null
@@ -0,0 +1,34 @@
+#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
diff --git a/Sandbox/FunctionsAsTemplate.h b/Sandbox/FunctionsAsTemplate.h
new file mode 100644 (file)
index 0000000..53bb3ac
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace FunctionsAsTemplate\r
+{\r
+    void tests();\r
+}\r
+\r
diff --git a/Sandbox/IfAndSwitchInitStatements.cpp b/Sandbox/IfAndSwitchInitStatements.cpp
new file mode 100644 (file)
index 0000000..3217c83
--- /dev/null
@@ -0,0 +1,54 @@
+#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
diff --git a/Sandbox/IfAndSwitchInitStatements.h b/Sandbox/IfAndSwitchInitStatements.h
new file mode 100644 (file)
index 0000000..6b10980
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace IfAndSwitchInitStatements\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/Lambdas.cpp b/Sandbox/Lambdas.cpp
new file mode 100644 (file)
index 0000000..c7a265f
--- /dev/null
@@ -0,0 +1,124 @@
+#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
diff --git a/Sandbox/Lambdas.h b/Sandbox/Lambdas.h
new file mode 100644 (file)
index 0000000..d7ad8d7
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace Lambdas\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/NextAndExchange.cpp b/Sandbox/NextAndExchange.cpp
new file mode 100644 (file)
index 0000000..a08af8e
--- /dev/null
@@ -0,0 +1,23 @@
+#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
diff --git a/Sandbox/NextAndExchange.h b/Sandbox/NextAndExchange.h
new file mode 100644 (file)
index 0000000..192dc0d
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace NextAndExchange\r
+{\r
+    void tests();\r
+}\r
+\r
diff --git a/Sandbox/PointerToMember.cpp b/Sandbox/PointerToMember.cpp
new file mode 100644 (file)
index 0000000..35eb1f0
--- /dev/null
@@ -0,0 +1,33 @@
+#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
diff --git a/Sandbox/PointerToMember.h b/Sandbox/PointerToMember.h
new file mode 100644 (file)
index 0000000..5166cba
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace PointerToMember\r
+{\r
+    void tests();\r
+}\r
+\r
diff --git a/Sandbox/ReadVarint.cpp b/Sandbox/ReadVarint.cpp
new file mode 100644 (file)
index 0000000..52ebddd
--- /dev/null
@@ -0,0 +1,107 @@
+#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
diff --git a/Sandbox/ReadVarint.h b/Sandbox/ReadVarint.h
new file mode 100644 (file)
index 0000000..7479f30
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace ReadVarint\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/Sandbox.vcxproj b/Sandbox/Sandbox.vcxproj
new file mode 100644 (file)
index 0000000..ba3e26b
--- /dev/null
@@ -0,0 +1,194 @@
+<?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
diff --git a/Sandbox/Sandbox.vcxproj.filters b/Sandbox/Sandbox.vcxproj.filters
new file mode 100644 (file)
index 0000000..2e56606
--- /dev/null
@@ -0,0 +1,129 @@
+<?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
diff --git a/Sandbox/TemplateMetaProgramming.cpp b/Sandbox/TemplateMetaProgramming.cpp
new file mode 100644 (file)
index 0000000..a54fb3c
--- /dev/null
@@ -0,0 +1,55 @@
+#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
diff --git a/Sandbox/TemplateMetaProgramming.h b/Sandbox/TemplateMetaProgramming.h
new file mode 100644 (file)
index 0000000..1a68459
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace TemplateMetaProgramming\r
+{\r
+    void tests();\r
+}\r
+\r
diff --git a/Sandbox/Traits.cpp b/Sandbox/Traits.cpp
new file mode 100644 (file)
index 0000000..066138c
--- /dev/null
@@ -0,0 +1,46 @@
+#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
diff --git a/Sandbox/Traits.h b/Sandbox/Traits.h
new file mode 100644 (file)
index 0000000..41f7e74
--- /dev/null
@@ -0,0 +1,12 @@
+#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
diff --git a/Sandbox/Types.h b/Sandbox/Types.h
new file mode 100644 (file)
index 0000000..bac6e1f
--- /dev/null
@@ -0,0 +1,5 @@
+#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
diff --git a/Sandbox/VariadicTemplates.cpp b/Sandbox/VariadicTemplates.cpp
new file mode 100644 (file)
index 0000000..86bdef2
--- /dev/null
@@ -0,0 +1,114 @@
+#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
diff --git a/Sandbox/VariadicTemplates.h b/Sandbox/VariadicTemplates.h
new file mode 100644 (file)
index 0000000..232640b
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace VariadicTemplates\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/VariadicUsing.cpp b/Sandbox/VariadicUsing.cpp
new file mode 100644 (file)
index 0000000..b87884a
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/Sandbox/VariadicUsing.h b/Sandbox/VariadicUsing.h
new file mode 100644 (file)
index 0000000..7541dd3
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once\r
+\r
+namespace VariadicUsing\r
+{\r
+    void tests();\r
+};\r
+\r
diff --git a/Sandbox/main.cpp b/Sandbox/main.cpp
new file mode 100644 (file)
index 0000000..9ecb8e9
--- /dev/null
@@ -0,0 +1,126 @@
+#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