├── 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 |
24 | 25 | ## Instructions and Navigation 26 | ### Assumed Knowledge 27 | To fully benefit from the coverage included in this course, you will need:
28 | 29 | 30 | ### Technical Requirements 31 | This course has the following software requirements:
32 | 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 33 | { 34 | public: 35 | virtual std::string InvokeFunction( 36 | const std::shared_ptr &customer) 37 | { 38 | return customer->address; 39 | } 40 | }; 41 | 42 | class CustomerPhoneNumber : 43 | public BaseClass 44 | { 45 | public: 46 | virtual std::string InvokeFunction( 47 | const std::shared_ptr &customer) 48 | { 49 | return customer->phoneNumber; 50 | } 51 | }; 52 | 53 | class CustomerEmail : 54 | public BaseClass 55 | { 56 | public: 57 | virtual std::string InvokeFunction( 58 | const std::shared_ptr &customer) 59 | { 60 | return customer->email; 61 | } 62 | }; 63 | 64 | public: 65 | static std::vector registeredCustomers; 66 | int id = 0; 67 | std::string name; 68 | std::string address; 69 | std::string phoneNumber; 70 | std::string email; 71 | bool isActive = true; 72 | 73 | static std::vector GetActiveCustomerNames(); 74 | static std::vector GetActiveCustomerAddresses(); 75 | static std::vector GetActiveCustomerPhoneNumbers(); 76 | static std::vector GetActiveCustomerEmails(); 77 | 78 | template 79 | static std::vector GetActiveCustomerByFunctionField( 80 | const std::shared_ptr> 81 | &classField); 82 | }; 83 | #endif // __CUSTOMER_H__ 84 | -------------------------------------------------------------------------------- /Section06/Step03/Main.cpp: -------------------------------------------------------------------------------- 1 | /* Main.cpp - Step03 */ 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 | Customer c; 31 | c.id = i++; 32 | c.name = name; 33 | c.address = "somewhere"; 34 | c.phoneNumber = "0123"; 35 | c.email = name + "@xyz.com"; 36 | c.isActive = b; 37 | 38 | b = !b; 39 | 40 | Customer::registeredCustomers.push_back(c); 41 | } 42 | } 43 | 44 | auto main() -> int 45 | { 46 | cout << "[Step03]" << endl; 47 | cout << "--------" << endl; 48 | 49 | RegisterCustomers(); 50 | 51 | Customer customer; 52 | 53 | cout << "List of active customer names:" << endl; 54 | vector activeCustomerNames = 55 | customer.GetActiveCustomerNames(); 56 | for (auto &name : activeCustomerNames) 57 | { 58 | cout << name << endl; 59 | } 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /Section06/Step04/Code_Example1.cpp: -------------------------------------------------------------------------------- 1 | template 2 | vector Customer::GetActiveCustomerByFunctionField( 3 | vector customers, 4 | const shared_ptr> 5 | &classField) 6 | { 7 | vector returnList; 8 | for (auto &customer : customers) 9 | { 10 | if (customer.isActive) 11 | { 12 | returnList.push_back( 13 | classField->InvokeFunction( 14 | make_shared(customer))); 15 | } 16 | } 17 | return returnList; 18 | } 19 | 20 | template 21 | static std::vector GetActiveCustomerByFunctionField( 22 | std::vector customers, 23 | const std::shared_ptr> 24 | &classField); 25 | 26 | vector Customer::GetActiveCustomerNames( 27 | vector customers) 28 | { 29 | return Customer::GetActiveCustomerByFunctionField( 30 | customers, 31 | make_shared()); 32 | } 33 | 34 | vector Customer::GetActiveCustomerAddresses( 35 | vector customer) 36 | { 37 | return Customer::GetActiveCustomerByFunctionField( 38 | customer, 39 | make_shared()); 40 | } 41 | 42 | vector Customer::GetActiveCustomerPhoneNumbers( 43 | vector customer) 44 | { 45 | return Customer::GetActiveCustomerByFunctionField( 46 | customer, 47 | make_shared()); 48 | } 49 | 50 | vector Customer::GetActiveCustomerEmails( 51 | vector customer) 52 | { 53 | return Customer::GetActiveCustomerByFunctionField( 54 | customer, 55 | make_shared()); 56 | } 57 | 58 | static std::vector GetActiveCustomerNames( 59 | std::vector customer); 60 | 61 | static std::vector GetActiveCustomerAddresses( 62 | std::vector customer); 63 | 64 | static std::vector GetActiveCustomerPhoneNumbers( 65 | std::vector customer); 66 | 67 | static std::vector GetActiveCustomerEmails( 68 | std::vector customer); 69 | -------------------------------------------------------------------------------- /Section06/Step04/Customer.cpp: -------------------------------------------------------------------------------- 1 | /* Customer.cpp - Step04 */ 2 | #include "Customer.h" 3 | 4 | using namespace std; 5 | 6 | vector Customer::GetActiveCustomerNames( 7 | vector customers) 8 | { 9 | return Customer::GetActiveCustomerByFunctionField( 10 | customers, 11 | make_shared()); 12 | } 13 | 14 | vector Customer::GetActiveCustomerAddresses( 15 | vector customer) 16 | { 17 | return Customer::GetActiveCustomerByFunctionField( 18 | customer, 19 | make_shared()); 20 | } 21 | 22 | vector Customer::GetActiveCustomerPhoneNumbers( 23 | vector customer) 24 | { 25 | return Customer::GetActiveCustomerByFunctionField( 26 | customer, 27 | make_shared()); 28 | } 29 | 30 | vector Customer::GetActiveCustomerEmails( 31 | vector customer) 32 | { 33 | return Customer::GetActiveCustomerByFunctionField( 34 | customer, 35 | make_shared()); 36 | } 37 | 38 | template 39 | vector Customer::GetActiveCustomerByFunctionField( 40 | vector customers, 41 | const shared_ptr> 42 | &classField) 43 | { 44 | vector returnList; 45 | for (auto &customer : customers) 46 | { 47 | if (customer.isActive) 48 | { 49 | returnList.push_back( 50 | classField->InvokeFunction( 51 | make_shared(customer))); 52 | } 53 | } 54 | return returnList; 55 | } 56 | -------------------------------------------------------------------------------- /Section06/Step04/Customer.h: -------------------------------------------------------------------------------- 1 | /* Customer.h - Step04 */ 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 33 | { 34 | public: 35 | virtual std::string InvokeFunction( 36 | const std::shared_ptr &customer) 37 | { 38 | return customer->address; 39 | } 40 | }; 41 | 42 | class CustomerPhoneNumber : 43 | public BaseClass 44 | { 45 | public: 46 | virtual std::string InvokeFunction( 47 | const std::shared_ptr &customer) 48 | { 49 | return customer->phoneNumber; 50 | } 51 | }; 52 | 53 | class CustomerEmail : 54 | public BaseClass 55 | { 56 | public: 57 | virtual std::string InvokeFunction( 58 | const std::shared_ptr &customer) 59 | { 60 | return customer->email; 61 | } 62 | }; 63 | 64 | public: 65 | int id = 0; 66 | std::string name; 67 | std::string address; 68 | std::string phoneNumber; 69 | std::string email; 70 | bool isActive = true; 71 | 72 | static std::vector GetActiveCustomerNames( 73 | std::vector customer); 74 | static std::vector GetActiveCustomerAddresses( 75 | std::vector customer); 76 | static std::vector GetActiveCustomerPhoneNumbers( 77 | std::vector customer); 78 | static std::vector GetActiveCustomerEmails( 79 | std::vector customer); 80 | 81 | template 82 | static std::vector GetActiveCustomerByFunctionField( 83 | std::vector customers, 84 | const std::shared_ptr> 85 | &classField); 86 | }; 87 | #endif // __CUSTOMER_H__ 88 | -------------------------------------------------------------------------------- /Section06/Step04/Main.cpp: -------------------------------------------------------------------------------- 1 | /* Main.cpp - Step04 */ 2 | #include 3 | #include "Customer.h" 4 | 5 | using namespace std; 6 | 7 | vector RegisterCustomers() 8 | { 9 | int i = 0; 10 | bool b = false; 11 | 12 | vector returnValue; 13 | 14 | vector nameList = 15 | { 16 | "William", 17 | "Aiden", 18 | "Rowan", 19 | "Jamie", 20 | "Quinn", 21 | "Haiden", 22 | "Logan", 23 | "Emerson", 24 | "Sherlyn", 25 | "Molly" 26 | }; 27 | 28 | for (auto name : nameList) 29 | { 30 | Customer c; 31 | c.id = i++; 32 | c.name = name; 33 | c.address = "somewhere"; 34 | c.phoneNumber = "0123"; 35 | c.email = name + "@xyz.com"; 36 | c.isActive = b; 37 | 38 | b = !b; 39 | 40 | returnValue.push_back(c); 41 | } 42 | 43 | return returnValue; 44 | } 45 | 46 | auto main() -> int 47 | { 48 | cout << "[Step04]" << endl; 49 | cout << "--------" << endl; 50 | 51 | Customer customer; 52 | 53 | cout << "List of active customer names:" << endl; 54 | vector activeCustomerNames = 55 | customer.GetActiveCustomerNames( 56 | RegisterCustomers()); 57 | for (auto name : activeCustomerNames) 58 | { 59 | cout << name << endl; 60 | } 61 | 62 | return 0; 63 | } 64 | --------------------------------------------------------------------------------