Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ set(PROJECT_NAME_TEST ${PROJECT_NAME}_unit_test) # name for the unit-test execut
# Compiler and language configuration
# ----------------------------------------------------------------------------------------
# Require C++17 for GoogleTest and modern C++ features
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Optionally enforce warnings (good for learning/debugging)
Expand Down Expand Up @@ -124,6 +124,8 @@ set(APP_SOURCES
"src/core/datatypes/container/sequence/Array.cpp"
"src/core/datatypes/container/sequence/Vector.cpp"
"src/core/datatypes/container/unordered/UnorderedMap.cpp"
"src/core/expression/Lambda.cpp"
"src/core/expression/FunctionPointer.cpp"
)

# Test files
Expand Down
61 changes: 61 additions & 0 deletions src/core/expression/FunctionPointer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <algorithm>
#include <iostream>
#include <vector>

namespace {

int increase(int a, int b) {
return a > b;
}

int decrease(int a, int b) {
return a < b;
}

// // Function
// // Declaring
// return_type (*FuncPtr) (parameter type, ....);
typedef int (*SortFcn)(int a, int b);

void run() {
std::vector<int> vect{1, 6, 4, 22, 0, 6, 33, 39, -5};

auto f_print = [](const std::vector<int>& vec) {
for (const auto& e : vec) {
std::cout << e << " ";
}
std::cout << "\n";
};

std::cout << "Before sorting : \n";
f_print(vect);

std::cout << "Sorting in descending "
<< "order \n";

// Use auto
auto sortTypeAuto = increase;
std::sort(vect.begin(), vect.end(), sortTypeAuto);

// Use pointer
SortFcn sortTypePtr = decrease;
f_print(vect);

std::cout << "Sorting with absolute "
<< "value as parameter\n ";
std::sort(vect.begin(), vect.end(), sortTypePtr);

for (auto i : vect)
std::cout << i << " ";
std::cout << "\n";
}
} // namespace

struct FunctionPointer {
FunctionPointer() {
std::cout << "\n--- Function Pointer Example ---\n";
run();
}
};

static FunctionPointer autoRunner;
48 changes: 48 additions & 0 deletions src/core/expression/Lambda.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <algorithm> // for std::sort
// std::sort
// default (1)
// template <class RandomAccessIterator> void sort (RandomAccessIterator first, RandomAccessIterator last);
// custom (2)
// template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

#include <iostream>
#include <vector>

namespace {
void run() {
std::vector<int> vect{-1, -6, 4, 2, 0, 6, 3, 9, -5};

auto f_print = [](const std::vector<int>& vec) {
for (const auto& e : vec) {
std::cout << e << " ";
}
std::cout << "\n";
};

std::cout << "Before sorting : \n";
f_print(vect);

std::cout << "Sorting in descending "
<< "order \n";
std::sort(vect.begin(), vect.end(), [](int a, int b) { return a > b; });

f_print(vect);

std::cout << "Sorting with absolute "
<< "value as parameter\n ";
std::sort(vect.begin(), vect.end(), [](int a, int b) { return a < b; });

for (auto i : vect)
std::cout << i << " ";
std::cout << "\n";
}
} // namespace

struct LambdaRunner {
LambdaRunner() {
std::cout << "\n--- Lambda Expression Example ---\n";
run();
}
};

static LambdaRunner autoRunner;
84 changes: 84 additions & 0 deletions src/core/expression/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Theory

## 1. Lambda Expressions
- In C++11 and later, lambda is a convenient way of defining an anonymous function object right at the location where it's involked or passed as an argument to a function.

- Syntax:
```cpp
[=] () mutable throw() -> int
{
int n = x + y;
return n;
}

```
- `[=]`: capture clause a.k.a lambda introducer
- `()`: (O) pararam list a.k.a lambda declarator
- `mutable`: (O)
- `throw()`: (O)
- `-> int`: (O) trailing-return-type
- body

### 1.1 Capture Clause
- It uses to introduce new variables in its body, specifics which vars are captured, and whether the capture is `by value[=]` or `by reference [&]`.
- An empty capture clause `[]` indicates that the body accesses no vars in the enclosing scope.
- An identifier or `this` cannot appear more than once in a capture scope.
- Since C++14, we can introduce and initialize new vars in the capture scope.
- E.g.
```cpp
int a{};
int b{};

auto f = []{ // no capture
return 1;
}

auto f0 = [a]{ // capture by value
return a+1;
}

auto f1 = [&a]{
return a+=1; // capture by reference (a = 1)
}

auto f2 = [=]{
return a + b; // all capture by value
}

auto f3 = [&]{
a+=1;
b+=1;
return a + b; // all capture by reference
}

auto f4 = [int a{}]{ // no capture
return a;
}
```

## 2. Function Pointers
- A function pointer is a pointer variable that stores the address of a function with a specific return type and parameter list.
- Syntax:
```cpp
// Declare
return_type (*FuncPtr) (parameter type, ....);

// Referencing: Assigning a function’s address to the function pointer.
FuncPtr = function_name;

// 3) Dereferencing: Invoking the function using the pointer. The dereference operator * is optional during function calls.
FuncPtr(10, 20); // Preferred
(*FuncPtr)(10, 20); // Also valid
```

- e.g.
```cpp
void print(int a){
std::cout << a;
}

void (*FuncPtr)(int a);
FuncPtr = print;
FuncPtr(1);
```

16 changes: 16 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
#include "version.h"

int main(int argc, char* argv[]) {
std::cout << std::endl;
if (__cplusplus == 202302L)
std::cout << "C++23";
else if (__cplusplus == 202002L)
std::cout << "C++20";
else if (__cplusplus == 201703L)
std::cout << "C++17";
else if (__cplusplus == 201402L)
std::cout << "C++14";
else if (__cplusplus == 201103L)
std::cout << "C++11";
else if (__cplusplus == 199711L)
std::cout << "C++98";
else
std::cout << "pre-standard C++ or an unknown version: " << __cplusplus;
std::cout << "\n";
std::cout << APP_NAME << " v" << APP_VERSION << std::endl;
std::cout << APP_DESCRIPTION << std::endl;
return 0;
Expand Down