First commit
[cpp_sandbox.git] / Sandbox / Lambdas.cpp
1 #include "Lambdas.h"
2
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 #include <array>
7 #include <variant>
8 #include <algorithm>
9 using namespace std;
10
11 // Ep 32: https://www.youtube.com/watch?v=_CbBfuQQQI8
12 // Ep 37: https://www.youtube.com/watch?v=_1X9D8Z5huA
13 // Ep 40: https://www.youtube.com/watch?v=W-xTpqj31mI, not shown here, see 'VariadicUsing.cpp'.
14 // Ep 41: https://www.youtube.com/watch?v=kmza9U_niq4 (constexpr Lambda Support)
15 // Ep 49: https://www.youtube.com/watch?v=3wm5QzdddYc (Why Inherit From Lambdas?)
16
17 namespace Lambdas
18 {
19 // Identical to the lambda [](){ return 5; }.
20 struct Lambda
21 {
22 auto operator()() const
23 {
24 return 5;
25 }
26 };
27
28 /////
29
30 struct Color
31 {
32 uint8_t num;
33 uint8_t r;
34 uint8_t g;
35 uint8_t b;
36 double luma = 0.2126 * r + 0.7152 * g + 0.0722 * b;
37 };
38
39 ostream& operator<<(ostream& stream, const Color& color)
40 {
41 stream << "{ num = " << int(color.num) << ", r = " << int(color.r) << ", g = " << int(color.g) << ", b = " << int(color.b) << "}";
42 return stream;
43 }
44
45 template<typename Colors>
46 constexpr auto nearest_color(const Colors& colors, const uint8_t r, const uint8_t g, const uint8_t b)
47 {
48 return
49 *min_element(
50 begin(colors),
51 end(colors),
52 // Lambda in constexpr.
53 [r, g, b](const auto& lhs, const auto& rhs)
54 {
55 const auto square = [](auto t) { return t * t; };
56 return
57 square(lhs.r - r) + square(lhs.g - g) + square(lhs.b - b) <
58 square(rhs.r - r) + square(rhs.g - g) + square(rhs.b - b);
59 }
60 );
61 }
62
63 /////
64
65 // Merge types with subtyping.
66 template<typename ... B>
67 struct Visitor : B...
68 {
69 template<typename ... T>
70 Visitor(T&& ... t) : B(forward<T>(t))...
71 {
72 }
73 };
74
75 // Class template argument deduction: https://en.cppreference.com/w/cpp/language/class_template_argument_deduction
76 template<typename ... T>
77 Visitor(T...) -> Visitor<decay_t<T>...>;
78 }
79
80 void Lambdas::tests()
81 {
82 // Parameter parenthesis can be omitted.
83 cout << [] { return 5; }() << endl;
84
85 cout << "/////" << endl;
86 /////
87
88 // Stateful lambda as a fibonnacci sequence.
89 auto l = [i = 0, j = 1]() mutable
90 {
91 i = exchange(j, j + i);
92 return i;
93 };
94
95 for (int i = 0; i < 10; i++)
96 cout << l() << endl;
97
98 cout << "/////" << endl;
99 /////
100
101 vector<Color> colors{ Color { 1, 10, 50, 200 }, Color { 2, 40, 10, 100 } , Color { 3, 250, 0, 70 } };
102 auto c = nearest_color(colors, 20, 40, 60);
103 cout << "color: " << c << endl;
104
105 cout << "/////" << endl;
106 /////
107
108 // Array of doubles and ints.
109 const auto aString{ "XYZ"s };
110 array<variant<double, int, string>, 6> a{ "ABC", 13.2, 3, 6.8, aString, 7 };
111
112 int intTotal = 0;
113 double doubleTotal = 0.0;
114 string allStrings;
115 Visitor visitor{
116 [&intTotal](const int i) { intTotal += i; },
117 [&doubleTotal](const double d) { doubleTotal += d; },
118 [&allStrings](const string& s) { allStrings.append(s); }
119 };
120
121 for_each(begin(a), end(a), [&visitor](const auto& v) { visit(visitor, v); });
122
123 cout << "intTotal = " << intTotal << ", doubleTotal = " << doubleTotal << ", allStrings = " << allStrings << endl;
124 }