diff --git a/AdvancedCppV2/.gitignore b/AdvancedCppV2/.gitignore
new file mode 100644
index 0000000..259148f
--- /dev/null
+++ b/AdvancedCppV2/.gitignore
@@ -0,0 +1,32 @@
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
diff --git a/AdvancedCppV2/LICENSE b/AdvancedCppV2/LICENSE
new file mode 100644
index 0000000..d15cf3b
--- /dev/null
+++ b/AdvancedCppV2/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2020 Hakim El Hattab, http://hakim.se, and reveal.js contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/agenda.md b/AdvancedCppV2/Presentation/agenda.md
new file mode 100644
index 0000000..ec1d320
--- /dev/null
+++ b/AdvancedCppV2/Presentation/agenda.md
@@ -0,0 +1,26 @@
+
+
+### Agenda
+
+* Cloning and building example project
+* What's new since C++98
+ * C++11
+ * C++14
+ * C++17
+ * C++20
+* Smart pointers
+ - std::unique_ptr<>
+ - std::shared_ptr<>
+ - std::weak_ptr<>
+ - Best practices
+ - Implementation details
+ - Efficiency
+* Templates
+ * Basics
+ * Typetraits
+ * Specializations
+ * Partial specializations
+ * Templates variable
+ * Deduction guides
+
+
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/compilation.md b/AdvancedCppV2/Presentation/compilation.md
new file mode 100644
index 0000000..fc292fa
--- /dev/null
+++ b/AdvancedCppV2/Presentation/compilation.md
@@ -0,0 +1,46 @@
+# Cloning and building example project
+
+___
+
+
+## Setup
+
+* Clone repository: https://github.com/nauka-programowania-MA/AdvancedCppV2
+* Go to exercises/exampleProject
+* Compile it and run:
+ * mkdir build
+ * cd build
+ * cmake ..
+ * make -j4 (where 4 is available threads)
+ * ./ExampleProject
+* Should print Hello World
+
+If you don't have linux, you can use replit
+
+* Click Create C++
+* Name it and confirm with button Create Repl.
+* Click three dot on the rigt top screen and click upload folder
+* Now find your directory with repo and upload it
+* Congratulation, you can use linux shell wit sanitizers, cmake and valgridn support :)
+
+
+___
+
+
+## replit
+
+If you decided to use replit please configure this file: `replit.nix`:
+
+```bash
+{ pkgs }: {
+ deps = [
+ pkgs.clang_12
+ pkgs.ccls
+ pkgs.gdb
+ pkgs.gnumake
+ pkgs.vim
+ pkgs.valgrind
+ pkgs.cmake
+ ];
+}
+```
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/complex/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/complex/CMakeLists.txt
new file mode 100644
index 0000000..1d92400
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/complex/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(Complex)
+
+set(SRC_LIST
+ complex.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/complex/README.md b/AdvancedCppV2/Presentation/exercises/complex/README.md
new file mode 100644
index 0000000..e4d70f3
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/complex/README.md
@@ -0,0 +1,16 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Exercise 1
+
+Write a function that creates `std::complex` number from two provided numbers. If the types of numbers are different, it should create `std::complex` of the first parameter. Usage:
+
+```c++
+std::complex a = makeComplex(4, 5); // both ints
+std::complex b = makeComplex(3.0, 2.0); // both doubles
+std::complex c = makeComplex(1, 5.0); // int, double -> takes int
+```
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/complex/complex.cpp b/AdvancedCppV2/Presentation/exercises/complex/complex.cpp
new file mode 100644
index 0000000..0931381
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/complex/complex.cpp
@@ -0,0 +1 @@
+#include
diff --git a/AdvancedCppV2/Presentation/exercises/complex/soulutions/complex.cpp b/AdvancedCppV2/Presentation/exercises/complex/soulutions/complex.cpp
new file mode 100644
index 0000000..0e1461f
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/complex/soulutions/complex.cpp
@@ -0,0 +1,6 @@
+#include
+
+template
+std::complex makeComplex(T a, U b) {
+ return std::complex{a, static_cast(b)};
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/converter/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/converter/CMakeLists.txt
new file mode 100644
index 0000000..2337c43
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/converter/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(Converter)
+
+set(SRC_LIST
+ converter.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/converter/README.md b/AdvancedCppV2/Presentation/exercises/converter/README.md
new file mode 100644
index 0000000..eb46653
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/converter/README.md
@@ -0,0 +1,18 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Valgrind usage
+
+ > valgrind valgrind_params path/to/binary binary_params, eg:
+ > valgrind --leak-check=full ./Converter
+ > or full output using command: valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./Converter
+
+## Converter exapmle
+
+1. Compile and run Converter application and check memory leaks under valgrind
+2. Fix code using std::unique_ptr and std::make_unique
+3. Find other issues and fix them (use good practise etc...)
diff --git a/AdvancedCppV2/Presentation/exercises/converter/converter.cpp b/AdvancedCppV2/Presentation/exercises/converter/converter.cpp
new file mode 100644
index 0000000..8e7d424
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/converter/converter.cpp
@@ -0,0 +1,59 @@
+#include
+#include
+#include
+
+class Resource {
+public:
+ Resource(const std::string& str): str_(str) {}
+
+ const std::string& str() const {
+ return str_;
+ }
+
+private:
+ std::string str_;
+};
+
+class Converter {
+public:
+ virtual void Convert(Resource* resource) = 0;
+};
+
+class CurlyBracketConverter : public Converter {
+public:
+ virtual void Convert(Resource* resource) {
+ std::cout << "{" << resource->str() << "}\n";
+ }
+};
+
+class SquareBracketConverter : public Converter {
+public:
+ virtual void Convert(Resource* resource) {
+ std::cout << "[" << resource->str() << "]\n";
+ }
+};
+
+class Printer {
+public:
+ Printer(Converter* converter): converter_(converter) {}
+
+ void Print(Resource* resource) {
+ converter_->Convert(resource);
+ }
+
+private:
+ Converter* converter_;
+};
+
+int main() {
+ Resource* resource = new Resource("Ala has a cat");
+ Printer printer(new SquareBracketConverter{});
+ Printer printer2(new CurlyBracketConverter{});
+
+ printer.Print(resource);
+ printer2.Print(resource);
+
+ delete resource;
+
+ return 0;
+}
diff --git a/AdvancedCppV2/Presentation/exercises/converter/solution/converter.cpp b/AdvancedCppV2/Presentation/exercises/converter/solution/converter.cpp
new file mode 100644
index 0000000..0677212
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/converter/solution/converter.cpp
@@ -0,0 +1,84 @@
+#include
+#include
+#include
+
+class Resource {
+public:
+ explicit Resource(const std::string& str): str_(str) {}
+
+ const std::string& str() const {
+ return str_;
+ }
+
+private:
+ std::string str_;
+};
+
+class Converter {
+public:
+ Converter() = default;
+
+ // Rule of 5
+ virtual ~Converter() = default;
+ Converter(const Converter& other) = default;
+ Converter(Converter&& other) = default;
+ Converter& operator=(const Converter& other) = default;
+ Converter& operator=(Converter&& other) = default;
+
+ virtual void Convert(const std::unique_ptr& resource) const = 0;
+};
+
+class CurlyBracketConverter : public Converter {
+public:
+ void Convert(const std::unique_ptr& resource) const override {
+ std::cout << "{" << resource->str() << "}\n";
+ }
+};
+
+class SquareBracketConverter : public Converter {
+public:
+ virtual void Convert(const std::unique_ptr& resource) const override{
+ std::cout << "[" << resource->str() << "]\n";
+ }
+};
+
+class Printer {
+public:
+ explicit Printer(std::unique_ptr&& converter) noexcept : converter_(std::move(converter)) {}
+
+ void Print(const std::unique_ptr& resource) const {
+ converter_->Convert(resource);
+ }
+
+private:
+ std::unique_ptr converter_;
+};
+
+struct Foo {
+ Foo(std::unique_ptr ptr);
+};
+
+struct Bar {
+ use(std::unique_ptr ptr);
+};
+
+struct MockFoo {};
+
+TEST() {
+ std::unique_ptr mock;
+ MockFoo* mock_ptr = mock.get();
+ Bar bar;
+ bar.use(std::move(mock));
+
+ EXPECT_CALL(mock_ptr, use);
+}
+
+int main() {
+ auto resource = std::make_unique("Ala has a cat");
+ Printer printer(std::make_unique());
+ Printer printer2(std::make_unique());
+ printer.Print(resource);
+ printer2.Print(resource);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/exampleProject/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/exampleProject/CMakeLists.txt
new file mode 100644
index 0000000..21e3c97
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/exampleProject/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(ExampleProject)
+
+set(SRC_LIST
+ exampleProject.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+# target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/exampleProject/README.md b/AdvancedCppV2/Presentation/exercises/exampleProject/README.md
new file mode 100644
index 0000000..14082ac
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/exampleProject/README.md
@@ -0,0 +1,10 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Run program
+
+Run program ./ExampleProject and check output, which should be "Hello World";
diff --git a/AdvancedCppV2/Presentation/exercises/exampleProject/exampleProject.cpp b/AdvancedCppV2/Presentation/exercises/exampleProject/exampleProject.cpp
new file mode 100644
index 0000000..4229ba4
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/exampleProject/exampleProject.cpp
@@ -0,0 +1,7 @@
+#include
+#include
+
+int main() {
+ const std::string str("Hello world!\n");
+ std::cout << str << '\n';
+}
diff --git a/AdvancedCppV2/Presentation/exercises/list/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/list/CMakeLists.txt
new file mode 100644
index 0000000..752b75d
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/list/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(List)
+
+set(SRC_LIST
+ list.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/list/README.md b/AdvancedCppV2/Presentation/exercises/list/README.md
new file mode 100644
index 0000000..934b308
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/list/README.md
@@ -0,0 +1,25 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Valgrind usage
+
+ > valgrind valgrind_params path/to/binary binary_params, eg:
+ > valgrind --leak-check=full ./List
+ > or full output using command: valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./List
+
+## Resource exapmle
+
+Take a look at `list.cpp` file, where simple (and buggy) single-linked list is implemented.
+
+* `pushFront` method adds a new `Node` at the begining of the list.
+* `findByValue` method iterates over the list and returns the first Node with matching `value` or `nullptr`.
+
+1. Compile and run List application
+2. Fix memory leaks without introducing smart pointers
+3. Fix memory leaks with smart pointers. What kind of pointers needs to be applied and why?
+4. Add function to add a node at the end of the list (try to do this with time complexity O(1))
+5. Add function to delete node with provided value.
diff --git a/AdvancedCppV2/Presentation/exercises/list/list.cpp b/AdvancedCppV2/Presentation/exercises/list/list.cpp
new file mode 100644
index 0000000..15ad44b
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/list/list.cpp
@@ -0,0 +1,68 @@
+#include
+
+class Node {
+public:
+ Node(const int value, Node* next)
+ : next_(next), value_(value) {}
+
+ explicit Node(const int v)
+ : Node(v, nullptr) {}
+
+ const Node* next() const { return next_; }
+ int value() const { return value_; }
+
+private:
+ Node* next_;
+ int value_;
+};
+
+class List {
+public:
+ void pushFront(int value) {
+ if (!head_) {
+ head_ = new Node(value);
+ return;
+ }
+
+ head_ = new Node(value, head_);
+ }
+
+ const Node* findByValue(const int value) const {
+ const auto* current = head_;
+
+ while (current) {
+ if (current->value() == value) {
+ return current;
+ }
+ current = current->next();
+ }
+
+ return nullptr;
+ }
+
+private:
+ Node* head_ = nullptr;
+};
+
+int main() {
+ List list;
+
+ list.pushFront(4);
+ list.pushFront(2);
+ list.pushFront(7);
+ list.pushFront(9);
+
+ if (const auto* const node = list.findByValue(1)) {
+ std::cout << node->value() << '\n';
+ } else {
+ std::cout << "can't find node with value 1\n";
+ }
+
+ if (const auto* const node = list.findByValue(7)) {
+ std::cout << node->value() << '\n';
+ } else {
+ std::cout << "can't find node with value 7\n";
+ }
+
+ return 0;
+}
diff --git a/AdvancedCppV2/Presentation/exercises/list/solution/list.cpp b/AdvancedCppV2/Presentation/exercises/list/solution/list.cpp
new file mode 100644
index 0000000..f9da679
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/list/solution/list.cpp
@@ -0,0 +1,76 @@
+#include
+#include
+#include
+
+class Node {
+public:
+ Node(const int value, std::unique_ptr next)
+ : next_(std::move(next)), value_(value) {}
+
+ explicit Node(const int v)
+ : Node(v, nullptr) {}
+
+ const Node* next() const { return next_.get(); }
+ int value() const { return value_; }
+ std::unique_ptr getNext() { return std::move(next_); }
+
+private:
+ std::unique_ptr next_;
+ int value_;
+};
+
+// 1
+// 2 -> 1
+// 3 -> 2 -> 1
+// 4 -> 3 -> 2 -> 1
+
+class List {
+public:
+ void pushFront(int value) {
+ if (!head_) {
+ head_ = std::make_unique(value);
+ return;
+ }
+
+ head_ = std::make_unique(value, std::move(head_));
+ }
+
+ const Node* findByValue(const int value) const {
+ const auto* current = head_.get();
+
+ while (current) {
+ if (current->value() == value) {
+ return current;
+ }
+ current = current->next();
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::unique_ptr head_;
+};
+
+int main() {
+ List list;
+
+ list.pushFront(4);
+ list.pushFront(2);
+ list.pushFront(7);
+ list.pushFront(9);
+
+ if (const auto* const node = list.findByValue(1)) {
+ std::cout << node->value() << '\n';
+ } else {
+ std::cout << "can't find node with value 1\n";
+ }
+
+ if (const auto* const node = list.findByValue(7)) {
+ std::cout << node->value() << '\n';
+ } else {
+ std::cout << "can't find node with value 7\n";
+ }
+
+ return 0;
+}
diff --git a/AdvancedCppV2/Presentation/exercises/list/solution/list2.cpp b/AdvancedCppV2/Presentation/exercises/list/solution/list2.cpp
new file mode 100644
index 0000000..6f545ee
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/list/solution/list2.cpp
@@ -0,0 +1,181 @@
+#include
+#include
+#include
+
+class Node {
+public:
+ Node(const int value, std::unique_ptr next)
+ : next_(std::move(next)), value_(value) {}
+
+ explicit Node(const int v)
+ : Node(v, nullptr) {}
+
+ const Node* next() const { return next_.get(); }
+ Node* next() { return next_.get(); }
+ int value() const { return value_; }
+ void setNext(std::unique_ptr next) { next_ = std::move(next); }
+ std::unique_ptr getNext() { return std::move(next_); }
+
+private:
+ std::unique_ptr next_;
+ int value_;
+};
+
+// ht
+// 1
+// h t
+// 2 -> 1
+// h t
+// 3 -> 2 -> 1
+// h t
+// 4 -> 3 -> 2 -> 1
+// h t
+// 4 -> 3 -> 2 -> 1 -> 5
+//
+// 3 -> 2 -> 1 -> 5
+// 3 -> 1 -> 5
+
+class List {
+public:
+ void pushFront(int value) {
+ if (!head_) {
+ pushHead(value);
+ return;
+ }
+
+ head_ = std::make_unique(value, std::move(head_));
+ }
+
+ void pushBack(int value) {
+ if (!tail_) {
+ pushHead(value);
+ return;
+ }
+
+ tail_->setNext(std::make_unique(value));
+ tail_ = tail_->next();
+ }
+
+ bool erase(int value) {
+ // Remove head
+ if (head_ && head_->value() == value) {
+ head_ = head_->getNext();
+ if (!head_) {
+ tail_ = nullptr;
+ }
+ return true;
+ }
+
+ if (auto* node = findPrevNode(value)) {
+ // Remove tail
+ if (node->next() == tail_) {
+ tail_ = node;
+ }
+ node->setNext(std::move(node->next()->getNext()));
+ return true;
+ }
+
+ return false;
+ }
+
+ const Node* findByValue(const int value) const {
+ const auto* current = head_.get();
+
+ while (current) {
+ if (current->value() == value) {
+ return current;
+ }
+ current = current->next();
+ }
+
+ return nullptr;
+ }
+
+ void print() const {
+ const auto* current = head_.get();
+
+ while (current) {
+ std::cout << current->value() << ' ';
+ current = current->next();
+ }
+ std::cout << '\n';
+ }
+
+private:
+ // ht
+ // 1
+ // h t
+ // 2 -> 1
+ // h t
+ // 2 -> 1 -> 3
+ // 2 -> 3
+ void pushHead(int value) {
+ head_ = std::make_unique(value);
+ tail_ = head_.get();
+ }
+
+ Node* findPrevNode(const int value) const {
+ auto* current = head_.get();
+ Node* prev = nullptr;
+
+ while (current) {
+ if (current->value() == value) {
+ return prev;
+ }
+ prev = current;
+ current = current->next();
+ }
+
+ return nullptr;
+ }
+
+ std::unique_ptr head_;
+ Node* tail_{nullptr};
+};
+
+int main() {
+ List list;
+
+ list.pushFront(4);
+ list.pushFront(2);
+ list.pushFront(7);
+ list.pushFront(9);
+ list.print();
+
+ if (const auto* const node = list.findByValue(1)) {
+ std::cout << node->value() << '\n';
+ } else {
+ std::cout << "can't find node with value 1\n";
+ }
+
+ if (const auto* const node = list.findByValue(7)) {
+ std::cout << node->value() << '\n';
+ } else {
+ std::cout << "can't find node with value 7\n";
+ }
+
+ list.pushBack(10);
+ list.print();
+ list.pushBack(12);
+ list.pushFront(3);
+ list.pushFront(5);
+ list.pushBack(13);
+ list.print();
+
+ list.erase(2);
+ list.print();
+
+ list.erase(5);
+ list.print();
+
+ list.erase(13);
+ list.print();
+
+ list.erase(12);
+ list.print();
+
+ list.pushBack(40);
+ list.print();
+
+ return 0;
+}
diff --git a/AdvancedCppV2/Presentation/exercises/map/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/map/CMakeLists.txt
new file mode 100644
index 0000000..52a7691
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/map/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(Map)
+
+set(SRC_LIST
+ map.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/map/README.md b/AdvancedCppV2/Presentation/exercises/map/README.md
new file mode 100644
index 0000000..f926fc2
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/map/README.md
@@ -0,0 +1,55 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Exercise 1
+
+Write a template class `VectorMap` that represents an over-engineered `std::map`.
+
+Inside, it should hold 2 `std::vectors` of the same size, each with different types. The first vector should hold keys, the other one values.
+
+Elements at the same position in both vectors should create a pair like `1` and `'c'` below.
+
+```c++
+VectorMap map;
+map.insert(1, 'c');
+map[1] = 'e'; // replaces value under 1
+std::cout << map[1]; // prints 'e'
+map.at(2); // throw std::out_of_range
+```
+
+Implement the mentioned above `insert()`, `operator[]`, `at()` methods.
+
+Do not bother about duplicated keys for now.
+You can also try to implement additional methods from the `std::map` interface 🙂
+
+Use [cppreference](http://en.cppreference.com/w/cpp/container/map).
+
+## Exercise 2 - `static_assert`
+
+Add a constraint to our `VectorMap`.
+
+Do not allow to create an object when `ValueType` does not have a default constructor.
+
+Use `static_assert` and proper trait from [``](https://en.cppreference.com/w/cpp/types#Type_traits) library.
+
+Check if it works properly.
+
+## Exercise 3 - `isIntKey()`
+
+Write a function `isIntKey()` in `VectorMap`. It should return `true` when the KeyType is `int` and `false` otherwise.
+
+Check the [``](https://en.cppreference.com/w/cpp/types#Type_traits) library for some inspiration 🙂
+
+# Exercie 4
+
+Write a partial specialization of `VectorMap` for boolean keys. We can have only 2 values for boolean keys. There is no need to keep vectors inside.
+
+Implement properly all currently available functions.
+
+# Exercie 5
+
+Write a variable template `is_int_key_v`. It should return a value of the `is_int_key` field in a given template type.
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/map/map.cpp b/AdvancedCppV2/Presentation/exercises/map/map.cpp
new file mode 100644
index 0000000..23b74e9
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/map/map.cpp
@@ -0,0 +1,4 @@
+#include
+#include
+#include
+#include
diff --git a/AdvancedCppV2/Presentation/exercises/map/soultions/map1.cpp b/AdvancedCppV2/Presentation/exercises/map/soultions/map1.cpp
new file mode 100644
index 0000000..948ea21
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/map/soultions/map1.cpp
@@ -0,0 +1,44 @@
+#include
+#include
+#include
+#include
+
+template
+class VectorMap {
+ std::vector keys_;
+ std::vector values_;
+
+public:
+ using K = Key;
+ using V = Value;
+
+ void insert(const Key& k, const Value& v) {
+ keys_.emplace_back(k);
+ values_.emplace_back(v);
+ }
+
+ Value& operator[](const Key& k);
+ Value& at(const Key& k);
+};
+
+template
+Value& VectorMap::operator[](const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ keys_.emplace_back(k);
+ values_.emplace_back(Value{});
+ return values_.back();
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
+
+template
+Value& VectorMap::at(const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ throw std::out_of_range("This key does not exist");
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
diff --git a/AdvancedCppV2/Presentation/exercises/map/soultions/map2.cpp b/AdvancedCppV2/Presentation/exercises/map/soultions/map2.cpp
new file mode 100644
index 0000000..cd20dd2
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/map/soultions/map2.cpp
@@ -0,0 +1,54 @@
+#include
+#include
+#include
+#include
+
+template
+class VectorMap {
+ std::vector keys_;
+ std::vector values_;
+
+ static_assert(std::is_default_constructible::value, "Value should have the default constructor");
+ static_assert(std::is_default_constructible_v, "Value should have the default constructor");
+
+public:
+ using K = Key;
+ using V = Value;
+ void insert(const Key& k, const Value& v) {
+ keys_.emplace_back(k);
+ values_.emplace_back(v);
+ }
+
+ static constexpr bool isIntKey() {
+ // if (std::is_integral_v) {
+ if (std::is_same_v) {
+ return true;
+ }
+ return false;
+ }
+
+ Value& operator[](const Key& k);
+ Value& at(const Key& k);
+};
+
+template
+Value& VectorMap::operator[](const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ keys_.emplace_back(k);
+ values_.emplace_back(Value{});
+ return values_.back();
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
+
+template
+Value& VectorMap::at(const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ throw std::out_of_range("This key does not exist");
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
diff --git a/AdvancedCppV2/Presentation/exercises/map/soultions/map3.cpp b/AdvancedCppV2/Presentation/exercises/map/soultions/map3.cpp
new file mode 100644
index 0000000..a0f966b
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/map/soultions/map3.cpp
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+#include
+
+template
+class VectorMap {
+ std::vector keys_;
+ std::vector values_;
+
+ static_assert(std::is_default_constructible::value, "Value should have the default constructor");
+ static_assert(std::is_default_constructible_v, "Value should have the default constructor");
+
+public:
+ using K = Key;
+ using V = Value;
+ void insert(const Key& k, const Value& v) {
+ keys_.emplace_back(k);
+ values_.emplace_back(v);
+ }
+
+ static constexpr bool isIntKey() {
+ // if (std::is_integral_v) {
+ if (std::is_same_v) {
+ return true;
+ }
+ return false;
+ }
+
+ Value& operator[](const Key& k);
+ Value& at(const Key& k);
+
+ static constexpr bool is_int_key = std::is_same_v;
+};
+
+template
+Value& VectorMap::operator[](const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ keys_.emplace_back(k);
+ values_.emplace_back(Value{});
+ return values_.back();
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
+
+template
+Value& VectorMap::at(const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ throw std::out_of_range("This key does not exist");
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
diff --git a/AdvancedCppV2/Presentation/exercises/map/soultions/map4.cpp b/AdvancedCppV2/Presentation/exercises/map/soultions/map4.cpp
new file mode 100644
index 0000000..9c7a510
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/map/soultions/map4.cpp
@@ -0,0 +1,125 @@
+#include
+#include
+#include
+#include
+
+template
+class VectorMap {
+ std::vector keys_;
+ std::vector values_;
+
+ static_assert(std::is_default_constructible::value, "Value should have the default constructor");
+ static_assert(std::is_default_constructible_v, "Value should have the default constructor");
+
+public:
+ using K = Key;
+ using V = Value;
+ template
+ using iterator = typename std::vector::iterator;
+
+ void insert(const Key& k, const Value& v) {
+ keys_.emplace_back(k);
+ values_.emplace_back(v);
+ }
+
+ static constexpr bool isIntKey() {
+ // if (std::is_integral_v) {
+ if (std::is_same_v) {
+ return true;
+ }
+ return false;
+ }
+
+ Value& operator[](const Key& k);
+ Value& at(const Key& k);
+
+ static constexpr bool is_int_key = std::is_same_v;
+};
+
+template
+Value& VectorMap::operator[](const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ keys_.emplace_back(k);
+ values_.emplace_back(Value{});
+ return values_.back();
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
+
+template
+Value& VectorMap::at(const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ throw std::out_of_range("This key does not exist");
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
+
+
+template
+class VectorMap { // specialization
+ static_assert(std::is_default_constructible::value,
+ "ValueType must have the default constructor");
+
+ ValueType t_;
+ ValueType f_;
+
+public:
+ static constexpr bool is_int_key = false; // type_traits #2
+
+ VectorMap() {
+ std::cout << "bool specialization used\n";
+ }
+
+ void insert(bool key, ValueType&& value) {
+ if (key) {
+ t_ = value;
+ } else {
+ f_ = value;
+ }
+ }
+
+ ValueType& operator[](bool key) {
+ if (key) {
+ return t_;
+ }
+ return f_;
+ }
+
+ ValueType& at(bool key) {
+ if (key) {
+ return t_;
+ }
+ return f_;
+ }
+};
+
+int main() {
+ VectorMap map;
+ // VectorMap::iterator k;
+ map.insert(1, 'c');
+ std::cout << map[1] << '\n';
+ map[1] = 'e'; // replaces value under 1
+ std::cout << map[1] << '\n'; // prints 'e'
+ // map.at(2); // throw std::out_of_range
+ std::cout << std::boolalpha << map.isIntKey() << '\n';
+ std::cout << std::boolalpha << map.is_int_key << '\n';
+
+ VectorMap map3;
+ std::cout << std::boolalpha << map3.isIntKey() << '\n';
+
+ VectorMap map4;
+ map4.insert(true, 3);
+ map4.insert(false, 0);
+ std::cout << map4[true] << '\n';
+ map4[true] = 10; // replaces value under 1
+ std::cout << map4[true] << '\n'; // prints 'e'
+
+ std::vector v{1, 2, 3};
+ find(begin(v), end(v), 2);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/map/soultions/map5.cpp b/AdvancedCppV2/Presentation/exercises/map/soultions/map5.cpp
new file mode 100644
index 0000000..4e3d4c9
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/map/soultions/map5.cpp
@@ -0,0 +1,134 @@
+#include
+#include
+#include
+#include
+
+template
+class VectorMap {
+ std::vector keys_;
+ std::vector values_;
+
+ static_assert(std::is_default_constructible::value, "Value should have the default constructor");
+ static_assert(std::is_default_constructible_v, "Value should have the default constructor");
+
+public:
+ using K = Key;
+ using V = Value;
+ template
+ using iterator = typename std::vector::iterator;
+
+ void insert(const Key& k, const Value& v) {
+ keys_.emplace_back(k);
+ values_.emplace_back(v);
+ }
+
+ static constexpr bool isIntKey() {
+ // if (std::is_integral_v) {
+ if (std::is_same_v) {
+ return true;
+ }
+ return false;
+ }
+
+ Value& operator[](const Key& k);
+ Value& at(const Key& k);
+
+ static constexpr bool is_int_key = std::is_same_v;
+};
+
+template
+Value& VectorMap::operator[](const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ keys_.emplace_back(k);
+ values_.emplace_back(Value{});
+ return values_.back();
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
+
+template
+Value& VectorMap::at(const Key& k) {
+ auto it = std::find(std::begin(keys_), std::end(keys_), k);
+ if (it == std::end(keys_)) {
+ throw std::out_of_range("This key does not exist");
+ }
+ auto dist = std::distance(keys_.begin(), it);
+ return values_[dist];
+}
+
+
+template
+class VectorMap { // specialization
+ static_assert(std::is_default_constructible::value,
+ "ValueType must have the default constructor");
+
+ ValueType t_;
+ ValueType f_;
+
+public:
+ static constexpr bool is_int_key = false; // type_traits #2
+
+ VectorMap() {
+ std::cout << "bool specialization used\n";
+ }
+
+ void insert(bool key, ValueType&& value) {
+ if (key) {
+ t_ = value;
+ } else {
+ f_ = value;
+ }
+ }
+
+ ValueType& operator[](bool key) {
+ if (key) {
+ return t_;
+ }
+ return f_;
+ }
+
+ ValueType& at(bool key) {
+ if (key) {
+ return t_;
+ }
+ return f_;
+ }
+};
+
+template
+constexpr bool is_int_key_v = T::is_int_key;
+
+template
+constexpr bool is_int_key_v1 = VectorMap::is_int_key;
+
+int main() {
+ VectorMap map;
+ // VectorMap::iterator k;
+ map.insert(1, 'c');
+ std::cout << map[1] << '\n';
+ map[1] = 'e'; // replaces value under 1
+ std::cout << map[1] << '\n'; // prints 'e'
+ // map.at(2); // throw std::out_of_range
+ std::cout << std::boolalpha << map.isIntKey() << '\n';
+ std::cout << std::boolalpha << map.is_int_key << '\n';
+
+ VectorMap map3;
+ std::cout << std::boolalpha << map3.isIntKey() << '\n';
+
+ VectorMap map4;
+ map4.insert(true, 3);
+ map4.insert(false, 0);
+ std::cout << map4[true] << '\n';
+ map4[true] = 10; // replaces value under 1
+ std::cout << map4[true] << '\n'; // prints 'e'
+ std::cout << std::boolalpha << is_int_key_v << '\n';
+ std::cout << std::boolalpha << is_int_key_v << '\n';
+ std::cout << std::boolalpha << is_int_key_v << '\n';
+
+ std::vector v{1, 2, 3};
+ find(begin(v), end(v), 2);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/resource/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/resource/CMakeLists.txt
new file mode 100644
index 0000000..78dd153
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/resource/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(Resource)
+
+set(SRC_LIST
+ resource.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/resource/README.md b/AdvancedCppV2/Presentation/exercises/resource/README.md
new file mode 100644
index 0000000..74cb103
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/resource/README.md
@@ -0,0 +1,19 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Valgrind usage
+
+ > valgrind valgrind_params path/to/binary binary_params, eg:
+ > valgrind --leak-check=full ./Resource 5
+ > or full output using command: valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./Resource
+
+## Resource exapmle
+
+1. Compile and run Resource application and check memory leaks under valgrind
+2. Fix memory leaks with a proper usage of delete operator
+3. Refactor the solution to use `std::unique_ptr<>`
+4. Use `std::make_unique`
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/resource/resource.cpp b/AdvancedCppV2/Presentation/exercises/resource/resource.cpp
new file mode 100644
index 0000000..e0c201a
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/resource/resource.cpp
@@ -0,0 +1,32 @@
+#include
+#include
+#include
+
+class Resource {
+public:
+ void use(const char* N) {
+ std::cout << "Using resource. Passed " << *N << '\n';
+ if (*N == 'd') {
+ throw std::logic_error("Passed d. d is prohibited.");
+ }
+ };
+};
+
+int main(int argc, char* argv[]) {
+ if (argc != 2) {
+ std::cerr << "You need to pass 1 argument" << '\n';
+ exit(-1);
+ }
+
+ const char* arg = argv[1];
+ Resource* rsc = nullptr;
+
+ try {
+ rsc = new Resource();
+ rsc->use(arg);
+ delete rsc;
+ } catch (std::logic_error& e) {
+ std::cout << e.what() << '\n';
+ }
+ return 0;
+}
diff --git a/AdvancedCppV2/Presentation/exercises/resource/solution/resource.cpp b/AdvancedCppV2/Presentation/exercises/resource/solution/resource.cpp
new file mode 100644
index 0000000..cb23290
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/resource/solution/resource.cpp
@@ -0,0 +1,32 @@
+#include
+#include
+#include
+
+class Resource {
+public:
+ void use(const char* N) {
+ std::cout << "Using resource. Passed " << *N << '\n';
+ if (*N == 'd') {
+ throw std::logic_error("Passed d. d is prohibited.");
+ }
+ };
+};
+
+int main(int argc, char* argv[]) {
+ if (argc != 2) {
+ std::cerr << "You need to pass 1 argument" << '\n';
+ exit(-1);
+ }
+
+ const char* arg = argv[1];
+ std::unique_ptr rsc;
+
+ try {
+ rsc = std::make_unique();
+ rsc->use(arg);
+ } catch (std::logic_error& e) {
+
+ }
+
+ return 0;
+}
diff --git a/AdvancedCppV2/Presentation/exercises/resourceFactory/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/resourceFactory/CMakeLists.txt
new file mode 100644
index 0000000..663bf30
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/resourceFactory/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(ResourceFactory)
+
+set(SRC_LIST
+ resourceFactory.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/resourceFactory/README.md b/AdvancedCppV2/Presentation/exercises/resourceFactory/README.md
new file mode 100644
index 0000000..c2581f2
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/resourceFactory/README.md
@@ -0,0 +1,20 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Valgrind usage
+
+ > valgrind valgrind_params path/to/binary binary_params, eg:
+ > valgrind --leak-check=full ./ResourceFactory
+ > or full output using command: valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./ResourceFactory
+
+## Resource exapmle
+
+1. Compile and run ResourceFactory application
+2. Put comments in places where you can spot some problems
+3. How to remove elements from the collection (vector<Resource*> resources)?
+4. Check memory leaks
+5. Fix problems
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/resourceFactory/resourceFactory.cpp b/AdvancedCppV2/Presentation/exercises/resourceFactory/resourceFactory.cpp
new file mode 100644
index 0000000..959f82f
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/resourceFactory/resourceFactory.cpp
@@ -0,0 +1,65 @@
+#include
+#include
+#include
+
+struct Resource
+{
+ Resource(char* byte) : byte_(byte) {}
+ char* byte() const { return byte_; }
+ virtual std::string name() const = 0;
+ ~Resource() { delete byte_; }
+
+protected:
+ char* byte_ = nullptr;
+};
+
+struct ResourceA : Resource
+{
+ ResourceA(char* byte) : Resource(byte) {}
+ std::string name() const override { return std::string("ResourceA ").append(byte_); }
+};
+
+struct ResourceB : Resource
+{
+ ResourceB(char* byte) : Resource(byte) {}
+ std::string name() const override { return std::string("ResourceB ").append(byte_); }
+};
+
+struct ResourceFactory
+{
+ Resource* makeResourceA(char* byte) { return new ResourceA{byte}; }
+ Resource* makeResourceB(char* byte) { return new ResourceB{byte}; }
+};
+
+struct ResourceCollection
+{
+ void add(Resource* r) { resources.push_back(r); }
+ void clear() { resources.clear(); }
+ Resource* operator[](int index) { return resources[index]; }
+ void printAll()
+ {
+ for (const auto & res : resources)
+ {
+ std::cout << res->name() << std::endl;
+ }
+ }
+
+private:
+ std::vector resources;
+};
+
+int main()
+{
+ ResourceCollection collection;
+ ResourceFactory rf;
+ collection.add(rf.makeResourceA(new char{91}));
+ collection.add(rf.makeResourceB(new char{92}));
+ collection.printAll();
+
+ auto firstByte = collection[0]->byte();
+ collection.clear();
+ std::cout << *firstByte << std::endl;
+
+ return 0;
+}
+
diff --git a/AdvancedCppV2/Presentation/exercises/resourceFactory/soultions/resourceFactory.cpp b/AdvancedCppV2/Presentation/exercises/resourceFactory/soultions/resourceFactory.cpp
new file mode 100644
index 0000000..2be86a1
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/resourceFactory/soultions/resourceFactory.cpp
@@ -0,0 +1,77 @@
+#include
+#include
+#include
+#include
+#include
+
+struct Resource {
+ Resource(std::unique_ptr byte)
+ : byte_(std::move(byte)) {}
+ virtual ~Resource() = default;
+ // Rule of 5
+
+ char* byte() const { return byte_.get(); }
+ virtual std::string name() const = 0;
+
+protected:
+ std::unique_ptr byte_;
+};
+
+struct ResourceA : Resource {
+ ~ResourceA() override {
+ std::cout << "ResourceA D'tor\n";
+ }
+
+ ResourceA(std::unique_ptr byte)
+ : Resource(std::move(byte)) {}
+ std::string name() const override { return std::string("ResourceA ").append(1, *byte_); }
+};
+
+struct ResourceB : Resource {
+ ~ResourceB() override {
+ std::cout << "ResourceB D'tor\n";
+ }
+
+ ResourceB(std::unique_ptr byte)
+ : Resource(std::move(byte)) {}
+ std::string name() const override { return std::string("ResourceB ") + *byte_; }
+};
+
+struct ResourceFactory {
+ static std::unique_ptr makeResourceA(std::unique_ptr byte) {
+ return std::make_unique(std::move(byte));
+ }
+ static std::unique_ptr makeResourceB(std::unique_ptr byte) {
+ return std::make_unique(std::move(byte));
+ }
+};
+
+struct ResourceCollection {
+ void add(std::unique_ptr r) { resources.push_back(std::move(r)); }
+ void clear() { resources.clear(); }
+ Resource* operator[](int index) const { return resources[index].get(); }
+ void printAll() const {
+ for (const auto& res : resources) {
+ std::cout << res->name() << '\n';
+ }
+ }
+
+private:
+ std::vector> resources;
+};
+
+int main() {
+ ResourceCollection collection;
+ collection.add(ResourceFactory::makeResourceA(std::make_unique(0x78)));
+ collection.add(ResourceFactory::makeResourceB(std::make_unique(0x79)));
+ collection.printAll();
+
+ auto* firstByte = collection[0]->byte();
+ std::cout << *firstByte << '\n';
+
+ collection.clear();
+ // Use already free memory!
+ //std::cout << *firstByte << '\n';
+
+ return 0;
+}
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/searcher/CMakeLists.txt
new file mode 100644
index 0000000..36f5eb9
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(Searcher)
+
+set(SRC_LIST
+ searcher.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/README.md b/AdvancedCppV2/Presentation/exercises/searcher/README.md
new file mode 100644
index 0000000..34e1bab
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/README.md
@@ -0,0 +1,11 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Exercise
+
+* Open project searcher
+* Implement function `searchFiles` which returns all files containing `keyWord`.
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/files/fileA.cpp b/AdvancedCppV2/Presentation/exercises/searcher/files/fileA.cpp
new file mode 100644
index 0000000..02a351d
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/files/fileA.cpp
@@ -0,0 +1 @@
+Hello FileA
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/files/fileA.hpp b/AdvancedCppV2/Presentation/exercises/searcher/files/fileA.hpp
new file mode 100644
index 0000000..2df259e
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/files/fileA.hpp
@@ -0,0 +1 @@
+Hello FileA Ala ma kota
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/files/fileB.cpp b/AdvancedCppV2/Presentation/exercises/searcher/files/fileB.cpp
new file mode 100644
index 0000000..0cfda48
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/files/fileB.cpp
@@ -0,0 +1 @@
+Hello FileB ALA
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/files/fileB.hpp b/AdvancedCppV2/Presentation/exercises/searcher/files/fileB.hpp
new file mode 100644
index 0000000..353e76f
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/files/fileB.hpp
@@ -0,0 +1 @@
+Hello FileB ala
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/files/fileC.cpp b/AdvancedCppV2/Presentation/exercises/searcher/files/fileC.cpp
new file mode 100644
index 0000000..048655a
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/files/fileC.cpp
@@ -0,0 +1 @@
+Hello FileC ala kot i ala
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/files/fileC.hpp b/AdvancedCppV2/Presentation/exercises/searcher/files/fileC.hpp
new file mode 100644
index 0000000..414da62
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/files/fileC.hpp
@@ -0,0 +1 @@
+Hello FileC ala kot i Ala i nie ma kota
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/searcher.cpp b/AdvancedCppV2/Presentation/exercises/searcher/searcher.cpp
new file mode 100644
index 0000000..9fe212c
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/searcher.cpp
@@ -0,0 +1,26 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace fs = std::filesystem;
+namespace rn = std::ranges;
+
+std::vector searchFiles(std::string_view keyWord, const fs::path& dirName) {
+ std::vector paths;
+
+ // Write implementation here
+
+ return paths;
+}
+
+int main() {
+ std::cout << "Files which contains word Ala:\n";
+ const auto& res = searchFiles("Ala", fs::current_path().string() + "/files");
+ rn::copy(res, std::ostream_iterator(std::cout, "\n"));
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/searcher/solution/searcher.cpp b/AdvancedCppV2/Presentation/exercises/searcher/solution/searcher.cpp
new file mode 100644
index 0000000..0679f8f
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/searcher/solution/searcher.cpp
@@ -0,0 +1,37 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace fs = std::filesystem;
+namespace rn = std::ranges;
+
+std::vector searchFiles(std::string_view keyWord, const fs::path& dirName) {
+ std::vector paths;
+ rn::transform(fs::directory_iterator(dirName),
+ fs::directory_iterator{},
+ std::back_inserter(paths),
+ [](const auto& entry) { return entry.path(); });
+
+ std::vector res;
+ rn::copy_if(paths, std::back_inserter(res), [keyWord](const auto& path) {
+ std::ifstream file(path);
+ const auto end = std::istream_iterator{};
+ return std::find_if(std::istream_iterator(file),
+ end,
+ [keyWord](const auto& str) { return str == keyWord; }) != end;
+ });
+
+ return res;
+}
+
+int main() {
+ std::cout << "Files which contains word Ala:\n";
+ const auto& res = searchFiles("Ala", fs::current_path().string() + "/files");
+ rn::copy(res, std::ostream_iterator(std::cout, "\n"));
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/someClass/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/someClass/CMakeLists.txt
new file mode 100644
index 0000000..490a553
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/someClass/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(Someclass)
+
+set(SRC_LIST
+ someclass.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/someClass/README.md b/AdvancedCppV2/Presentation/exercises/someClass/README.md
new file mode 100644
index 0000000..c80e261
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/someClass/README.md
@@ -0,0 +1,10 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Not exrecise
+
+This is only example of template
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/someClass/someclass.cpp b/AdvancedCppV2/Presentation/exercises/someClass/someclass.cpp
new file mode 100644
index 0000000..3d5023e
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/someClass/someclass.cpp
@@ -0,0 +1,7 @@
+#include
+
+int main() {
+ SomeClass sc;
+ std::cout << sc.getValue() << std::endl;
+ return 0;
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/someClass/soultions/someclass.cpp b/AdvancedCppV2/Presentation/exercises/someClass/soultions/someclass.cpp
new file mode 100644
index 0000000..0cbf0f1
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/someClass/soultions/someclass.cpp
@@ -0,0 +1,16 @@
+#include
+
+template
+class SomeClass {
+public:
+ T getValue() { return value; }
+private:
+ T value = {};
+ U* ptr = nullptr;
+};
+
+int main() {
+ SomeClass sc;
+ std::cout << sc.getValue() << std::endl;
+ return 0;
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/streamer/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/streamer/CMakeLists.txt
new file mode 100644
index 0000000..5c09b8f
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/streamer/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(Streamer)
+
+set(SRC_LIST
+ streamer.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/streamer/README.md b/AdvancedCppV2/Presentation/exercises/streamer/README.md
new file mode 100644
index 0000000..f8e5992
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/streamer/README.md
@@ -0,0 +1,31 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Exercise 1
+
+* Open project streamer
+* Add two C'tor:
+ * first will take initializer_list
+ * second const StreamInfo&
+* initialize vector in initialization list
+
+## Exercise 2
+
+* Open project streamer
+* Add aliases for ip adress, port and vlan.
+
+## Exercise 3
+
+* Open project streamer
+* Create Streamer interface
+ * Allow to add data to stream
+ * Allow to add/remove receivers
+ * start/stop stream
+ * validate data
+* Create Mpeg2Streamer class
+* Create MjpegStreamer class
+* Make some implementations that will allow to compile code
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/streamer/solution/streamer.cpp b/AdvancedCppV2/Presentation/exercises/streamer/solution/streamer.cpp
new file mode 100644
index 0000000..35d70cb
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/streamer/solution/streamer.cpp
@@ -0,0 +1,29 @@
+#include
+#include
+
+class Streamer {
+public:
+ struct StreamInfo {
+ std::string sourceAddress_;
+ std::string destinationAddress_;
+ uint16_t sourcePort_;
+ uint16_t destinationPort_;
+ uint16_t vlan_;
+ };
+
+ Streamer(std::initializer_list info)
+ : info_(info) {
+ }
+
+ Streamer(const StreamInfo& info)
+ : info_{info} {
+ }
+
+private:
+ std::vector info_;
+};
+
+int main() {
+ Streamer streamer({"192.168.0.0", "192.168.10.24", 5432, 5432, 12});
+ Streamer streamer2{};
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/streamer/solution/streamer2.cpp b/AdvancedCppV2/Presentation/exercises/streamer/solution/streamer2.cpp
new file mode 100644
index 0000000..654d1e1
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/streamer/solution/streamer2.cpp
@@ -0,0 +1,71 @@
+#include
+#include
+
+template
+struct StrongAlias {
+ // Other C'tors, for r-value etc...
+ StrongAlias(const T& value)
+ : value_(value) {}
+
+ const T& operator*() const { return value_; }
+ T& operator*() { return value_; }
+
+ // Need to add hash function and operator<<
+ auto operator<=>(const StrongAlias& other) const = default;
+
+private:
+ T value_;
+};
+
+using IpV4 = StrongAlias;
+using IpV6 = StrongAlias;
+using MacAddress = StrongAlias;
+
+class Streamer {
+public:
+ using IpAddress = std::string;
+ using Port = uint16_t;
+ using Vlan = uint16_t;
+
+ struct StreamInfo {
+ IpAddress sourceAddress_;
+ IpAddress destinationAddress_;
+ Port sourcePort_;
+ Port destinationPort_;
+ Vlan vlan_;
+ };
+
+ Streamer(std::initializer_list info)
+ : info_(info) {
+ }
+
+ Streamer(const StreamInfo& info)
+ : info_{info} {
+ }
+
+private:
+ std::vector info_;
+};
+
+struct I {};
+struct A : I {};
+struct B : I {};
+
+struct Foo {
+ Foo(I* inter): inter_(inter) {}
+
+ I* inter_;
+}
+
+int main() {
+ Streamer streamer({"192.168.0.0", "192.168.10.24", 5432, 5432, 12});
+ Streamer streamer2{};
+
+ IpV4 ip{"192.168.0.1"};
+ IpV4 ip2{"192.168.0.2"};
+
+ std::cout << std::boolalpha << (ip < ip2) << '\n';
+ std::cout << std::boolalpha << (ip > ip2) << '\n';
+ std::cout << std::boolalpha << (ip != ip2) << '\n';
+ std::cout << std::boolalpha << (ip == ip2) << '\n';
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/streamer/streamer.cpp b/AdvancedCppV2/Presentation/exercises/streamer/streamer.cpp
new file mode 100644
index 0000000..aaa9c26
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/streamer/streamer.cpp
@@ -0,0 +1,23 @@
+#include
+#include
+
+class Streamer {
+public:
+ struct StreamInfo {
+ std::string sourceAddress_;
+ std::string destinationAddress_;
+ uint16_t sourcePort_;
+ uint16_t destinationPort_;
+ uint16_t vlan_;
+ };
+
+ // Write C'tors here
+
+private:
+ std::vector info_;
+};
+
+int main() {
+ Streamer streamer({"192.168.0.0", "192.168.10.24", 5432, 5432, 12});
+ Streamer streamer2{};
+}
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/students/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/students/CMakeLists.txt
new file mode 100644
index 0000000..ddbe8c3
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/students/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(Students)
+
+set(SRC_LIST
+ students.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
\ No newline at end of file
diff --git a/AdvancedCppV2/Presentation/exercises/students/README.md b/AdvancedCppV2/Presentation/exercises/students/README.md
new file mode 100644
index 0000000..193c733
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/students/README.md
@@ -0,0 +1,22 @@
+## Linux compilation
+
+ > mkdir build
+ > cd build
+ > cmake -DCMAKE_BUILD_TYPE=Debug ..
+ > make
+
+## Exercise
+
+Open project `students`:
+
+* implement function `filterStudents`,
+* Student should be disqualified whether his average is below `minAvergae`,
+* Write an algorithm that prints students using ranges (do not implement friend operator<<)
+
+Output:
+
+```C++
+Name: Jane | index: 743561 | average: 4.44
+Name: Tom | index: 811111 | average: 4.36
+Name: Mike | index: 811111 | average: 4.45
+```
diff --git a/AdvancedCppV2/Presentation/exercises/students/solution/students.cpp b/AdvancedCppV2/Presentation/exercises/students/solution/students.cpp
new file mode 100644
index 0000000..856366b
--- /dev/null
+++ b/AdvancedCppV2/Presentation/exercises/students/solution/students.cpp
@@ -0,0 +1,49 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace rn = std::ranges;
+
+struct Student {
+ int index_;
+ std::string name_;
+ double average_;
+};
+
+std::vector filterStudents(const std::vector>& students, double minAverage) {
+ std::vector result;
+
+ rn::copy(students |
+ std::views::transform([](const auto& student) { return student.get(); }) |
+ std::views::filter([minAverage](const auto& student) { return student->average_ <= minAverage; }),
+ std::back_inserter(result));
+
+ return result;
+}
+
+int main() {
+ std::vector> students;
+ students.push_back(std::make_unique(123456, "Jordan", 4.53));
+ students.push_back(std::make_unique(654321, "Michael", 4.51));
+ students.push_back(std::make_unique(246892, "John", 4.56));
+ students.push_back(std::make_unique(743561, "Jane", 4.44));
+ students.push_back(std::make_unique(811111, "Anna", 4.46));
+ students.push_back(std::make_unique(811111, "Tom", 4.36));
+ students.push_back(std::make_unique