├── LICENSE
├── README.md
├── Section01
├── lambda_capturing_by_reference
│ └── lambda_capturing_by_reference.cpp
├── lambda_capturing_by_value
│ └── lambda_capturing_by_value.cpp
├── lambda_capturing_by_value_mutable
│ └── lambda_capturing_by_value_mutable.cpp
├── lambda_expression_generic
│ └── lambda_expression_generic.cpp
├── lambda_initialization_captures
│ └── lambda_initialization_captures.cpp
├── lambda_multiline_func
│ └── lambda_multiline_func.cpp
├── lambda_returning_value
│ └── lambda_returning_value.cpp
└── lambda_tiny_func
│ ├── lambda_tiny_func.cpp
│ ├── vehicle.cpp
│ └── vehicle.h
├── Section02
├── curry_1
│ └── curry_1.cpp
├── curry_2
│ └── curry_2.cpp
├── filter_1
│ └── filter_1.cpp
├── filter_2
│ └── filter_2.cpp
├── first_class_1
│ └── first_class_1.cpp
├── first_class_2
│ └── first_class_2.cpp
├── first_class_3
│ └── first_class_3.cpp
├── first_class_4
│ └── first_class_4.cpp
├── fold_1
│ └── fold_1.cpp
├── fold_2
│ └── fold_2.cpp
├── im_pure_function_1
│ └── im_pure_function_1.cpp
├── impure_function_1
│ └── impure_function_1.cpp
├── pure_function_1
│ └── pure_function_1.cpp
└── transform_1
│ └── transform_1.cpp
├── Section03
├── const
│ └── const.cpp
├── const_error
│ └── const_error.cpp
├── first_class_pure_immutable
│ └── first_class_pure_immutable.cpp
├── immutable_1
│ └── immutable_1.cpp
├── immutable_2
│ ├── a.out
│ └── immutable_2.cpp
├── immutable_3
│ └── immutable_3.cpp
├── immutableemployee
│ ├── immutableemployee.cpp
│ └── immutableemployee.h
├── mutable_1
│ └── mutable_1.cpp
├── mutable_2
│ └── mutable_2.cpp
├── mutable_2a
│ └── mutable_2a.cpp
├── mutable_3
│ └── mutable_3.cpp
└── mutableemployee
│ ├── mutableemployee.cpp
│ └── mutableemployee.h
├── Section04
├── exponential_iteration
│ └── exponential_iteration.cpp
├── exponential_recursion
│ └── exponential_recursion.cpp
├── factorial_iteration_do_while
│ └── factorial_iteration_do_while.cpp
├── factorial_iteration_for
│ └── factorial_iteration_for.cpp
├── factorial_recursion
│ └── factorial_recursion.cpp
├── factorial_recursion_tail
│ └── factorial_recursion_tail.cpp
├── fibonacci_iteration
│ └── fibonacci_iteration.cpp
├── fibonacci_recursion
│ └── fibonacci_recursion.cpp
├── labyrinth
│ └── labyrinth.cpp
├── permutation
│ └── permutation.cpp
├── tail_recursion
│ └── tail_recursion.cpp
└── tail_recursion_goto
│ └── tail_recursion_goto.cpp
├── Section05
├── delaying
│ ├── Code_Example1.cpp
│ └── delaying.cpp
├── delaying_non_pure
│ └── delaying_non_pure.cpp
├── delaying_non_pure_memoization
│ ├── Code_Example2.cpp
│ └── delaying_non_pure_memoization.cpp
├── non_strict
│ └── non_strict.cpp
├── prime
│ └── prime.cpp
└── strict
│ └── strict.cpp
└── Section06
├── Step01
├── Customer.cpp
├── Customer.h
└── Main.cpp
├── Step02
├── Customer.cpp
├── Customer.h
└── Main.cpp
├── Step03
├── Code_Example1.cpp
├── Code_Example2.cpp
├── Customer.cpp
├── Customer.h
└── Main.cpp
└── Step04
├── Code_Example1.cpp
├── Customer.cpp
├── Customer.h
└── Main.cpp
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Packt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Learning Modern C++ Functional Programming [Video]
2 | This is the code repository for [Learning Modern C++ Functional Programming [Video]](https://www.packtpub.com/application-development/learning-modern-c-functional-programming-video?utm_source=github&utm_medium=repository&utm_campaign=9781789348859), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the video course from start to finish.
3 | ## About the Video Course
4 | Functional programming allows developers to divide programs into smaller, reusable components that ease the creation, testing, and maintenance of software as a whole. Combined with the power of C++, you can develop robust and scalable applications that fulfil modern day software requirements. This course will help you discover all the C++ 17 features that can be applied to build software in a functional way.
5 |
6 | The course is divided into three modules—the first introduces the fundamentals of functional programming and how it is supported by modern C++. The second module explains how to efficiently implement C++ features such as pure functions and immutable states to build robust applications. The last module describes how to achieve concurrency and apply design patterns to enhance your application’s performance.
7 |
8 | By the end of the course, you will be familiar with the functional approach of programming and will be able to use these techniques on a daily basis.
9 |
10 | The course is divided into three modules—the first introduces the fundamentals of functional programming and how it is supported by modern C++. The second module explains how to efficiently implement C++ features such as pure functions and immutable states to build robust applications. The last module describes how to achieve concurrency and apply design patterns to enhance your application’s performance.
11 |
12 | By the end of the course, you will be familiar with the functional approach of programming and will be able to use these techniques on a daily basis.
13 |
14 |
What You Will Learn
15 |
16 |
17 | - Get to know the difference between imperative and functional approaches.
18 |
- See the use of first-class functions and pure functions in a functional style.
19 |
- Discover various techniques to apply immutable state to avoid side effects.
20 |
- Design a recursive algorithm effectively.
21 |
- Create faster programs using lazy evaluation.
22 |
- Learn how to use the C++ Standard Template Library in a functional way to improve code
23 | optimization.
24 |
25 | ## Instructions and Navigation
26 | ### Assumed Knowledge
27 | To fully benefit from the coverage included in this course, you will need:
28 | - This course is for C++ developers comfortable with OOP who are interested in learning how to apply the functional paradigm to create robust and testable apps
29 |
30 | ### Technical Requirements
31 | This course has the following software requirements:
32 | - The latest version of GCC, which supports C++11, C++14, and C++17
33 |
34 | ## Related Products
35 | * [Mastering Multithreading with C++ [Video]](https://www.packtpub.com/application-development/mastering-multithreading-c-video?utm_source=github&utm_medium=repository&utm_campaign=9781788836210)
36 |
37 | * [High Performance Applications with C++ [Video]](https://www.packtpub.com/application-development/high-performance-applications-c-video?utm_source=github&utm_medium=repository&utm_campaign=9781789136869)
38 |
39 | * [GUI Programming with C++ [Video]](https://www.packtpub.com/application-development/gui-programming-c-video?utm_source=github&utm_medium=repository&utm_campaign=9781789139464)
40 |
41 |
--------------------------------------------------------------------------------
/Section01/lambda_capturing_by_reference/lambda_capturing_by_reference.cpp:
--------------------------------------------------------------------------------
1 | /* lambda_capturing_by_reference.cpp */
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | auto main() -> int
9 | {
10 | cout << "[lambda_capturing_by_reference.cpp]" << endl;
11 |
12 | vector vect;
13 | for (int i = 0; i < 10; ++i)
14 | vect.push_back(i);
15 |
16 | cout << "Original Data:" << endl;
17 | for_each(
18 | begin(vect),
19 | end(vect),
20 | [](int n){
21 | cout << n << " ";
22 | });
23 | cout << endl;
24 |
25 | int a = 1;
26 | int b = 1;
27 |
28 | for_each(
29 | begin(vect),
30 | end(vect),
31 | [&a, &b](int& x){
32 | const int old = x;
33 | x *= 2;
34 | a = b;
35 | b = old;
36 | });
37 |
38 | cout << "Squared Data:" << endl;
39 | for_each(
40 | begin(vect),
41 | end(vect),
42 | [](int n) {
43 | cout << n << " ";
44 | });
45 | cout << endl << endl;
46 |
47 | cout << "a = " << a << endl;
48 | cout << "b = " << b << endl;
49 |
50 | return 0;
51 | }
52 |
--------------------------------------------------------------------------------
/Section01/lambda_capturing_by_value/lambda_capturing_by_value.cpp:
--------------------------------------------------------------------------------
1 | /* lambda_capturing_by_value.cpp */
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | auto main() -> int
9 | {
10 | cout << "[lambda_capturing_by_value.cpp]" << endl;
11 |
12 | vector vect;
13 | for (int i = 0; i < 10; ++i)
14 | vect.push_back(i);
15 |
16 | cout << "Original Data:" << endl;
17 | for_each(
18 | begin(vect),
19 | end(vect),
20 | [](int n){
21 | cout << n << " ";
22 | });
23 | cout << endl;
24 |
25 | int a = 2;
26 | int b = 8;
27 |
28 | cout << "Printing elements between " << a;
29 | cout << " and " << b << " explicitly [a,b]:" << endl;
30 | for_each(
31 | begin(vect),
32 | end(vect),
33 | [a,b](int n){
34 | if (n >= a && n <= b)
35 | cout << n << " ";
36 | });
37 | cout << endl;
38 |
39 | a = 3;
40 | b = 7;
41 |
42 | cout << "printing elements between " << a;
43 | cout << " and " << b << " implicitly[=]:" << endl;
44 | for_each(
45 | begin(vect),
46 | end(vect),
47 | [=](int n){
48 | if (n >= a && n <= b)
49 | cout << n << " ";
50 | });
51 | cout << endl;
52 |
53 | return 0;
54 | }
55 |
--------------------------------------------------------------------------------
/Section01/lambda_capturing_by_value_mutable/lambda_capturing_by_value_mutable.cpp:
--------------------------------------------------------------------------------
1 | /* lambda_capturing_by_value_mutable.cpp */
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | auto main() -> int
9 | {
10 | cout << "[lambda_capturing_by_value_mutable.cpp]" << endl;
11 |
12 | vector vect;
13 | for (int i = 0; i < 10; ++i)
14 | vect.push_back(i);
15 |
16 | cout << "Original Data:" << endl;
17 | for_each(
18 | begin(vect),
19 | end(vect),
20 | [](int n){
21 | cout << n << " ";
22 | });
23 | cout << endl;
24 |
25 | int a = 1;
26 | int b = 1;
27 |
28 | for_each(
29 | begin(vect),
30 | end(vect),
31 | [=](int& x) mutable {
32 | const int old = x;
33 | x *= 2;
34 | a = b;
35 | b = old;
36 | });
37 |
38 | cout << "Squared Data:" << endl;
39 | for_each(
40 | begin(vect),
41 | end(vect),
42 | [](int n) {
43 | cout << n << " ";
44 | });
45 | cout << endl << endl;
46 |
47 | cout << "a = " << a << endl;
48 | cout << "b = " << b << endl;
49 |
50 | return 0;
51 | }
52 |
--------------------------------------------------------------------------------
/Section01/lambda_expression_generic/lambda_expression_generic.cpp:
--------------------------------------------------------------------------------
1 | /* lambda_expression_generic.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | auto main() -> int
7 | {
8 | cout << "[lambda_capturing_by_reference.cpp]" << endl;
9 |
10 | auto findMax = [](auto &x, auto &y){
11 | return x > y ? x : y; };
12 |
13 | int i1 = 5, i2 = 3;
14 | float f1 = 2.5f, f2 = 2.05f;
15 |
16 | cout << "i1 = 5, i2 = 3" << endl;
17 | cout << "Max: " << findMax(i1, i2) << endl << endl;
18 |
19 | cout << "f1 = 2.5f, f2 = 2.05f" << endl;
20 | cout << "Max: " << findMax(f1, f2) << endl << endl;
21 |
22 | return 0;
23 | }
24 |
--------------------------------------------------------------------------------
/Section01/lambda_initialization_captures/lambda_initialization_captures.cpp:
--------------------------------------------------------------------------------
1 | /* lambda_initialization_captures.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | auto main() -> int
7 | {
8 | cout << "[lambda_initialization_captures.cpp]" << endl;
9 |
10 | int a = 5;
11 | cout << "Initial a = " << a << endl;
12 |
13 | auto myLambda = [&x = a]() { x += 2; };
14 |
15 | myLambda();
16 |
17 | cout << "New a = " << a << endl;
18 |
19 | return 0;
20 | }
21 |
--------------------------------------------------------------------------------
/Section01/lambda_multiline_func/lambda_multiline_func.cpp:
--------------------------------------------------------------------------------
1 | /* lambda_multiline_func.cpp */
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | auto main() -> int
9 | {
10 | cout << "[lambda_multiline_func.cpp]" << endl;
11 |
12 | vector vect;
13 | for (int i = 0; i < 10; ++i)
14 | vect.push_back(i);
15 |
16 | for_each(
17 | begin(vect),
18 | end(vect),
19 | [](int n) {
20 | cout << n << " is";
21 | if(n < 2)
22 | {
23 | if(n == 0)
24 | cout << " not";
25 | }
26 | else
27 | {
28 | for (int j = 2; j < n; ++j)
29 | {
30 | if (n % j == 0)
31 | {
32 | cout << " not";
33 | break;
34 | }
35 | }
36 | }
37 | cout << " prime number" << endl;
38 | });
39 |
40 | return 0;
41 | }
42 |
--------------------------------------------------------------------------------
/Section01/lambda_returning_value/lambda_returning_value.cpp:
--------------------------------------------------------------------------------
1 | /* lambda_returning_value.cpp */
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | auto main() -> int
9 | {
10 | cout << "[lambda_returning_value.cpp]" << endl;
11 |
12 | vector vect;
13 | for (int i = 0; i < 10; ++i)
14 | vect.push_back(i);
15 |
16 | cout << "Original Data:" << endl;
17 | for_each(
18 | begin(vect),
19 | end(vect),
20 | [](int n){
21 | cout << n << " ";
22 | });
23 | cout << endl;
24 |
25 | vector vect2;
26 |
27 | vect2.resize(vect.size());
28 |
29 | transform(
30 | begin(vect),
31 | end(vect),
32 | begin(vect2),
33 | [](int n) {
34 | return n * n;
35 | });
36 |
37 | cout << "Squared Data:" << endl;
38 | for_each(
39 | begin(vect2),
40 | end(vect2),
41 | [](int n) {
42 | cout << n << " ";
43 | });
44 | cout << endl;
45 |
46 | vector vect3;
47 |
48 | vect3.resize(vect.size());
49 |
50 | transform(
51 | begin(vect2),
52 | end(vect2),
53 | begin(vect3),
54 | [](int n) -> double {
55 | return n / 2.0;
56 | });
57 |
58 | cout << "Average Data:" << endl;
59 | for_each(
60 | begin(vect3),
61 | end(vect3),
62 | [](double d) {
63 | cout << d << " ";
64 | });
65 | cout << endl;
66 |
67 | return 0;
68 | }
69 |
--------------------------------------------------------------------------------
/Section01/lambda_tiny_func/lambda_tiny_func.cpp:
--------------------------------------------------------------------------------
1 | /* lambda_tiny_func.cpp */
2 | #include
3 | #include
4 | #include
5 | #include "vehicle.h"
6 |
7 | using namespace std;
8 |
9 | auto main() -> int
10 | {
11 | cout << "[lambda_tiny_func.cpp]" << endl;
12 |
13 | Vehicle car("car", 4);
14 | Vehicle motorcycle("motorcycle", 2);
15 | Vehicle bicycle("bicycle", 2);
16 | Vehicle bus("bus", 6);
17 |
18 | vector vehicles = { car, motorcycle, bicycle, bus };
19 |
20 | cout << "All vehicles:" << endl;
21 | for_each(
22 | begin(vehicles),
23 | end(vehicles),
24 | [](const Vehicle &vehicle){
25 | cout << vehicle.GetType() << endl;
26 | });
27 |
28 | return 0;
29 | }
30 |
--------------------------------------------------------------------------------
/Section01/lambda_tiny_func/vehicle.cpp:
--------------------------------------------------------------------------------
1 | #include "vehicle.h"
2 |
3 | using namespace std;
4 |
5 | Vehicle::Vehicle() : m_vehicleType("two-wheeler"),m_totalOfWheel(0)
6 | {
7 | }
8 |
9 | Vehicle::Vehicle(
10 | const string &type,
11 | int wheel) :
12 | m_vehicleType(type),
13 | m_totalOfWheel(wheel)
14 | {
15 | }
16 |
17 | Vehicle::~Vehicle()
18 | {
19 | }
20 |
--------------------------------------------------------------------------------
/Section01/lambda_tiny_func/vehicle.h:
--------------------------------------------------------------------------------
1 | #ifndef __VEHICLE_H__
2 | #define __VEHICLE_H__
3 |
4 | #include
5 |
6 | class Vehicle
7 | {
8 | private:
9 | std::string m_vehicleType;
10 | int m_totalOfWheel;
11 |
12 | public:
13 | Vehicle(
14 | const std::string &type,
15 | int wheel);
16 | Vehicle();
17 | ~Vehicle();
18 |
19 | std::string GetType() const {return m_vehicleType;}
20 | int GetNumOfWheel() const {return m_totalOfWheel;}
21 | };
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/Section02/curry_1/curry_1.cpp:
--------------------------------------------------------------------------------
1 | /* curry_1.cpp */
2 |
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | template
9 | auto curry(Func func, Args... args)
10 | {
11 | return [=](auto... lastParam)
12 | {
13 | return func(args..., lastParam...);
14 | };
15 | }
16 |
17 | int areaOfRectangle(int length, int width)
18 | {
19 | return length * width;
20 | }
21 |
22 | auto main() -> int
23 | {
24 | cout << "[curry_1.cpp]" << endl;
25 |
26 | auto length5 = curry(areaOfRectangle, 5);
27 |
28 | cout << "Curried with specific length = 5" << endl;
29 | for(int i = 0; i <= 5; ++i)
30 | {
31 | cout << "length5(" << i << ") = ";
32 | cout << length5(i) << endl;
33 | }
34 |
35 | return 0;
36 | }
37 |
--------------------------------------------------------------------------------
/Section02/curry_2/curry_2.cpp:
--------------------------------------------------------------------------------
1 | /* curry_2.cpp */
2 |
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | template
9 | auto curry(Func func, Args... args)
10 | {
11 | return [=](auto... lastParam)
12 | {
13 | return func(args..., lastParam...);
14 | };
15 | }
16 |
17 | int volumeOfRectangular(
18 | int length,
19 | int width,
20 | int height)
21 | {
22 | return length * width * height;
23 | }
24 |
25 | auto main() -> int
26 | {
27 | cout << "[curry_2.cpp]" << endl;
28 |
29 | auto length5width4 = curry(volumeOfRectangular, 5, 4);
30 |
31 | cout << "Curried with specific data:" << endl;
32 | cout << "length = 5, width 4" << endl;
33 | for(int i = 0; i <= 5; ++i)
34 | {
35 | cout << "length5width4(" << i << ") = ";
36 | cout << length5width4(i) << endl;
37 | }
38 |
39 | return 0;
40 | }
41 |
--------------------------------------------------------------------------------
/Section02/filter_1/filter_1.cpp:
--------------------------------------------------------------------------------
1 | /* filter_1.cpp */
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | using namespace std;
8 |
9 | auto main() -> int
10 | {
11 | cout << "[filter_1.cpp]" << endl;
12 |
13 | // Initializing a vector containing integer elements
14 | vector numbers;
15 | for (int i = 0; i < 20; ++i)
16 | numbers.push_back(i);
17 |
18 | // Displaying the elements of numbers
19 | cout << "The original numbers: " << endl;
20 | copy(
21 | begin(numbers),
22 | end(numbers),
23 | ostream_iterator(cout, " "));
24 | cout << endl;
25 |
26 | // Declaring a vector containing int elements
27 | vector primes;
28 |
29 | // Filtering the vector
30 | copy_if(
31 | begin(numbers),
32 | end(numbers),
33 | back_inserter(primes),
34 | [](int n) {
35 | if(n < 2) {
36 | return (n != 0) ? true : false;}
37 | else {
38 | for (int j = 2; j < n; ++j) {
39 | if (n % j == 0){
40 | return false;}
41 | }
42 |
43 | return true;
44 | }});
45 |
46 | // Displaying the elements of primes
47 | // using copy() function
48 | cout << "The primes numbers: " << endl;
49 | copy(
50 | begin(primes),
51 | end(primes),
52 | ostream_iterator(cout, " "));
53 | cout << endl;
54 |
55 | return 0;
56 | }
57 |
--------------------------------------------------------------------------------
/Section02/filter_2/filter_2.cpp:
--------------------------------------------------------------------------------
1 | /* filter_2.cpp */
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | using namespace std;
8 |
9 | int main()
10 | {
11 | cout << "[filter_2.cpp]" << endl;
12 |
13 | // Initializing a vector containing integer elements
14 | vector numbers;
15 | for (int i = 0; i < 20; ++i)
16 | numbers.push_back(i);
17 |
18 | // Displaying the elements of numbers
19 | cout << "The original numbers: " << endl;
20 | copy(
21 | begin(numbers),
22 | end(numbers),
23 | ostream_iterator(cout, " "));
24 | cout << endl;
25 |
26 | // Declaring a vector containing int elements
27 | vector nonPrimes;
28 |
29 | // Filtering the vector
30 | remove_copy_if(
31 | numbers.begin(),
32 | numbers.end(),
33 | back_inserter(nonPrimes),
34 | [](int n) {
35 | if(n < 2){
36 | return (n != 0) ? true : false;}
37 | else {
38 | for (int j = 2; j < n; ++j){
39 | if (n % j == 0) {
40 | return false;}
41 | }
42 |
43 | return true;
44 | }});
45 |
46 | // Displaying the elements of nonPrimes
47 | // using copy() function
48 | cout << "The non-primes numbers: " << endl;
49 | copy(
50 | begin(nonPrimes),
51 | end(nonPrimes),
52 | ostream_iterator(cout, " "));
53 | cout << endl;
54 |
55 | return 0;
56 | }
57 |
--------------------------------------------------------------------------------
/Section02/first_class_1/first_class_1.cpp:
--------------------------------------------------------------------------------
1 | /* first_class_1.cpp */
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | typedef function FuncType;
8 |
9 | int addition(int x, int y)
10 | {
11 | return x + y;
12 | }
13 |
14 | int subtraction(int x, int y)
15 | {
16 | return x - y;
17 | }
18 |
19 | int multiplication(int x, int y)
20 | {
21 | return x * y;
22 | }
23 |
24 | int division(int x, int y)
25 | {
26 | return x / y;
27 | }
28 |
29 | void PassingFunc(
30 | FuncType fn, int x, int y)
31 | {
32 | cout << "Result = " << fn(x, y) << endl;
33 | }
34 |
35 | auto main() -> int
36 | {
37 | cout << "[first_class_1.cpp]" << endl;
38 |
39 | int i, a, b;
40 | FuncType func;
41 |
42 | cout << "Select mode:" << endl;
43 | cout << "1. Addition" << endl;
44 | cout << "2. Subtraction" << endl;
45 | cout << "3. Multiplication" << endl;
46 | cout << "4. Division" << endl;
47 | cout << "Choice: ";
48 | cin >> i;
49 |
50 | if(i < 1 || i > 4)
51 | {
52 | cout << "Please select available mode!";
53 | return 1;
54 | }
55 |
56 | cout << "a -> ";
57 | cin >> a;
58 |
59 | while (cin.fail())
60 | {
61 |
62 | cin.clear();
63 |
64 | cin.ignore(INT8_MAX, '\n');
65 |
66 | cout << "You can only enter numbers.\n";
67 | cout << "Enter a number for variable a -> ";
68 | cin >> a;
69 | }
70 |
71 | cout << "b -> ";
72 | cin >> b;
73 |
74 | while (cin.fail())
75 | {
76 |
77 | cin.clear();
78 |
79 | cin.ignore(INT8_MAX, '\n');
80 |
81 | cout << "You can only enter numbers.\n";
82 | cout << "Enter a number for variable b -> ";
83 | cin >> b;
84 | }
85 |
86 | switch(i)
87 | {
88 | case 1: PassingFunc(addition, a, b); break;
89 | case 2: PassingFunc(subtraction, a, b); break;
90 | case 3: PassingFunc(multiplication, a, b); break;
91 | case 4: PassingFunc(division, a, b); break;
92 | }
93 |
94 | return 0;
95 | }
96 |
--------------------------------------------------------------------------------
/Section02/first_class_2/first_class_2.cpp:
--------------------------------------------------------------------------------
1 | /* first_class_2.cpp */
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | typedef function FuncType;
8 |
9 | int addition(int x, int y)
10 | {
11 | return x + y;
12 | }
13 |
14 | int subtraction(int x, int y)
15 | {
16 | return x - y;
17 | }
18 |
19 | int multiplication(int x, int y)
20 | {
21 | return x * y;
22 | }
23 |
24 | int division(int x, int y)
25 | {
26 | return x / y;
27 | }
28 |
29 | auto main() -> int
30 | {
31 | cout << "[first_class_2.cpp]" << endl;
32 |
33 | int i, a, b;
34 | FuncType func;
35 |
36 | cout << "Select mode:" << endl;
37 | cout << "1. Addition" << endl;
38 | cout << "2. Subtraction" << endl;
39 | cout << "3. Multiplication" << endl;
40 | cout << "4. Division" << endl;
41 | cout << "Choice: ";
42 | cin >> i;
43 |
44 | if(i < 1 || i > 4)
45 | {
46 | cout << "Please select available mode!";
47 | return 1;
48 | }
49 |
50 | cout << "a -> ";
51 | cin >> a;
52 |
53 | while (cin.fail())
54 | {
55 |
56 | cin.clear();
57 |
58 | cin.ignore(INT8_MAX, '\n');
59 |
60 | cout << "You can only enter numbers.\n";
61 | cout << "Enter a number for variable a -> ";
62 | cin >> a;
63 | }
64 |
65 | cout << "b -> ";
66 | cin >> b;
67 |
68 | while (cin.fail())
69 | {
70 |
71 | cin.clear();
72 |
73 | cin.ignore(INT8_MAX, '\n');
74 |
75 | cout << "You can only enter numbers.\n";
76 | cout << "Enter a number for variable b -> ";
77 | cin >> b;
78 | }
79 |
80 | switch(i)
81 | {
82 | case 1: func = addition; break;
83 | case 2: func = subtraction; break;
84 | case 3: func = multiplication; break;
85 | case 4: func = division; break;
86 | }
87 |
88 | cout << "Result = " << func(a, b) << endl;
89 |
90 | return 0;
91 | }
92 |
--------------------------------------------------------------------------------
/Section02/first_class_3/first_class_3.cpp:
--------------------------------------------------------------------------------
1 | /* first_class_3.cpp */
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | typedef function FuncType;
9 |
10 | int addition(int x, int y)
11 | {
12 | return x + y;
13 | }
14 |
15 | int subtraction(int x, int y)
16 | {
17 | return x - y;
18 | }
19 |
20 | int multiplication(int x, int y)
21 | {
22 | return x * y;
23 | }
24 |
25 | int division(int x, int y)
26 | {
27 | return x / y;
28 | }
29 |
30 | auto main() -> int
31 | {
32 | cout << "[first_class_3.cpp]" << endl;
33 |
34 | vector functions;
35 |
36 | functions.push_back(addition);
37 | functions.push_back(subtraction);
38 | functions.push_back(multiplication);
39 | functions.push_back(division);
40 |
41 | int i, a, b;
42 | function func;
43 |
44 | cout << "Select mode:" << endl;
45 | cout << "1. Addition" << endl;
46 | cout << "2. Subtraction" << endl;
47 | cout << "3. Multiplication" << endl;
48 | cout << "4. Division" << endl;
49 | cout << "Choice: ";
50 | cin >> i;
51 |
52 | if(i < 1 || i > 4)
53 | {
54 | cout << "Please select available mode!";
55 | return 1;
56 | }
57 |
58 | cout << "a -> ";
59 | cin >> a;
60 |
61 | while (cin.fail())
62 | {
63 |
64 | cin.clear();
65 |
66 | cin.ignore(INT8_MAX, '\n');
67 |
68 | cout << "You can only enter numbers.\n";
69 | cout << "Enter a number for variable a -> ";
70 | cin >> a;
71 | }
72 |
73 | cout << "b -> ";
74 | cin >> b;
75 |
76 | while (cin.fail())
77 | {
78 |
79 | cin.clear();
80 |
81 | cin.ignore(INT8_MAX, '\n');
82 |
83 | cout << "You can only enter numbers.\n";
84 | cout << "Enter a number for variable b -> ";
85 | cin >> b;
86 | }
87 |
88 | cout << "Result = " << functions.at(i - 1)(a, b) << endl;
89 |
90 | return 0;
91 | }
92 |
--------------------------------------------------------------------------------
/Section02/first_class_4/first_class_4.cpp:
--------------------------------------------------------------------------------
1 | /* first_class_4.cpp */
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | using std::vector;
9 | using std::function;
10 | using std::transform;
11 | using std::back_inserter;
12 | using std::cout;
13 | using std::endl;
14 |
15 | typedef function HyperbolicFunc;
16 |
17 | vector funcs = {
18 | sinh,
19 | cosh,
20 | tanh,
21 | [](double x) {
22 | return x*x; }
23 | };
24 |
25 | vector inverseFuncs = {
26 | asinh,
27 | acosh,
28 | atanh,
29 | [](double x) {
30 | return exp(log(x)/2); }
31 | };
32 |
33 | template
34 | function compose(
35 | function f,
36 | function g) {
37 | return [f,g](A x) {
38 | return f(g(x));
39 | };
40 | }
41 |
42 | auto main() -> int
43 | {
44 | cout << "[first_class_4.cpp]" << endl;
45 |
46 | vector composedFuncs;
47 |
48 | vector nums;
49 | for (int i = 1; i <= 5; ++i)
50 | nums.push_back(i * 0.2);
51 |
52 | transform(
53 | begin(inverseFuncs),
54 | end(inverseFuncs),
55 | begin(funcs),
56 | back_inserter(composedFuncs),
57 | compose);
58 |
59 | for (auto num: nums)
60 | {
61 | for (auto func: composedFuncs)
62 | cout << "f(g(" << num << ")) = " << func(num) << endl;
63 |
64 | cout << "---------------" << endl;
65 | }
66 |
67 | return 0;
68 | }
69 |
--------------------------------------------------------------------------------
/Section02/fold_1/fold_1.cpp:
--------------------------------------------------------------------------------
1 | /* fold_1.cpp */
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | using namespace std;
8 |
9 | auto main() -> int
10 | {
11 | cout << "[fold_1.cpp]" << endl;
12 |
13 | // Initializing a vector containing integer elements
14 | vector numbers = {0, 1, 2, 3, 4};
15 |
16 | // Calculating the sum of the value
17 | // in the vector
18 | auto foldl = accumulate(
19 | begin(numbers),
20 | end(numbers),
21 | 0,
22 | std::plus());
23 |
24 | // Calculating the sum of the value
25 | // in the vector
26 | auto foldr = accumulate(
27 | rbegin(numbers),
28 | rend(numbers),
29 | 0,
30 | std::plus());
31 |
32 | // Displaying the calculating result
33 | cout << "foldl result = " << foldl << endl;
34 | cout << "foldr result = " << foldr << endl;
35 |
36 | return 0;
37 | }
38 |
--------------------------------------------------------------------------------
/Section02/fold_2/fold_2.cpp:
--------------------------------------------------------------------------------
1 | /* fold_2.cpp */
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | using namespace std;
8 |
9 | // Function for logging the flow
10 | int addition(const int& x, const int& y)
11 | {
12 | cout << x << " + " << y << endl;
13 | return x + y;
14 | }
15 |
16 | auto main() -> int
17 | {
18 | cout << "[fold_2.cpp]" << endl;
19 |
20 | // Initializing a vector containing integer elements
21 | vector numbers = {0, 1, 2, 3, 4};
22 |
23 | // Calculating the sum of the value
24 | // in the vector
25 | // from left to right
26 | cout << "foldl" << endl;
27 | auto foldl = accumulate(
28 | begin(numbers),
29 | end(numbers),
30 | 0,
31 | addition);
32 |
33 | // Calculating the sum of the value
34 | // in the vector
35 | // from right to left
36 | cout << endl << "foldr" << endl;
37 | auto foldr = accumulate(
38 | rbegin(numbers),
39 | rend(numbers),
40 | 0,
41 | addition);
42 |
43 | cout << endl;
44 |
45 | // Displaying the calculating result
46 | cout << "foldl result = " << foldl << endl;
47 | cout << "foldr result = " << foldr << endl;
48 |
49 | return 0;
50 | }
51 |
--------------------------------------------------------------------------------
/Section02/im_pure_function_1/im_pure_function_1.cpp:
--------------------------------------------------------------------------------
1 | /* im_pure_function_1.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | // Initializing a global variable
7 | float phi = 3.14f;
8 |
9 | float circleArea(float r)
10 | {
11 | return phi * r * r;
12 | }
13 |
14 | auto main() -> int
15 | {
16 | cout << "[im_pure_function_1.cpp]" << endl;
17 |
18 | // Initializing a float variable
19 | float f = 2.5f;
20 |
21 | // Involving the global variable
22 | // in the calculation
23 | for(int i = 1; i <= 5; ++i)
24 | {
25 | cout << "Invocation " << i << " -> ";
26 | cout << "Result of circleArea(" << f << ") = ";
27 | cout << circleArea(f) << endl;
28 | }
29 |
30 | return 0;
31 | }
32 |
--------------------------------------------------------------------------------
/Section02/impure_function_1/impure_function_1.cpp:
--------------------------------------------------------------------------------
1 | /* impure_function_1.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | // Initializing a global variable
7 | int currentState = 0;
8 |
9 | int increment(int i)
10 | {
11 | currentState += i;
12 | return currentState;
13 | }
14 |
15 | auto main() -> int
16 | {
17 | cout << "[impure_function_1.cpp]" << endl;
18 |
19 | // Initializing a local variable
20 | int fix = 5;
21 |
22 | // Involving the global variable
23 | // in the calculation
24 | for(int i = 1; i <= 5; ++i)
25 | {
26 | cout << "Invocation " << i << " -> ";
27 | cout << "Result of increment(" << fix << ") = ";
28 | cout << increment(fix) << endl;
29 | }
30 |
31 | return 0;
32 | }
33 |
--------------------------------------------------------------------------------
/Section02/pure_function_1/pure_function_1.cpp:
--------------------------------------------------------------------------------
1 | /* pure_function_1.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | float circleArea(float r)
7 | {
8 | return 3.14 * r * r;
9 | }
10 |
11 | auto main() -> int
12 | {
13 | cout << "[pure_function_1.cpp]" << endl;
14 |
15 | // Initializing a float variable
16 | float f = 2.5f;
17 |
18 | // Invoking the circleArea() function
19 | // passing the f variable five times
20 | for(int i = 1; i <= 5; ++i)
21 | {
22 | cout << "Invocation " << i << " -> ";
23 | cout << "Result of circleArea(" << f << ") = ";
24 | cout << circleArea(f) << endl;
25 | }
26 |
27 | return 0;
28 | }
29 |
--------------------------------------------------------------------------------
/Section02/transform_1/transform_1.cpp:
--------------------------------------------------------------------------------
1 | /* transform_1.cpp */
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | auto main() -> int
9 | {
10 | cout << "[transform_1.cpp]" << endl;
11 |
12 | // Initializing a vector containing integer elements
13 | vector v1;
14 | for (int i = 0; i < 5; ++i)
15 | v1.push_back(i);
16 |
17 | // Creating another v2 vector
18 | vector v2;
19 | // Resizing the size of v2 exactly same with v1
20 | v2.resize(v1.size());
21 |
22 | // Transforming the element inside the vector
23 | transform (
24 | begin(v1),
25 | end(v1),
26 | begin(v2),
27 | [](int i){
28 | return i * i;});
29 |
30 | // Displaying the elements of v1
31 | std::cout << "v1 contains:";
32 | for (auto v : v1)
33 | std::cout << " " << v;
34 | std::cout << endl;
35 |
36 | // Displaying the elements of v2
37 | std::cout << "v2 contains:";
38 | for (auto v : v2)
39 | std::cout << " " << v;
40 | std::cout << endl;
41 |
42 | return 0;
43 | }
44 |
--------------------------------------------------------------------------------
/Section03/const/const.cpp:
--------------------------------------------------------------------------------
1 | /* const.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | class MyAge
7 | {
8 | public:
9 | const int age;
10 | MyAge(const int initAge = 20) :
11 | age(initAge)
12 | {
13 | }
14 | };
15 |
16 | auto main() -> int
17 | {
18 | cout << "[const.cpp]" << endl;
19 |
20 | MyAge AgeNow, AgeLater(28);
21 |
22 | cout << "My current age is ";
23 | cout << AgeNow.age << endl;
24 |
25 | cout << "My age in eight years later is ";
26 | cout << AgeLater.age << endl;
27 |
28 | return 0;
29 | }
30 |
--------------------------------------------------------------------------------
/Section03/const_error/const_error.cpp:
--------------------------------------------------------------------------------
1 | /* const_error.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | class MyAge
7 | {
8 | public:
9 | const int age;
10 | MyAge(const int initAge = 20) :
11 | age(initAge)
12 | {
13 | }
14 | };
15 |
16 | auto main() -> int
17 | {
18 | cout << "[const_error.cpp]" << endl;
19 |
20 | MyAge AgeNow, AgeLater(28);
21 |
22 | cout << "My current age is ";
23 | cout << AgeNow.age << endl;
24 |
25 | cout << "My age in eight years later is ";
26 | cout << AgeLater.age << endl;
27 |
28 | AgeLater.age = 10;
29 |
30 | return 0;
31 | }
32 |
--------------------------------------------------------------------------------
/Section03/first_class_pure_immutable/first_class_pure_immutable.cpp:
--------------------------------------------------------------------------------
1 | /* first_class_pure_immutable.cpp */
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | class MyValue
8 | {
9 | public:
10 | const int value;
11 | MyValue(int v) : value(v)
12 | {
13 | }
14 | };
15 |
16 | class MyFunction
17 | {
18 | public:
19 | const int x, y;
20 |
21 | MyFunction(int _x, int _y) :
22 | x(_x), y(_y)
23 | {
24 | }
25 |
26 | MyValue addition() const
27 | {
28 | return MyValue(x + y);
29 | }
30 |
31 | MyValue subtraction() const
32 | {
33 | return MyValue(x - y);
34 | }
35 |
36 | MyValue multiplication() const
37 | {
38 | return MyValue(x * y);
39 | }
40 |
41 | MyValue division() const
42 | {
43 | return MyValue(x / y);
44 | }
45 | };
46 |
47 | auto main() -> int
48 | {
49 | cout << "[first_class_pure_immutable.cpp]" << endl;
50 |
51 | int a = 100;
52 | int b = 10;
53 |
54 | cout << "Initial value" << endl;
55 | cout << "a = " << a << endl;
56 | cout << "b = " << b << endl;
57 | cout << endl;
58 |
59 | MyFunction func(a, b);
60 |
61 | auto callableAdd = mem_fn(&MyFunction::addition);
62 | auto callableSub = mem_fn(&MyFunction::subtraction);
63 | auto callableMul = mem_fn(&MyFunction::multiplication);
64 | auto callableDiv = mem_fn(&MyFunction::division);
65 |
66 | auto value1 = callableAdd(func);
67 | auto value2 = callableSub(func);
68 | auto value3 = callableMul(func);
69 | auto value4 = callableDiv(func);
70 |
71 | cout << "The result" << endl;
72 | cout << "addition = " << value1.value << endl;
73 | cout << "subtraction = " << value2.value << endl;
74 | cout << "multiplication = " << value3.value << endl;
75 | cout << "division = " << value4.value << endl;
76 |
77 | return 0;
78 | }
79 |
--------------------------------------------------------------------------------
/Section03/immutable_1/immutable_1.cpp:
--------------------------------------------------------------------------------
1 | /* immutable_1.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | auto main() -> int
7 | {
8 | cout << "[immutable_1.cpp]" << endl;
9 |
10 | int mutableVar = 100;
11 | cout << "Initial mutableVar = " << mutableVar;
12 | cout << endl;
13 |
14 | int mutableVar0 = mutableVar + 0;
15 | int mutableVar1 = mutableVar0 + 1;
16 | int mutableVar2 = mutableVar1 + 2;
17 | int mutableVar3 = mutableVar2 + 3;
18 | int mutableVar4 = mutableVar3 + 4;
19 | int mutableVar5 = mutableVar4 + 5;
20 | int mutableVar6 = mutableVar5 + 6;
21 | int mutableVar7 = mutableVar6 + 7;
22 | int mutableVar8 = mutableVar7 + 8;
23 | int mutableVar9 = mutableVar8 + 9;
24 | int mutableVar10 = mutableVar9 + 10;
25 |
26 | cout << "After manipulating mutableVar = " << mutableVar10;
27 | cout << endl;
28 |
29 | return 0;
30 | }
31 |
--------------------------------------------------------------------------------
/Section03/immutable_2/a.out:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Modern-CPlusPlus-Functional-Programming/9c9e674fcb1581b4466dd8c9cbf3e09fad4bb781/Section03/immutable_2/a.out
--------------------------------------------------------------------------------
/Section03/immutable_2/immutable_2.cpp:
--------------------------------------------------------------------------------
1 | /* immutable_2.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | void Modify(string name)
7 | {
8 | name = "Alexis Andrews";
9 | }
10 |
11 | auto main() -> int
12 | {
13 | cout << "[immutable_2.cpp]" << endl;
14 |
15 | string n = "Frankie Jones";
16 | cout << "Initial name = " << n;
17 | cout << endl;
18 |
19 | Modify(n);
20 |
21 | cout << "After manipulating = " << n;
22 | cout << endl;
23 |
24 | return 0;
25 | }
26 |
--------------------------------------------------------------------------------
/Section03/immutable_3/immutable_3.cpp:
--------------------------------------------------------------------------------
1 | /* immutable_3.cpp */
2 | #include
3 | #include "../immutableemployee/immutableemployee.cpp"
4 |
5 | using namespace std;
6 |
7 | auto main() -> int
8 | {
9 | cout << "[immutable_3.cpp]" << endl;
10 |
11 | string first = "Frankie";
12 | string last = "Jones";
13 | double d = 1500.0;
14 |
15 | ImmutableEmployee me(0, first, last, d);
16 |
17 | cout << "Content of ImmutableEmployee instance" << endl;
18 | cout << "ID : " << me.Id() << endl;
19 | cout << "Name : " << me.FirstName()
20 | << " " << me.LastName() << endl;
21 | cout << "Salary : " << me.Salary() << endl << endl;
22 |
23 | ImmutableEmployee me2 = me.SetId(1);
24 | ImmutableEmployee me3 = me2.SetFirstName("Alexis");
25 | ImmutableEmployee me4 = me3.SetLastName("Andrews");
26 | ImmutableEmployee me5 = me4.SetSalary(2100.0);
27 |
28 | cout << "Content of ImmutableEmployee after modifying" << endl;
29 | cout << "ID : " << me5.Id() << endl;
30 | cout << "Name : " << me5.FirstName()
31 | << " " << me5.LastName() << endl;
32 | cout << "Salary : " << me5.Salary() << endl;
33 |
34 | return 0;
35 | }
36 |
--------------------------------------------------------------------------------
/Section03/immutableemployee/immutableemployee.cpp:
--------------------------------------------------------------------------------
1 | /* immutableemployee.cpp */
2 | #include "immutableemployee.h"
3 |
4 | using namespace std;
5 |
6 | ImmutableEmployee::ImmutableEmployee() :
7 | m_id(0),
8 | m_salary(0.0)
9 | {
10 | }
11 |
12 | ImmutableEmployee::ImmutableEmployee(
13 | const int id,
14 | const string& firstName,
15 | const string& lastName,
16 | const double& salary) :
17 | m_id(id),
18 | m_firstName(firstName),
19 | m_lastName(lastName),
20 | m_salary(salary)
21 | {
22 | }
23 |
--------------------------------------------------------------------------------
/Section03/immutableemployee/immutableemployee.h:
--------------------------------------------------------------------------------
1 | /* immutableemployee.h */
2 | #ifndef __IMMUTABLEEMPLOYEE_H__
3 | #define __IMMUTABLEEMPLOYEE_H__
4 |
5 | #include
6 |
7 | class ImmutableEmployee
8 | {
9 | private:
10 | int m_id;
11 | std::string m_firstName;
12 | std::string m_lastName;
13 | double m_salary;
14 |
15 | public:
16 | ImmutableEmployee(
17 | const int id,
18 | const std::string& firstName,
19 | const std::string& lastName,
20 | const double& _salary);
21 | ImmutableEmployee();
22 |
23 | const int Id() const {
24 | return m_id;
25 | }
26 |
27 | const std::string& FirstName() const {
28 | return m_firstName;
29 | }
30 |
31 | const std::string& LastName() const {
32 | return m_lastName;
33 | }
34 |
35 | const double Salary() const {
36 | return m_salary;
37 | }
38 |
39 | const ImmutableEmployee SetId(
40 | const int id) const {
41 | return ImmutableEmployee(
42 | id, m_firstName, m_lastName, m_salary);
43 | }
44 |
45 | const ImmutableEmployee SetFirstName(
46 | const std::string& firstName) const {
47 | return ImmutableEmployee(
48 | m_id, firstName, m_lastName, m_salary);
49 | }
50 |
51 | const ImmutableEmployee SetLastName(
52 | const std::string& lastName) const {
53 | return ImmutableEmployee(
54 | m_id, m_firstName, lastName, m_salary);
55 | }
56 |
57 | const ImmutableEmployee SetSalary(
58 | const double& salary) const {
59 | return ImmutableEmployee(
60 | m_id, m_firstName, m_lastName, salary);
61 | }
62 |
63 | };
64 |
65 | #endif // End of __IMMUTABLEEMPLOYEE_H__
66 |
--------------------------------------------------------------------------------
/Section03/mutable_1/mutable_1.cpp:
--------------------------------------------------------------------------------
1 | /* mutable_1.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | auto main() -> int
7 | {
8 | cout << "[mutable_1.cpp]" << endl;
9 |
10 | int mutableVar = 100;
11 | cout << "Initial mutableVar = " << mutableVar;
12 | cout << endl;
13 |
14 | for(int i = 0; i <= 10; ++i)
15 | mutableVar = mutableVar + i;
16 |
17 | cout << "After manipulating mutableVar = " << mutableVar;
18 | cout << endl;
19 |
20 | return 0;
21 | }
22 |
--------------------------------------------------------------------------------
/Section03/mutable_2/mutable_2.cpp:
--------------------------------------------------------------------------------
1 | /* mutable_2.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | void Modify(string &name)
7 | {
8 | name = "Alexis Andrews";
9 | }
10 |
11 | auto main() -> int
12 | {
13 | cout << "[mutable_2.cpp]" << endl;
14 |
15 | string n = "Frankie Jones";
16 | cout << "Initial name = " << n;
17 | cout << endl;
18 |
19 | Modify(n);
20 |
21 | cout << "After manipulating = " << n;
22 | cout << endl;
23 |
24 | return 0;
25 | }
26 |
--------------------------------------------------------------------------------
/Section03/mutable_2a/mutable_2a.cpp:
--------------------------------------------------------------------------------
1 | /* mutable_2a.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | class Name
7 | {
8 | public:
9 | string str;
10 | };
11 |
12 | void Modify(Name &name)
13 | {
14 | name.str = "Alexis Andrews";
15 | }
16 |
17 | auto main() -> int
18 | {
19 | cout << "[mutable_2a.cpp]" << endl;
20 |
21 | Name n = {"Frankie Jones"};
22 | cout << "Initial name = " << n.str;
23 | cout << endl;
24 |
25 | Modify(n);
26 |
27 | cout << "After manipulating = " << n.str;
28 | cout << endl;
29 |
30 | return 0;
31 | }
32 |
--------------------------------------------------------------------------------
/Section03/mutable_3/mutable_3.cpp:
--------------------------------------------------------------------------------
1 | /* mutable_3.cpp */
2 | #include
3 | #include "../mutableemployee/mutableemployee.cpp"
4 |
5 | using namespace std;
6 |
7 | auto main() -> int
8 | {
9 | cout << "[mutable_3.cpp]" << endl;
10 |
11 | string first = "Frankie";
12 | string last = "Kaur";
13 | double d = 1500.0;
14 |
15 | MutableEmployee me(0, first, last, d);
16 |
17 | cout << "Content of MutableEmployee instance" << endl;
18 | cout << "ID : " << me.Id() << endl;
19 | cout << "Name : " << me.FirstName();
20 | cout << " " << me.LastName() << endl;
21 | cout << "Salary : " << me.Salary() << endl << endl;
22 |
23 | me.SetId(1);
24 | me.SetFirstName("Alexis");
25 | me.SetLastName("Andrews");
26 | me.SetSalary(2100.0);
27 |
28 | cout << "Content of MutableEmployee after mutating" << endl;
29 | cout << "ID : " << me.Id() << endl;
30 | cout << "Name : " << me.FirstName();
31 | cout << " " << me.LastName() << endl;
32 | cout << "Salary : " << me.Salary() << endl;
33 |
34 | return 0;
35 | }
36 |
--------------------------------------------------------------------------------
/Section03/mutableemployee/mutableemployee.cpp:
--------------------------------------------------------------------------------
1 | /* mutableemployee.cpp */
2 | #include "mutableemployee.h"
3 |
4 | using namespace std;
5 |
6 | MutableEmployee::MutableEmployee() :
7 | m_id(0),
8 | m_salary(0.0)
9 | {
10 | }
11 |
12 | MutableEmployee::MutableEmployee(
13 | int id,
14 | const string& firstName,
15 | const string& lastName,
16 | const double& salary) :
17 | m_id(id),
18 | m_firstName(firstName),
19 | m_lastName(lastName),
20 | m_salary(salary)
21 | {
22 | }
23 |
24 | void MutableEmployee::SetId(const int id)
25 | {
26 | m_id = id;
27 | }
28 |
29 | void MutableEmployee::SetFirstName(
30 | const std::string& FirstName) {
31 | m_firstName = FirstName;
32 | }
33 |
34 | void MutableEmployee::SetLastName(
35 | const std::string& LastName) {
36 | m_lastName = LastName;
37 | }
38 |
39 | void MutableEmployee::SetSalary(
40 | const double& Salary) {
41 | m_salary = Salary;
42 | }
43 |
--------------------------------------------------------------------------------
/Section03/mutableemployee/mutableemployee.h:
--------------------------------------------------------------------------------
1 | /* mutableemployee.h */
2 | #ifndef __MUTABLEEMPLOYEE_H__
3 | #define __MUTABLEEMPLOYEE_H__
4 |
5 | #include
6 |
7 | class MutableEmployee
8 | {
9 | private:
10 | int m_id;
11 | std::string m_firstName;
12 | std::string m_lastName;
13 | double m_salary;
14 |
15 | public:
16 | MutableEmployee(
17 | int id,
18 | const std::string& firstName,
19 | const std::string& lastName,
20 | const double& salary);
21 | MutableEmployee();
22 |
23 | void SetId(const int id);
24 | void SetFirstName(
25 | const std::string& FirstName);
26 | void SetLastName(
27 | const std::string& LastName);
28 | void SetSalary(
29 | const double& Salary);
30 |
31 | int Id() const {return m_id;}
32 | std::string FirstName() const {return m_firstName;}
33 | std::string LastName() const {return m_lastName;}
34 | double Salary() const {return m_salary;}
35 | };
36 |
37 | #endif // End of __MUTABLEEMPLOYEE_H__
38 |
--------------------------------------------------------------------------------
/Section04/exponential_iteration/exponential_iteration.cpp:
--------------------------------------------------------------------------------
1 | /* exponential_iteration.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | int power(int base, int exp)
7 | {
8 | int result = 1;
9 |
10 | for(int i = 0; i < exp; ++i)
11 | {
12 | result *= base;
13 | }
14 |
15 | return(result);
16 | }
17 |
18 | auto main() -> int
19 | {
20 | cout << "[exponential_iteration.cpp]" << endl;
21 |
22 | for(int i = 0; i <= 5; ++i)
23 | {
24 | cout << "power (2, " << i << ") = ";
25 | cout << power(2, i) << endl;
26 | }
27 |
28 | return 0;
29 | }
30 |
--------------------------------------------------------------------------------
/Section04/exponential_recursion/exponential_recursion.cpp:
--------------------------------------------------------------------------------
1 | /* exponential_recursion.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | int power(int base, int exp)
7 | {
8 | if(exp == 0)
9 | return 1;
10 | else
11 | return base * power(base, exp - 1);
12 | }
13 |
14 | auto main() -> int
15 | {
16 | cout << "[exponential_recursion.cpp]" << endl;
17 |
18 | for(int i = 0; i <= 5; ++i)
19 | {
20 | cout << "power (2, " << i << ") = ";
21 | cout << power(2, i) << endl;
22 | }
23 |
24 | return 0;
25 | }
26 |
--------------------------------------------------------------------------------
/Section04/factorial_iteration_do_while/factorial_iteration_do_while.cpp:
--------------------------------------------------------------------------------
1 | /* factorial_iteration_do_while.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | int factorial (int n)
7 | {
8 | int result = 1;
9 | int i = 1;
10 |
11 | do
12 | {
13 | result *= i;
14 | }
15 | while(++i <= n);
16 |
17 | return result;
18 | }
19 |
20 | auto main() -> int
21 | {
22 | cout << "[factorial_iteration_do_while.cpp]" << endl;
23 |
24 | for(int i = 1; i < 10; ++i)
25 | {
26 | cout << i << "! = " << factorial(i) << endl;
27 | }
28 |
29 | return 0;
30 | }
31 |
--------------------------------------------------------------------------------
/Section04/factorial_iteration_for/factorial_iteration_for.cpp:
--------------------------------------------------------------------------------
1 | /* factorial_iteration_for.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | int factorial (int n)
7 | {
8 | int result = 1;
9 |
10 | for(int i = 1; i <= n; ++i)
11 | {
12 | result *= i;
13 | }
14 |
15 | return result;
16 | }
17 |
18 | auto main() -> int
19 | {
20 | cout << "[factorial_iteration_for.cpp]" << endl;
21 |
22 | for(int i = 1; i < 10; ++i)
23 | {
24 | cout << i << "! = " << factorial(i) << endl;
25 | }
26 |
27 | return 0;
28 | }
29 |
--------------------------------------------------------------------------------
/Section04/factorial_recursion/factorial_recursion.cpp:
--------------------------------------------------------------------------------
1 | /* factorial_recursion.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | int factorial(int n)
7 | {
8 |
9 | if (n == 0)
10 | return 1;
11 | else
12 | return n * factorial (n - 1);
13 | }
14 |
15 | auto main() -> int
16 | {
17 | cout << "[factorial_recursion.cpp]" << endl;
18 |
19 | for(int i = 1; i < 10; ++i)
20 | {
21 | cout << i << "! = " << factorial(i) << endl;
22 | }
23 |
24 | return 0;
25 | }
26 |
--------------------------------------------------------------------------------
/Section04/factorial_recursion_tail/factorial_recursion_tail.cpp:
--------------------------------------------------------------------------------
1 | /* factorial_recursion_tail.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | int factorialTail(int n, int i)
7 | {
8 | if (n == 0)
9 | return i;
10 |
11 | return factorialTail(n - 1, n * i);
12 | }
13 |
14 | int factorial(int n)
15 | {
16 | return factorialTail(n, 1);
17 | }
18 |
19 | auto main() -> int
20 | {
21 | cout << "[factorial_recursion_tail.cpp]" << endl;
22 |
23 | for(int i = 1; i < 10; ++i)
24 | {
25 | cout << i << "! = " << factorial(i) << endl;
26 | }
27 |
28 | return 0;
29 | }
30 |
--------------------------------------------------------------------------------
/Section04/fibonacci_iteration/fibonacci_iteration.cpp:
--------------------------------------------------------------------------------
1 | /* fibonacci_iteration.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | int fibonacci(int n)
7 | {
8 | if (n == 0)
9 | return 0;
10 |
11 | int previous = 0;
12 | int current = 1;
13 |
14 | for (int i = 1; i < n; ++i)
15 | {
16 | int next = previous + current;
17 | previous = current;
18 | current = next;
19 | }
20 |
21 | return current;
22 | }
23 |
24 | auto main() -> int
25 | {
26 | cout << "[fibonacci_iteration.cpp]" << endl;
27 |
28 | for(int i = 0; i < 10; ++i)
29 | {
30 | cout << fibonacci(i) << " ";
31 | }
32 | cout << endl;
33 |
34 | return 0;
35 | }
36 |
--------------------------------------------------------------------------------
/Section04/fibonacci_recursion/fibonacci_recursion.cpp:
--------------------------------------------------------------------------------
1 | /* fibonacci_recursion.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | int fibonacci(int n)
7 | {
8 | if(n <= 1)
9 | return n;
10 |
11 | return fibonacci(n-1) + fibonacci(n-2);
12 | }
13 |
14 | auto main() -> int
15 | {
16 | cout << "[fibonacci_recursion.cpp]" << endl;
17 |
18 | for(int i = 0; i < 10; ++i)
19 | {
20 | cout << fibonacci(i) << " ";
21 | }
22 | cout << endl;
23 |
24 | return 0;
25 | }
26 |
--------------------------------------------------------------------------------
/Section04/labyrinth/labyrinth.cpp:
--------------------------------------------------------------------------------
1 | /* labyrinth.cpp */
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | const int rows = 8 ;
9 | const int cols = 8 ;
10 |
11 | vector> createLabyrinth()
12 | {
13 |
14 | vector> labyrinth =
15 | {
16 | {'#', '#', '#', '#', '#', '#', '#', '#'},
17 | {'#', 'S', ' ', ' ', ' ', ' ', ' ', '#'},
18 | {'#', '#', '#', ' ', '#', '#', '#', '#'},
19 | {'#', ' ', '#', ' ', '#', '#', '#', '#'},
20 | {'#', ' ', ' ', ' ', ' ', ' ', ' ', '#'},
21 | {'#', ' ', '#', '#', '#', '#', '#', '#'},
22 | {'#', ' ', ' ', ' ', ' ', ' ', 'F', '#'},
23 | {'#', '#', '#', '#', '#', '#', '#', '#'}
24 | };
25 |
26 | return labyrinth;
27 | }
28 |
29 | void displayLabyrinth(
30 | vector> labyrinth)
31 | {
32 | cout << endl;
33 | cout << "====================" << endl;
34 | cout << "The Labyrinth" << endl;
35 | cout << "====================" << endl;
36 |
37 | for (int i = 0; i < rows; i++)
38 | {
39 | for (int j = 0; j < cols; j++)
40 | {
41 | cout << labyrinth[i][j] << " ";
42 | }
43 | cout << endl;
44 | }
45 | cout << "====================" << endl << endl;
46 | }
47 |
48 | bool navigate(
49 | vector> labyrinth,
50 | int row,
51 | int col)
52 | {
53 | displayLabyrinth(labyrinth);
54 |
55 | cout << "Checking cell (";
56 | cout << row << "," << col << ")" << endl;
57 |
58 | sleep(1);
59 |
60 | if (labyrinth[row][col] == 'F')
61 | {
62 | cout << "Yeayy.. ";
63 | cout << "Found the finish flag ";
64 | cout << "at point (" << row << ",";
65 | cout << col << ")" << endl;
66 | return (true);
67 | }
68 | else if (
69 | labyrinth[row][col] == '#' ||
70 | labyrinth[row][col] == '*')
71 | {
72 | return (false);
73 | }
74 | else if (labyrinth[row][col] == ' ')
75 | {
76 | labyrinth[row][col] = '*';
77 | }
78 |
79 | if ((row + 1 < rows) &&
80 | navigate(labyrinth, row + 1, col))
81 | return (true);
82 |
83 | if ((col + 1 < cols) &&
84 | navigate(labyrinth, row, col + 1))
85 | return (true);
86 |
87 | if ((row - 1 >= 0) &&
88 | navigate(labyrinth, row - 1, col))
89 | return (true);
90 |
91 | if ((col - 1 >= 0) &&
92 | navigate(labyrinth, row, col - 1))
93 | return (true);
94 |
95 | return (false);
96 | }
97 |
98 | bool isLabyrinthSolvable(
99 | vector> labyrinth)
100 | {
101 | int start_row = -1;
102 | int start_col = -1;
103 | for (int i = 0; i < rows; i++)
104 | {
105 | for (int j = 0; j < cols; j++)
106 | {
107 | if (labyrinth[i][j] == 'S')
108 | {
109 | start_row = i;
110 | start_col = j;
111 | break;
112 | }
113 | }
114 | }
115 |
116 | if (start_row == -1 || start_col == -1)
117 | {
118 | cerr << "No valid starting point found!" << endl;
119 | return (false);
120 | }
121 |
122 | cout << "Starting at point (" << start_row << ",";
123 | cout << start_col << ")" << endl;
124 |
125 | return navigate(labyrinth, start_row, start_col);
126 | }
127 |
128 | auto main() -> int
129 | {
130 | vector> labyrinth = createLabyrinth();
131 | displayLabyrinth(labyrinth);
132 |
133 | string line;
134 | cout << endl << "Press enter to continue..." << endl;
135 | getline(cin, line);
136 |
137 | if (isLabyrinthSolvable(labyrinth))
138 | cout << "Labyrinth solved!" << endl;
139 | else
140 | cout << "Labyrinth could not be solved!" << endl;
141 |
142 | return 0;
143 | }
144 |
--------------------------------------------------------------------------------
/Section04/permutation/permutation.cpp:
--------------------------------------------------------------------------------
1 | /* permutation.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | void doPermute(
7 | const string &chosen,
8 | const string &remaining)
9 | {
10 | if(remaining == "")
11 | {
12 | cout << chosen << endl;
13 | }
14 | else
15 | {
16 | for(uint32_t u = 0; u < remaining.length(); ++u)
17 | {
18 | doPermute(
19 | chosen + remaining[u],
20 | remaining.substr(0, u)
21 | + remaining.substr(u + 1));
22 | }
23 | }
24 | }
25 |
26 | void permute(
27 | const string &s)
28 | {
29 | doPermute("", s);
30 | }
31 |
32 | auto main() -> int
33 | {
34 | cout << "[permutation.cpp]" << endl;
35 |
36 | string str;
37 | cout << "Permutation of a string" << endl;
38 | cout << "Enter a string: ";
39 | getline(cin, str);
40 |
41 | cout << endl << "The possibility permutation of ";
42 | cout << str << endl;
43 | permute(str);
44 |
45 | return 0;
46 | }
47 |
--------------------------------------------------------------------------------
/Section04/tail_recursion/tail_recursion.cpp:
--------------------------------------------------------------------------------
1 | /* tail_recursion.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | void displayNumber(long long n)
7 | {
8 | cout << n << endl;
9 |
10 | displayNumber(n + 1);
11 | }
12 |
13 | auto main() -> int
14 | {
15 | cout << "[tail_recursion.cpp]" << endl;
16 |
17 | displayNumber(0);
18 | return 0;
19 | }
20 |
--------------------------------------------------------------------------------
/Section04/tail_recursion_goto/tail_recursion_goto.cpp:
--------------------------------------------------------------------------------
1 | /* tail_recursion_goto.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | void displayNumber(long long n)
7 | {
8 | loop:
9 | cout << n << endl;
10 |
11 | n++;
12 | goto loop;
13 | }
14 |
15 | auto main() -> int
16 | {
17 | cout << "[tail_recursion_goto.cpp]" << endl;
18 |
19 | displayNumber(0);
20 |
21 | return 0;
22 | }
23 |
--------------------------------------------------------------------------------
/Section05/delaying/Code_Example1.cpp:
--------------------------------------------------------------------------------
1 | template class Delay
2 | {
3 | private:
4 | function m_func;
5 |
6 | public:
7 | Delay(
8 | function func)
9 | : m_func(func)
10 | {
11 | }
12 |
13 | T Fetch()
14 | {
15 | return m_func();
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/Section05/delaying/delaying.cpp:
--------------------------------------------------------------------------------
1 | /* delaying.cpp */
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | template class Delay
8 | {
9 | private:
10 | function m_func;
11 |
12 | public:
13 | Delay(
14 | function func)
15 | : m_func(func)
16 | {
17 | }
18 |
19 | T Fetch()
20 | {
21 | return m_func();
22 | }
23 | };
24 |
25 | auto main() -> int
26 | {
27 | cout << "[delaying.cpp]" << endl;
28 |
29 | int a = 10;
30 | int b = 5;
31 |
32 | cout << "Constructing Delay<> named multiply";
33 | cout << endl;
34 | Delay multiply([a, b]()
35 | {
36 | cout << "Delay<> named multiply";
37 | cout << " is constructed." << endl;
38 | return a * b;
39 | });
40 |
41 | cout << "Constructing Delay<> named division";
42 | cout << endl;
43 | Delay division([a, b]()
44 | {
45 | cout << "Delay<> named division ";
46 | cout << "is constructed." << endl;
47 | return a / b;
48 | });
49 |
50 | cout << "Invoking Fetch() method in ";
51 | cout << "multiply instance." << endl;
52 | int c = multiply.Fetch();
53 |
54 | cout << "Invoking Fetch() method in ";
55 | cout << "division instance." << endl;
56 | int d = division.Fetch();
57 |
58 | cout << "The result of a * b = " << c << endl;
59 | cout << "The result of a / b = " << d << endl;
60 |
61 | return 0;
62 | }
63 |
--------------------------------------------------------------------------------
/Section05/delaying_non_pure/delaying_non_pure.cpp:
--------------------------------------------------------------------------------
1 | /* delaying_non_pure.cpp */
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | template class Delay
8 | {
9 | private:
10 | function m_func;
11 |
12 | public:
13 | Delay(
14 | function func)
15 | : m_func(func)
16 | {
17 | }
18 |
19 | T Fetch()
20 | {
21 | return m_func();
22 | }
23 | };
24 |
25 | auto main() -> int
26 | {
27 | cout << "[delaying_non_pure.cpp]" << endl;
28 |
29 | int a = 10;
30 | int b = 5;
31 | int multiplexer = 0;
32 |
33 | Delay multiply_impure([&]()
34 | {
35 | return multiplexer * a * b;
36 | });
37 |
38 | for (int i = 0; i < 5; ++i)
39 | {
40 | ++multiplexer;
41 | cout << "Multiplexer = " << multiplexer << endl;
42 | cout << "a * b = " << multiply_impure.Fetch();
43 | cout << endl;
44 | }
45 |
46 | return 0;
47 | }
48 |
--------------------------------------------------------------------------------
/Section05/delaying_non_pure_memoization/Code_Example2.cpp:
--------------------------------------------------------------------------------
1 | template class Memoization
2 | {
3 | private:
4 | T const & (*m_subRoutine)(Memoization *);
5 | mutable T m_recordedFunc;
6 | function m_func;
7 |
8 | static T const & ForceSubroutine(
9 | Memoization * d)
10 | {
11 | return d->DoRecording();
12 | }
13 |
14 | static T const & FetchSubroutine(
15 | Memoization * d)
16 | {
17 | return d->FetchRecording();
18 | }
19 |
20 | T const & FetchRecording()
21 | {
22 | return m_recordedFunc;
23 | }
24 |
25 | T const & DoRecording()
26 | {
27 | m_recordedFunc = m_func();
28 | m_subRoutine = &FetchSubroutine;
29 | return FetchRecording();
30 | }
31 |
32 | public:
33 | Memoization(
34 | function func)
35 | : m_func(func),
36 | m_subRoutine(&ForceSubroutine),
37 | m_recordedFunc(T())
38 | {
39 | }
40 |
41 | T Fetch()
42 | {
43 | return m_subRoutine(this);
44 | }
45 | };
46 |
--------------------------------------------------------------------------------
/Section05/delaying_non_pure_memoization/delaying_non_pure_memoization.cpp:
--------------------------------------------------------------------------------
1 | /* delaying_non_pure_memoization.cpp */
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | template class Memoization
8 | {
9 | private:
10 | T const & (*m_subRoutine)(Memoization *);
11 | mutable T m_recordedFunc;
12 | function m_func;
13 |
14 | static T const & ForceSubroutine(
15 | Memoization * d)
16 | {
17 | return d->DoRecording();
18 | }
19 |
20 | static T const & FetchSubroutine(
21 | Memoization * d)
22 | {
23 | return d->FetchRecording();
24 | }
25 |
26 | T const & FetchRecording()
27 | {
28 | return m_recordedFunc;
29 | }
30 |
31 | T const & DoRecording()
32 | {
33 | m_recordedFunc = m_func();
34 | m_subRoutine = &FetchSubroutine;
35 | return FetchRecording();
36 | }
37 |
38 | public:
39 | Memoization(
40 | function func)
41 | : m_func(func),
42 | m_subRoutine(&ForceSubroutine),
43 | m_recordedFunc(T())
44 | {
45 | }
46 |
47 | T Fetch()
48 | {
49 | return m_subRoutine(this);
50 | }
51 | };
52 |
53 | auto main() -> int
54 | {
55 | cout << "[delaying_non_pure_memoization.cpp]" << endl;
56 |
57 | int a = 10;
58 | int b = 5;
59 | int multiplexer = 0;
60 |
61 | Memoization multiply_impure([&]()
62 | {
63 | return multiplexer * a * b;
64 | });
65 |
66 | for (int i = 0; i < 5; ++i)
67 | {
68 | ++multiplexer;
69 | cout << "Multiplexer = " << multiplexer << endl;
70 | cout << "a * b = " << multiply_impure.Fetch();
71 | cout << endl;
72 | }
73 |
74 | return 0;
75 | }
76 |
--------------------------------------------------------------------------------
/Section05/non_strict/non_strict.cpp:
--------------------------------------------------------------------------------
1 | /* non_strict.cpp */
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | int OuterFormulaNonStrict(
8 | int x,
9 | int y,
10 | int z,
11 | function yzFunc)
12 | {
13 | cout << "Calculate " << x << " + ";
14 | cout << "InnerFormula(" << y << ", ";
15 | cout << z << ")" << endl;
16 |
17 | return x + yzFunc(y, z);
18 | }
19 |
20 | int InnerFormula(int y, int z)
21 | {
22 | cout << "Calculate " << y << " * ";
23 | cout << z << endl;
24 |
25 | return y * z;
26 | }
27 |
28 | auto main() -> int
29 | {
30 | cout << "[non_strict.cpp]" << endl;
31 |
32 | int x = 4;
33 | int y = 3;
34 | int z = 2;
35 |
36 | cout << "Calculate " << x <<" + ";
37 | cout << "(" << y << " * " << z << ")";
38 | cout << endl;
39 | int result = OuterFormulaNonStrict(x, y, z, InnerFormula);
40 |
41 | cout << x << " + ";
42 | cout << "(" << y << " * " << z << ")";
43 | cout << " = " << result << endl;
44 |
45 | return 0;
46 | }
47 |
--------------------------------------------------------------------------------
/Section05/prime/prime.cpp:
--------------------------------------------------------------------------------
1 | /* prime.cpp */
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | bool PrimeCheck(int i)
8 | {
9 | if ((i % 2) == 0)
10 | {
11 | return i == 2;
12 | }
13 |
14 | int sqr = sqrt(i);
15 |
16 | for (int t = 3; t <= sqr; t += 2)
17 | {
18 | if (i % t == 0)
19 | {
20 | return false;
21 | }
22 | }
23 |
24 | return i != 1;
25 | }
26 |
27 | auto main() -> int
28 | {
29 | cout << "[prime.cpp]" << endl;
30 |
31 | int n = 0;
32 |
33 | cout << "List of the first 100 prime numbers:" << endl;
34 | for (int i = 0; ; ++i)
35 | {
36 | if (PrimeCheck(i))
37 | {
38 | cout << i << "\n";
39 |
40 | if (++n == 100)
41 | return 0;
42 | }
43 | }
44 |
45 | return 0;
46 | }
47 |
--------------------------------------------------------------------------------
/Section05/strict/strict.cpp:
--------------------------------------------------------------------------------
1 | /* strict.cpp */
2 | #include
3 |
4 | using namespace std;
5 |
6 | int OuterFormula(int x, int yz)
7 | {
8 | cout << "Calculate " << x << " + ";
9 | cout << "InnerFormula(" << yz << ")";
10 | cout << endl;
11 |
12 | return x + yz;
13 | }
14 |
15 | int InnerFormula(int y, int z)
16 | {
17 | cout << "Calculate " << y << " * ";
18 | cout << z << endl;
19 |
20 | return y * z;
21 | }
22 |
23 | auto main() -> int
24 | {
25 | cout << "[strict.cpp]" << endl;
26 |
27 | int x = 4;
28 | int y = 3;
29 | int z = 2;
30 |
31 | cout << "Calculate " << x <<" + ";
32 | cout << "(" << y << " * " << z << ")";
33 | cout << endl;
34 | int result = OuterFormula(x, InnerFormula(y, z));
35 |
36 | cout << x << " + ";
37 | cout << "(" << y << " * " << z << ")";
38 | cout << " = " << result << endl;
39 |
40 | return 0;
41 | }
42 |
--------------------------------------------------------------------------------
/Section06/Step01/Customer.cpp:
--------------------------------------------------------------------------------
1 | /* Customer.cpp - Step01 */
2 | #include "Customer.h"
3 |
4 | using namespace std;
5 |
6 | vector Customer::registeredCustomers;
7 |
8 | vector Customer::GetActiveCustomerNames()
9 | {
10 | vector returnList;
11 | for (auto &customer : Customer::registeredCustomers)
12 | {
13 | if (customer.isActive)
14 | {
15 | returnList.push_back(customer.name);
16 | }
17 | }
18 | return returnList;
19 | }
20 |
21 | vector Customer::GetActiveCustomerAddresses()
22 | {
23 | vector returnList;
24 | for (auto &customer : Customer::registeredCustomers)
25 | {
26 | if (customer.isActive)
27 | {
28 | returnList.push_back(customer.address);
29 | }
30 | }
31 | return returnList;
32 | }
33 |
34 | vector Customer::GetActiveCustomerPhoneNumbers()
35 | {
36 | vector returnList;
37 | for (auto &customer : Customer::registeredCustomers)
38 | {
39 | if (customer.isActive)
40 | {
41 | returnList.push_back(customer.phoneNumber);
42 | }
43 | }
44 | return returnList;
45 | }
46 |
47 | vector Customer::GetActiveCustomerEmails()
48 | {
49 | vector returnList;
50 | for (auto &customer : Customer::registeredCustomers)
51 | {
52 | if (customer.isActive)
53 | {
54 | returnList.push_back(customer.email);
55 | }
56 | }
57 | return returnList;
58 | }
59 |
--------------------------------------------------------------------------------
/Section06/Step01/Customer.h:
--------------------------------------------------------------------------------
1 | /* Customer.h - Step01 */
2 | #ifndef __CUSTOMER_H__
3 | #define __CUSTOMER_H__
4 |
5 | #include
6 | #include
7 |
8 | class Customer
9 | {
10 | public:
11 | static std::vector registeredCustomers;
12 | int id = 0;
13 | std::string name;
14 | std::string address;
15 | std::string phoneNumber;
16 | std::string email;
17 | bool isActive = true;
18 |
19 | std::vector GetActiveCustomerNames();
20 | std::vector GetActiveCustomerAddresses();
21 | std::vector GetActiveCustomerPhoneNumbers();
22 | std::vector GetActiveCustomerEmails();
23 | };
24 | #endif // __CUSTOMER_H__
25 |
--------------------------------------------------------------------------------
/Section06/Step01/Main.cpp:
--------------------------------------------------------------------------------
1 | /* Main.cpp - Step01 */
2 | #include
3 | #include "Customer.h"
4 |
5 | using namespace std;
6 |
7 | void RegisterCustomers()
8 | {
9 | int i = 0;
10 | bool b = false;
11 |
12 | vector nameList =
13 | {
14 | "William",
15 | "Aiden",
16 | "Rowan",
17 | "Jamie",
18 | "Quinn",
19 | "Haiden",
20 | "Logan",
21 | "Emerson",
22 | "Sherlyn",
23 | "Molly"
24 | };
25 |
26 | Customer::registeredCustomers.clear();
27 |
28 | for (auto name : nameList)
29 | {
30 |
31 | Customer c;
32 | c.id = i++;
33 | c.name = name;
34 | c.address = "somewhere";
35 | c.phoneNumber = "0123";
36 | c.email = name + "@xyz.com";
37 | c.isActive = b;
38 |
39 | b = !b;
40 |
41 | Customer::registeredCustomers.push_back(c);
42 | }
43 | }
44 |
45 | auto main() -> int
46 | {
47 | cout << "[Step01]" << endl;
48 | cout << "--------" << endl;
49 |
50 | RegisterCustomers();
51 |
52 | Customer customer;
53 |
54 | cout << "List of active customer names:" << endl;
55 | vector activeCustomerNames =
56 | customer.GetActiveCustomerNames();
57 | for (auto &name : activeCustomerNames)
58 | {
59 | cout << name << endl;
60 | }
61 |
62 | return 0;
63 | }
64 |
--------------------------------------------------------------------------------
/Section06/Step02/Customer.cpp:
--------------------------------------------------------------------------------
1 | /* Customer.cpp - Step02 */
2 | #include
3 | #include "Customer.h"
4 |
5 | using namespace std;
6 |
7 | vector Customer::registeredCustomers;
8 |
9 | string Customer::GetActiveCustomerNames(
10 | Customer customer) const
11 | {
12 | return customer.name;
13 | }
14 |
15 | string Customer::GetActiveCustomerAddresses(
16 | Customer customer) const
17 | {
18 | return customer.address;
19 | }
20 |
21 | string Customer::GetActiveCustomerPhoneNumbers(
22 | Customer customer) const
23 | {
24 | return customer.phoneNumber;
25 | }
26 |
27 | string Customer::GetActiveCustomerEmails(
28 | Customer customer) const
29 | {
30 | return customer.email;
31 | }
32 |
33 | vector Customer::GetActiveCustomerByFunctionField(
34 | function funcField)
35 | {
36 | vector returnList;
37 |
38 | Customer c;
39 |
40 | for (auto customer : Customer::registeredCustomers)
41 | {
42 | if (customer.isActive)
43 | {
44 | returnList.push_back(
45 | funcField(c, customer));
46 | }
47 | }
48 | return returnList;
49 | }
50 |
51 | vector Customer::GetActiveCustomerByField(
52 | const string &field)
53 | {
54 | function funct;
55 |
56 | if (field == "name")
57 | {
58 | funct = &Customer::GetActiveCustomerNames;
59 | }
60 | else if (field == "address")
61 | {
62 | funct = &Customer::GetActiveCustomerAddresses;
63 | }
64 | else if (field == "phoneNumber")
65 | {
66 | funct = &Customer::GetActiveCustomerPhoneNumbers;
67 | }
68 | else if (field == "email")
69 | {
70 | funct = &Customer::GetActiveCustomerEmails;
71 | }
72 | else
73 | {
74 | throw invalid_argument("Unknown field");
75 | }
76 |
77 | return GetActiveCustomerByFunctionField(funct);
78 | }
79 |
--------------------------------------------------------------------------------
/Section06/Step02/Customer.h:
--------------------------------------------------------------------------------
1 | /* Customer.h - Step02 */
2 | #ifndef __CUSTOMER_H__
3 | #define __CUSTOMER_H__
4 |
5 | #include
6 | #include
7 | #include
8 |
9 | class Customer
10 | {
11 | private:
12 | std::string GetActiveCustomerNames(
13 | Customer customer) const;
14 | std::string GetActiveCustomerAddresses(
15 | Customer customer) const;
16 | std::string GetActiveCustomerPhoneNumbers(
17 | Customer customer) const;
18 | std::string GetActiveCustomerEmails(
19 | Customer customer) const;
20 |
21 | public:
22 | static std::vector registeredCustomers;
23 | int id = 0;
24 | std::string name;
25 | std::string address;
26 | std::string phoneNumber;
27 | std::string email;
28 | bool isActive = true;
29 |
30 | std::vector GetActiveCustomerByField(
31 | const std::string &field);
32 |
33 | std::vector GetActiveCustomerByFunctionField(
34 | std::function
35 | funcField);
36 | };
37 | #endif //#ifndef __CUSTOMER_H__
38 |
--------------------------------------------------------------------------------
/Section06/Step02/Main.cpp:
--------------------------------------------------------------------------------
1 | /* Main.cpp - Step02 */
2 | #include
3 | #include "Customer.h"
4 |
5 | using namespace std;
6 |
7 | void RegisterCustomers()
8 | {
9 | int i = 0;
10 | bool b = false;
11 |
12 | // Initialize name
13 | vector nameList =
14 | {
15 | "William",
16 | "Aiden",
17 | "Rowan",
18 | "Jamie",
19 | "Quinn",
20 | "Haiden",
21 | "Logan",
22 | "Emerson",
23 | "Sherlyn",
24 | "Molly"
25 | };
26 |
27 | // Clear the registeredCustomers vector array
28 | Customer::registeredCustomers.clear();
29 |
30 | for (auto name : nameList)
31 | {
32 | // Create Customer object
33 | // and fill all properties
34 | Customer c;
35 | c.id = i++;
36 | c.name = name;
37 | c.address = "somewhere";
38 | c.phoneNumber = "0123";
39 | c.email = name + "@xyz.com";
40 | c.isActive = b;
41 |
42 | // Flip the b value
43 | b = !b;
44 |
45 | // Send data to the registeredCustomers
46 | Customer::registeredCustomers.push_back(c);
47 | }
48 | }
49 |
50 | auto main() -> int
51 | {
52 | cout << "[Step02]" << endl;
53 | cout << "--------" << endl;
54 |
55 | // Fill the Customer::registeredCustomers
56 | // with the content
57 | RegisterCustomers();
58 |
59 | // Instance Customer object
60 | Customer customer;
61 |
62 | // Get the active customer names
63 | cout << "List of active customer names:" << endl;
64 | vector activeCustomerNames =
65 | customer.GetActiveCustomerByField("name");
66 | for (auto &name : activeCustomerNames)
67 | {
68 | cout << name << endl;
69 | }
70 |
71 | return 0;
72 | }
73 |
--------------------------------------------------------------------------------
/Section06/Step03/Code_Example1.cpp:
--------------------------------------------------------------------------------
1 | template
2 | class BaseClass
3 | {
4 | public:
5 | virtual U InvokeFunction(
6 | const std::shared_ptr&) = 0;
7 | };
8 |
9 | class CustomerName :
10 | public BaseClass
11 | {
12 | public:
13 | virtual std::string InvokeFunction(
14 | const std::shared_ptr &customer)
15 | {
16 | return customer->name;
17 | }
18 | };
19 |
20 | class CustomerAddress :
21 | public BaseClass
22 | {
23 | public:
24 | virtual std::string InvokeFunction(
25 | const std::shared_ptr &customer)
26 | {
27 | return customer->address;
28 | }
29 | };
30 | class CustomerPhoneNumber :
31 | public BaseClass
32 | {
33 | public:
34 | virtual std::string InvokeFunction(
35 | const std::shared_ptr &customer)
36 | {
37 | return customer->phoneNumber;
38 | }
39 | };
40 | class CustomerEmail :
41 | public BaseClass
42 | {
43 | public:
44 | virtual std::string InvokeFunction(
45 | const std::shared_ptr &customer)
46 | {
47 | return customer->email;
48 | }
49 | };
50 |
51 | template
52 | static std::vector GetActiveCustomerByFunctionField(
53 | const std::shared_ptr>
54 | &classField);
55 |
--------------------------------------------------------------------------------
/Section06/Step03/Code_Example2.cpp:
--------------------------------------------------------------------------------
1 | template
2 | vector Customer::GetActiveCustomerByFunctionField(
3 | const shared_ptr> &classField)
4 | {
5 | vector returnList;
6 | for (auto customer : Customer::registeredCustomers)
7 | {
8 | if (customer.isActive)
9 | {
10 | returnList.push_back(
11 | classField->InvokeFunction(
12 | make_shared(customer)));
13 | }
14 | }
15 | return returnList;
16 | }
17 |
18 | vector Customer::GetActiveCustomerNames()
19 | {
20 | return Customer::GetActiveCustomerByFunctionField(
21 | make_shared());
22 | }
23 |
24 | vector Customer::GetActiveCustomerAddresses()
25 | {
26 | return Customer::GetActiveCustomerByFunctionField(
27 | make_shared());
28 | }
29 |
30 | vector Customer::GetActiveCustomerPhoneNumbers()
31 | {
32 | return Customer::GetActiveCustomerByFunctionField(
33 | make_shared());
34 | }
35 |
36 | vector Customer::GetActiveCustomerEmails()
37 | {
38 | return Customer::GetActiveCustomerByFunctionField(
39 | make_shared());
40 | }
41 |
--------------------------------------------------------------------------------
/Section06/Step03/Customer.cpp:
--------------------------------------------------------------------------------
1 | /* Customer.cpp - Step03 */
2 | #include "Customer.h"
3 |
4 | using namespace std;
5 |
6 | vector Customer::registeredCustomers;
7 |
8 | vector Customer::GetActiveCustomerNames()
9 | {
10 | return Customer::GetActiveCustomerByFunctionField(
11 | make_shared());
12 | }
13 |
14 | vector Customer::GetActiveCustomerAddresses()
15 | {
16 | return Customer::GetActiveCustomerByFunctionField(
17 | make_shared());
18 | }
19 |
20 | vector Customer::GetActiveCustomerPhoneNumbers()
21 | {
22 | return Customer::GetActiveCustomerByFunctionField(
23 | make_shared());
24 | }
25 |
26 | vector Customer::GetActiveCustomerEmails()
27 | {
28 | return Customer::GetActiveCustomerByFunctionField(
29 | make_shared());
30 | }
31 |
32 | template
33 | vector Customer::GetActiveCustomerByFunctionField(
34 | const shared_ptr> &classField)
35 | {
36 | vector returnList;
37 | for (auto &customer : Customer::registeredCustomers)
38 | {
39 | if (customer.isActive)
40 | {
41 | returnList.push_back(
42 | classField->InvokeFunction(
43 | make_shared(customer)));
44 | }
45 | }
46 | return returnList;
47 | }
48 |
--------------------------------------------------------------------------------
/Section06/Step03/Customer.h:
--------------------------------------------------------------------------------
1 | /* Customer.h - Step03 */
2 | #ifndef __CUSTOMER_H__
3 | #define __CUSTOMER_H__
4 |
5 | #include
6 | #include
7 | #include
8 |
9 | class Customer
10 | {
11 | private:
12 | template
13 | class BaseClass
14 | {
15 | public:
16 | virtual U InvokeFunction(
17 | const std::shared_ptr&) = 0;
18 | };
19 |
20 | class CustomerName :
21 | public BaseClass
22 | {
23 | public:
24 | virtual std::string InvokeFunction(
25 | const std::shared_ptr &customer)
26 | {
27 | return customer->name;
28 | }
29 | };
30 |
31 | class CustomerAddress :
32 | public BaseClass