├── .devcontainer └── devcontainer.json ├── .gitignore ├── README.md ├── exercises ├── day01 │ ├── assignment │ │ └── TestAssigment.md │ ├── cmake │ │ ├── 01-basic │ │ │ ├── .vscode │ │ │ │ ├── launch.json │ │ │ │ └── settings.json │ │ │ ├── CMakeLists.txt │ │ │ └── src │ │ │ │ └── main.cpp │ │ ├── 02-multifiles │ │ │ ├── .vscode │ │ │ │ ├── launch.json │ │ │ │ └── settings.json │ │ │ ├── CMakeLists.txt │ │ │ ├── inc │ │ │ │ └── cpptest.h │ │ │ └── src │ │ │ │ ├── cpptest.cpp │ │ │ │ └── main.cpp │ │ ├── 03-library │ │ │ ├── .vscode │ │ │ │ ├── launch.json │ │ │ │ └── settings.json │ │ │ ├── CMakeLists.txt │ │ │ ├── app │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── main.cpp │ │ │ ├── inc │ │ │ │ └── test │ │ │ │ │ └── test.h │ │ │ └── src │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── test.cpp │ │ └── README.md │ ├── environment │ │ ├── environment.assets │ │ │ ├── gitpod-20240502124437655.png │ │ │ ├── gitpod-20240502124625222.png │ │ │ ├── gitpod-20240502124750209.png │ │ │ ├── gitpod-20240502124825230.png │ │ │ ├── gitpod-20240502124929404.png │ │ │ ├── gitpod-20240502125329746.png │ │ │ ├── gitpod-20240502125505301.png │ │ │ ├── gitpod-20240502125543161.png │ │ │ ├── gitpod-20240502125615560.png │ │ │ ├── gitpod-20240502125640364.png │ │ │ ├── gitpod-20240502125751441.png │ │ │ ├── gitpod-20240502125916736.png │ │ │ ├── gitpod-20240502130000147.png │ │ │ ├── image-20240509085920480.png │ │ │ ├── image-20240509091038855.png │ │ │ ├── image-20240509091257444.png │ │ │ ├── image-20240509091817370.png │ │ │ ├── image-20240509091840882.png │ │ │ └── image-20240509091911828.png │ │ └── environment.md │ ├── github │ │ ├── basics.md │ │ └── res │ │ │ ├── github-fork-2.png │ │ │ └── github-fork.png │ └── markdown │ │ ├── 01-basic │ │ ├── basic.md │ │ └── res │ │ │ ├── mdanother.png │ │ │ ├── mdextension.png │ │ │ └── mdpreview.png │ │ ├── 02-advanced │ │ ├── advanced.md │ │ └── res │ │ │ └── download.png │ │ ├── 03-samplereport │ │ ├── report.md │ │ └── res │ │ │ ├── event.viewer.jpg │ │ │ ├── imu-long.png │ │ │ ├── imu-short.png │ │ │ ├── pdf-acquisition-time-imu.jpg │ │ │ └── project.structure.jpg │ │ └── README.md ├── day02 │ └── cpp98 │ │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ │ ├── CMakeLists.txt │ │ ├── include │ │ └── cpp98.h │ │ └── src │ │ ├── cpp98.cpp │ │ └── main.cpp ├── day03 │ ├── mcore01 │ │ ├── .vscode │ │ │ ├── launch.json │ │ │ └── settings.json │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── mcore01.h │ │ └── src │ │ │ ├── main.cpp │ │ │ └── mcore01.cpp │ └── test │ │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ │ ├── CMakeLists.txt │ │ ├── docs │ │ └── report.md │ │ ├── include │ │ ├── printerClient.h │ │ ├── printerIF.h │ │ ├── printerServer.h │ │ └── printerTest.h │ │ └── src │ │ ├── main.cpp │ │ ├── printerClient.cpp │ │ ├── printerServer.cpp │ │ └── printerTest.cpp ├── day04 │ ├── mcore02 │ │ ├── .vscode │ │ │ ├── launch.json │ │ │ └── settings.json │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── mcore02.h │ │ └── src │ │ │ ├── main.cpp │ │ │ └── mcore02.cpp │ └── modernpimpl │ │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── include │ │ └── modernprinter.h │ │ └── src │ │ ├── main.cpp │ │ └── moderprinter.cpp ├── day05 │ ├── CMakeLists.txt │ └── main.cpp ├── day06 │ ├── CMakeLists.txt │ └── main.cpp ├── day07 │ ├── cond_variables.cpp │ └── future-promise.cpp ├── day08 │ ├── CMakeLists.txt │ └── main.cpp ├── day09 │ ├── morepimpl │ │ ├── .vscode │ │ │ ├── launch.json │ │ │ └── settings.json │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── include │ │ │ ├── modernpimpl.h │ │ │ └── widget98.h │ │ └── src │ │ │ ├── main.cpp │ │ │ ├── modernpimpl.cpp │ │ │ └── widget98.cpp │ └── moveSemantic │ │ ├── exerciseMoveSem.cpp │ │ └── instructionMoveSemanticsExercise.md └── shared │ └── CMakeOptions.cmake ├── program ├── 2022-23 │ └── Modern-C++-2022-23.pdf ├── 2023-24 │ └── Modern-C++-2023-24.pdf └── 2024-25 │ └── modern-c++-2024-25.pdf └── slides ├── day01 ├── modern-c++-01-a-presentation-202x.pdf └── modern-c++-01-b-toolchain-202x.pdf ├── day02 └── modern-c++-02-prerequisites.pdf ├── day03-04 └── modern-c++-03-04-thebasics.pdf ├── day05 ├── Modern_C++_Programming_Course_–algo_containers.pdf └── Modern_C++_Programming_Course_–lambda.pdf ├── day06 ├── Modern_C++_Programming_Course_–smart_pointers.pdf └── moveSemantics.pdf ├── day07 └── multithreading.pdf ├── day08 └── Modern_C++_Programming_Course_– C++20.pdf ├── day09 └── README.md └── day10 └── README.md /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", 3 | // Or for a C++ focused environment: 4 | // "image": "mcr.microsoft.com/devcontainers/cpp:ubuntu-24.04", 5 | 6 | "customizations": { 7 | "vscode": { 8 | "extensions": [ 9 | // Add any VS Code extensions you commonly use. Examples: 10 | "ms-vscode.cpptools", // For C++ 11 | "ms-python.python", // For Python 12 | "redhat.java", // For Java (if needed) 13 | "ms-toolsai.jupyter", // For Jupyter notebooks 14 | "webfreak.debug", 15 | "yzhang.markdown-all-in-one", 16 | "bierner.markdown-mermaid", 17 | "houkanshan.vscode-markdown-footnote" 18 | ] 19 | } 20 | }, 21 | 22 | // Optional: Forward ports if your applications need them. 23 | // "forwardPorts": [3000, 8080], 24 | 25 | // Optional: Set environment variables. 26 | // "remoteEnv": { 27 | // "MY_VARIABLE": "my_value" 28 | // }, 29 | 30 | // Use 'postCreateCommand' to run commands after the container is created. 31 | // For example, to update package lists and install some common tools: 32 | "postCreateCommand": "sudo apt-get update && sudo apt-get install -y git build-essential cmake curl wget", 33 | 34 | // Set the remote user. 'vscode' is common for these images and has sudo access. 35 | "remoteUser": "vscode" 36 | } 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Build directory 35 | build*/ 36 | 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # material-modern-cpp 3 | This repository hosts the material of the course `Modern C++` 4 | 5 | The structure of the repo is the following: 6 | 7 | - folder `slides` contains the headline of the presentations; 8 | - folder `exercises` contains all the material which is used as a support for the lesson; 9 | - folder `program` is a brief of what the course contains each year. 10 | 11 | This repository can be used with [GitHub Codespaces](https://docs.github.com/en/codespaces/overview) and is already configured to use CMake, gcc, gdb and Visual Studio Code to execute the exercises. 12 | -------------------------------------------------------------------------------- /exercises/day01/assignment/TestAssigment.md: -------------------------------------------------------------------------------- 1 | # Test Assignment 2 | 3 | This is an example of an assignment for the `Modern C++` course. It is based on C++98 because it will be discussed before much of modern C++ is shown. 4 | 5 | 6 | 7 | ## Exercise 8 | 9 | Implement two classes which behave respectively as a printer client and a printer server. 10 | 11 | The client accepts a string and sends it to a specific printer server which sends it to standard output. The interface of the two classes will be minimal and will hide implementation using the PIMPL idiom. 12 | 13 | The project will use CMake, must compile and when launched must produce the print of the following sequence of strings: "hello", "world", "of", "example", "test", "assignment". 14 | 15 | You will write a brief explanation of the project using Markdown language. 16 | 17 | The project will be written in plain old C++98. 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /exercises/day01/cmake/01-basic/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) ubuntu", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/demo01", 12 | "args": [], 13 | "cwd" : "${workspaceFolder}/build", 14 | "miDebuggerPath": "/usr/bin/gdb" 15 | }, 16 | { 17 | "name": "(gdb) gitpod", 18 | "type": "gdb", 19 | "request": "launch", 20 | "target": "${workspaceFolder}/build/demo01", 21 | "cwd": "${workspaceRoot}", 22 | "valuesFormatting": "parseText" 23 | }, 24 | ] 25 | } -------------------------------------------------------------------------------- /exercises/day01/cmake/01-basic/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "string": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "*.tcc": "cpp", 8 | "cctype": "cpp", 9 | "clocale": "cpp", 10 | "cmath": "cpp", 11 | "compare": "cpp", 12 | "concepts": "cpp", 13 | "cstdarg": "cpp", 14 | "cstddef": "cpp", 15 | "cstdint": "cpp", 16 | "cstdio": "cpp", 17 | "cstdlib": "cpp", 18 | "cwchar": "cpp", 19 | "cwctype": "cpp", 20 | "deque": "cpp", 21 | "unordered_map": "cpp", 22 | "vector": "cpp", 23 | "exception": "cpp", 24 | "algorithm": "cpp", 25 | "functional": "cpp", 26 | "iterator": "cpp", 27 | "memory": "cpp", 28 | "memory_resource": "cpp", 29 | "numeric": "cpp", 30 | "random": "cpp", 31 | "string_view": "cpp", 32 | "system_error": "cpp", 33 | "tuple": "cpp", 34 | "type_traits": "cpp", 35 | "utility": "cpp", 36 | "initializer_list": "cpp", 37 | "iosfwd": "cpp", 38 | "iostream": "cpp", 39 | "istream": "cpp", 40 | "limits": "cpp", 41 | "new": "cpp", 42 | "numbers": "cpp", 43 | "ostream": "cpp", 44 | "stdexcept": "cpp", 45 | "streambuf": "cpp", 46 | "typeinfo": "cpp" 47 | } 48 | } -------------------------------------------------------------------------------- /exercises/day01/cmake/01-basic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # set the minimum required version of CMake to be 3.20 2 | cmake_minimum_required(VERSION 3.20) 3 | 4 | # create a project named demo01 5 | project(demo01) 6 | 7 | # impose default compilation mode to be Debug 8 | # you can override with: 9 | # > ccmake .. -DCMAKE_BUILD_TYPE=Release 10 | if(NOT CMAKE_BUILD_TYPE) 11 | set(CMAKE_BUILD_TYPE "Debug" CACHE STRING 12 | "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." 13 | FORCE) 14 | endif() 15 | 16 | # impose c++ standard to be strict c++98. so far you cannot override it 17 | set(CMAKE_CXX_EXTENSIONS OFF) 18 | set(CMAKE_CXX_STANDARD 98) 19 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 20 | 21 | # add a single file 22 | add_executable(demo01 src/main.cpp) 23 | 24 | -------------------------------------------------------------------------------- /exercises/day01/cmake/01-basic/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | #include 6 | 7 | #define __USE_CPP98 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | 12 | #if defined(__USE_CPP98) 13 | #else 14 | auto iammodern{3}; 15 | iammodern++; 16 | #endif 17 | 18 | std::cout << "Hello World! of Modern C++" << std::endl; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /exercises/day01/cmake/02-multifiles/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) ubuntu", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/demo02", 12 | "args": [], 13 | "cwd" : "${workspaceFolder}/build", 14 | "miDebuggerPath": "/usr/bin/gdb" 15 | }, 16 | { 17 | "name": "(gdb) gitpod", 18 | "type": "gdb", 19 | "request": "launch", 20 | "target": "${workspaceFolder}/build/demo02", 21 | "cwd": "${workspaceRoot}", 22 | "valuesFormatting": "parseText" 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /exercises/day01/cmake/02-multifiles/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "string": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "*.tcc": "cpp", 8 | "cctype": "cpp", 9 | "clocale": "cpp", 10 | "cmath": "cpp", 11 | "compare": "cpp", 12 | "concepts": "cpp", 13 | "cstdarg": "cpp", 14 | "cstddef": "cpp", 15 | "cstdint": "cpp", 16 | "cstdio": "cpp", 17 | "cstdlib": "cpp", 18 | "cwchar": "cpp", 19 | "cwctype": "cpp", 20 | "deque": "cpp", 21 | "unordered_map": "cpp", 22 | "vector": "cpp", 23 | "exception": "cpp", 24 | "algorithm": "cpp", 25 | "functional": "cpp", 26 | "iterator": "cpp", 27 | "memory": "cpp", 28 | "memory_resource": "cpp", 29 | "numeric": "cpp", 30 | "random": "cpp", 31 | "string_view": "cpp", 32 | "system_error": "cpp", 33 | "tuple": "cpp", 34 | "type_traits": "cpp", 35 | "utility": "cpp", 36 | "initializer_list": "cpp", 37 | "iosfwd": "cpp", 38 | "iostream": "cpp", 39 | "istream": "cpp", 40 | "limits": "cpp", 41 | "new": "cpp", 42 | "numbers": "cpp", 43 | "ostream": "cpp", 44 | "stdexcept": "cpp", 45 | "streambuf": "cpp", 46 | "typeinfo": "cpp" 47 | } 48 | } -------------------------------------------------------------------------------- /exercises/day01/cmake/02-multifiles/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # set the minimum required version of CMake to be 3.20 2 | cmake_minimum_required(VERSION 3.20) 3 | 4 | # create a project named demo02 5 | project(demo02) 6 | 7 | # set debug mode 8 | set(CMAKE_BUILD_TYPE Debug) 9 | 10 | # impose c++11 11 | set(CMAKE_CXX_EXTENSIONS OFF) 12 | set(CMAKE_CXX_STANDARD 11) 13 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 14 | 15 | 16 | # add include path 17 | include_directories(inc) 18 | 19 | # define a variable holding all the source files 20 | file(GLOB SOURCES "src/*.cpp") 21 | 22 | # add the files to the project 23 | add_executable(demo02 ${SOURCES}) 24 | -------------------------------------------------------------------------------- /exercises/day01/cmake/02-multifiles/inc/cpptest.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | // - include guard ---------------------------------------------------------------------------------------------------- 9 | 10 | #ifndef __CPP_TEST_H_ 11 | #define __CPP_TEST_H_ 12 | 13 | 14 | #include 15 | 16 | namespace d01 { namespace test01 { 17 | 18 | void say(const std::string &st); 19 | 20 | } } // namespace d01::test01 21 | 22 | 23 | 24 | #endif // include-guard 25 | 26 | 27 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 28 | 29 | 30 | -------------------------------------------------------------------------------- /exercises/day01/cmake/02-multifiles/src/cpptest.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | // - public interface 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "cpptest.h" 14 | 15 | 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | // - external dependencies 18 | // -------------------------------------------------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | 23 | 24 | // -------------------------------------------------------------------------------------------------------------------- 25 | // - all the rest 26 | // -------------------------------------------------------------------------------------------------------------------- 27 | 28 | namespace d01 { namespace test01 { 29 | 30 | auto ncalls {0}; 31 | void say(const std::string &str) 32 | { 33 | ncalls ++; 34 | std::cout << str << ", called " << std::to_string(ncalls) << " times" << std::endl; 35 | } 36 | 37 | 38 | }} // namespace d01::test01 39 | 40 | 41 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /exercises/day01/cmake/02-multifiles/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | #include 10 | #include "cpptest.h" 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | std::cout << "Hello World! of Modern C++. We are using more source files" << std::endl; 15 | d01::test01::say("hello world"); 16 | d01::test01::say("hello world"); 17 | for(size_t i=0; i<7; i++) 18 | { 19 | d01::test01::say("hello world"); 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /exercises/day01/cmake/03-library/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) ubuntu", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/app/app", 12 | "args": [], 13 | "cwd" : "${workspaceFolder}/build", 14 | "miDebuggerPath": "/usr/bin/gdb" 15 | }, 16 | { 17 | "name": "(gdb) gitpod", 18 | "type": "gdb", 19 | "request": "launch", 20 | "target": "${workspaceFolder}/build/app/app", 21 | "cwd": "${workspaceRoot}", 22 | "valuesFormatting": "parseText" 23 | }, 24 | ] 25 | } -------------------------------------------------------------------------------- /exercises/day01/cmake/03-library/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "string": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "*.tcc": "cpp", 8 | "cctype": "cpp", 9 | "clocale": "cpp", 10 | "cmath": "cpp", 11 | "compare": "cpp", 12 | "concepts": "cpp", 13 | "cstdarg": "cpp", 14 | "cstddef": "cpp", 15 | "cstdint": "cpp", 16 | "cstdio": "cpp", 17 | "cstdlib": "cpp", 18 | "cwchar": "cpp", 19 | "cwctype": "cpp", 20 | "deque": "cpp", 21 | "unordered_map": "cpp", 22 | "vector": "cpp", 23 | "exception": "cpp", 24 | "algorithm": "cpp", 25 | "functional": "cpp", 26 | "iterator": "cpp", 27 | "memory": "cpp", 28 | "memory_resource": "cpp", 29 | "numeric": "cpp", 30 | "random": "cpp", 31 | "string_view": "cpp", 32 | "system_error": "cpp", 33 | "tuple": "cpp", 34 | "type_traits": "cpp", 35 | "utility": "cpp", 36 | "initializer_list": "cpp", 37 | "iosfwd": "cpp", 38 | "iostream": "cpp", 39 | "istream": "cpp", 40 | "limits": "cpp", 41 | "new": "cpp", 42 | "numbers": "cpp", 43 | "ostream": "cpp", 44 | "stdexcept": "cpp", 45 | "streambuf": "cpp", 46 | "typeinfo": "cpp" 47 | } 48 | } -------------------------------------------------------------------------------- /exercises/day01/cmake/03-library/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html?highlight=cmake_minimum_required 3 | # 4 | # set the minimum required version of CMake to be 3.20 5 | cmake_minimum_required(VERSION 3.20) 6 | 7 | set(ROOT_PROJECT_NAME ModernC++CMakeExample) 8 | 9 | # https://cmake.org/cmake/help/latest/command/project.html 10 | # 11 | # project( [...]) 12 | # project( 13 | # [VERSION [.[.[.]]]] 14 | # [DESCRIPTION ] 15 | # [HOMEPAGE_URL ] 16 | # [LANGUAGES ...]) 17 | # 18 | # stores in PROJECT_NAME the string ModernCMakeExample (and also in CMAKE_PROJECT_NAME), uses language C++ etc. 19 | project( 20 | ${ROOT_PROJECT_NAME} 21 | VERSION 0.1.0.0 22 | DESCRIPTION "An example project with CMake for Modern C++" 23 | LANGUAGES CXX) 24 | 25 | include(../../../shared/CMakeOptions.cmake) 26 | 27 | # https://cmake.org/cmake/help/latest/command/message.html 28 | # we just print some variables 29 | # message(STATUS "PROJECT_NAME is: " ${PROJECT_NAME}) 30 | # message(STATUS "CMAKE_CXX_STANDARD is: " ${CMAKE_CXX_STANDARD}) 31 | 32 | 33 | # the compiled library code is here 34 | add_subdirectory(src) 35 | 36 | # the executable code is here 37 | add_subdirectory(app) 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /exercises/day01/cmake/03-library/app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(app main.cpp) 2 | target_link_libraries(app PRIVATE test) 3 | -------------------------------------------------------------------------------- /exercises/day01/cmake/03-library/app/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | std::cout << "Hello World! of Modern C++. We are using a lib" << std::endl; 15 | d01::test::say("hello world"); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /exercises/day01/cmake/03-library/inc/test/test.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | // - include guard ---------------------------------------------------------------------------------------------------- 9 | 10 | #ifndef __TEST_H_ 11 | #define __TEST_H_ 12 | 13 | 14 | #include 15 | 16 | namespace d01 { namespace test { 17 | 18 | void say(const std::string &st); 19 | 20 | } } // namespace d01::test 21 | 22 | 23 | 24 | #endif // include-guard 25 | 26 | 27 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 28 | 29 | 30 | -------------------------------------------------------------------------------- /exercises/day01/cmake/03-library/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Note that headers are optional, and do not affect add_library, but they will not 3 | # show up in IDEs unless they are listed in add_library. 4 | # Optionally glob, but only for CMake 3.12 or later: 5 | # file(GLOB HEADER_LIST CONFIGURE_DEPENDS "${ModernCMakeExample_SOURCE_DIR}/inc/test/*.h") 6 | # set(HEADER_LIST "${ModernCMakeExample_SOURCE_DIR}/inc/test/test.h") 7 | 8 | # make an automatic library - will be static or dynamic based on user setting 9 | #add_library(test_library test.cpp ${HEADER_LIST}) 10 | 11 | add_library(test) 12 | 13 | set(SOURCES "./test.cpp") 14 | set(APIDIR "../inc") 15 | 16 | target_sources(test PRIVATE ${SOURCES}) 17 | 18 | 19 | # we need this directory, and users of our library will need it too 20 | target_include_directories(test PUBLIC ${APIDIR}) 21 | 22 | # this may depends on another library 23 | # target_link_libraries(test_library PRIVATE other_library) 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /exercises/day01/cmake/03-library/src/test.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | // - public interface 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "test/test.h" 14 | 15 | 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | // - external dependencies 18 | // -------------------------------------------------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | 23 | 24 | // -------------------------------------------------------------------------------------------------------------------- 25 | // - all the rest 26 | // -------------------------------------------------------------------------------------------------------------------- 27 | 28 | namespace d01 { namespace test { 29 | 30 | auto ncalls {0}; 31 | void say(const std::string &str) 32 | { 33 | ncalls ++; 34 | std::cout << "test lib: -> " << str << ", called " << std::to_string(ncalls) << " times" << std::endl; 35 | } 36 | 37 | 38 | }} // namespace d01::test 39 | 40 | 41 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /exercises/day01/cmake/README.md: -------------------------------------------------------------------------------- 1 | ## README.md 2 | 3 | 4 | 5 | This folder contains examples of use of [CMake](https://cmake.org/) tailored for the `Modern C++` course. 6 | -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502124437655.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502124437655.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502124625222.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502124625222.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502124750209.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502124750209.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502124825230.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502124825230.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502124929404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502124929404.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502125329746.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502125329746.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502125505301.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502125505301.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502125543161.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502125543161.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502125615560.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502125615560.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502125640364.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502125640364.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502125751441.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502125751441.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502125916736.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502125916736.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/gitpod-20240502130000147.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/gitpod-20240502130000147.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/image-20240509085920480.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/image-20240509085920480.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/image-20240509091038855.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/image-20240509091038855.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/image-20240509091257444.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/image-20240509091257444.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/image-20240509091817370.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/image-20240509091817370.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/image-20240509091840882.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/image-20240509091840882.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.assets/image-20240509091911828.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/environment/environment.assets/image-20240509091911828.png -------------------------------------------------------------------------------- /exercises/day01/environment/environment.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # The environment 4 | 5 | We need an environment where to run our exercises. As they come with `Cmake` there are several possibilities. We propose two: 6 | 7 | - a `gitpod` environment ready to use with `Visual Studio Code`, 8 | - a `Ubuntu` 2022.04 environment in `WSL2` with `Visual Studio Code`. 9 | 10 | 11 | 12 | In the following are basic instructions for preparing these two environments. 13 | 14 | 15 | 16 | ## Setting up `gitpod` 17 | 18 | 19 | 20 | This environment is ready to use and requires only a browser. Instructions of its use are in here. 21 | 22 | In here are instructions about how to use `gitpod` 23 | 24 | 25 | 26 | 1. log in 27 | 28 | ![gitpod-20240502124437655](./environment.assets/gitpod-20240502124437655.png) 29 | 30 | 2. then open a workspace w/ CTRL + O. Open your forked repository: `https://github.com/marcoaccame/material_modern-cpp` 31 | 32 | ![gitpod-20240502124625222](./environment.assets/gitpod-20240502124625222.png) 33 | 34 | ![gitpod-20240502124750209](./environment.assets/gitpod-20240502124750209.png) 35 | 36 | 4. after some preparation your environment will appear 37 | 38 | ![gitpod-20240502124825230](./environment.assets/gitpod-20240502124825230.png) 39 | 40 | ![gitpod-20240502124929404](./environment.assets/gitpod-20240502124929404.png) 41 | 42 | 5. use it for: 43 | 44 | - visualizing .md files 45 | ![gitpod-20240502125329746](./environment.assets/gitpod-20240502125329746.png) 46 | 47 | - for compiling and running code 48 | 49 | ![gitpod-20240502125505301](./environment.assets/gitpod-20240502125505301.png) 50 | 51 | ![gitpod-20240502125543161](./environment.assets/gitpod-20240502125543161.png) 52 | 53 | ![gitpod-20240502125615560](./environment.assets/gitpod-20240502125615560.png) 54 | 55 | ![gitpod-20240502125640364](./environment.assets/gitpod-20240502125640364.png) 56 | 57 | - for debugging 58 | 59 | ![gitpod-20240502125751441](./environment.assets/gitpod-20240502125751441.png) 60 | 61 | ![gitpod-20240502125916736](./environment.assets/gitpod-20240502125916736.png) 62 | 63 | ![gitpod-20240502130000147](./environment.assets/gitpod-20240502130000147.png) 64 | 65 | 66 | 67 | 68 | 69 | ## Setting up `Ubuntu` 70 | 71 | This section will show how to setup the Ubuntu 20.04 environment for WSL2 in Windows. Similar settings apply to a native Ubuntu distribution. 72 | 73 | The steps are: 74 | 75 | - install Ubuntu 20.04 on WSL2 76 | - install the development tools required to compile 77 | - install and configure Visual Studio Code to run the debugger. 78 | 79 | ### Install Ubuntu on WSL2 80 | 81 | TBD 82 | 83 | ### Install the compilation tools 84 | 85 | The following are required 86 | - `git` 87 | 88 | ```bash 89 | $ sudo apt install git -y 90 | $ git --version 91 | ``` 92 | 93 | - `cmake` 94 | 95 | ```bash 96 | $ sudo apt install cmake 97 | $ cmake --version 98 | ``` 99 | 100 | - `ccmake` 101 | 102 | ```bash 103 | $ sudo apt install cmake-curses-gui 104 | $ ccmake --version 105 | ``` 106 | - `gcc` et al (gcc, g++ and make) 107 | 108 | ```bash 109 | $ sudo apt install build-essential 110 | $ gcc --version 111 | $ g++ --version 112 | $ make --version 113 | ``` 114 | 115 | - `gdb` 116 | 117 | ```bash 118 | $ sudo apt install gdb 119 | $ gdb --version 120 | ``` 121 | 122 | - `others`: tree, meld 123 | 124 | ```bash 125 | $ sudo apt install tree 126 | $ sudo apt install meld 127 | ``` 128 | 129 | 130 | 131 | ### Install and launch VSC 132 | 133 | Visual Studio Code can be installed either on windows via the Microsoft store or directly on Ubuntu. Then it can started from Ubuntu (but also from Windows). 134 | 135 | See the following installation instructions: 136 | 137 | - `Ubuntu`: https://code.visualstudio.com/docs/setup/linux 138 | - `Windows`: https://code.visualstudio.com/docs/setup/windows 139 | 140 | 141 | 142 | On Linux we start it w/ following command 143 | 144 | ```bash 145 | $ code 146 | ``` 147 | 148 | 149 | 150 | ![image-20240509085920480](./environment.assets/image-20240509085920480.png) 151 | 152 | 153 | 154 | ### Configure VSC 155 | 156 | After we launch it we must configure it for using with C++ and for debugging with GDB, so we need to install the following extensions suggested by https://code.visualstudio.com/docs/languages/cpp. See also https://code.visualstudio.com/docs/cpp/cpp-debug. 157 | 158 | - `ms-vscode.cpptools-extension-pack` 159 | 160 | ![image-20240509091038855](./environment.assets/image-20240509091038855.png) 161 | 162 | - `ms-vscode-remote.remote-wsl` 163 | 164 | ![image-20240509091257444](./environment.assets/image-20240509091257444.png) 165 | 166 | 167 | 168 | The above should be enough. However, it is important to: 169 | 170 | - connect to wsl2 w/ CTRL + ALT + O 171 | 172 | ![image-20240509091911828](./environment.assets/image-20240509091911828.png) 173 | 174 | - make sure that the extensions are enabled also in wsl2. 175 | 176 | ![image-20240509091817370](./environment.assets/image-20240509091817370.png) 177 | 178 | ![image-20240509091840882](./environment.assets/image-20240509091840882.png) 179 | 180 | 181 | -------------------------------------------------------------------------------- /exercises/day01/github/basics.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | # Basic operativity in GitHub 6 | 7 | 8 | 9 | ## Fork the repository 10 | 11 | See pictures. 12 | 13 | 14 | 15 | ![](./res/github-fork.png) 16 | 17 | ![](./res/github-fork-2.png) 18 | 19 | **Figure**. How to fork the repository 20 | 21 | 22 | 23 | ## Clone the repository 24 | 25 | ```bash 26 | $ git clone https://github.com/USER/material_modern-cpp 27 | $ cd material_modern-cpp 28 | $ 29 | ``` 30 | 31 | **Listing**. How to clone the forked repository 32 | 33 | 34 | 35 | ## Update your clone 36 | 37 | ```bash 38 | $ git remote add orig https://github.com/icub-training/material_modern-cpp 39 | $ git fetch orig 40 | $ git checkout master 41 | $ git pull 42 | $ git rebase orig/master 43 | $ git push --force-with-lease origin master 44 | $ 45 | ``` 46 | 47 | **Listing**. How to rebase your cloned repository vs the original 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /exercises/day01/github/res/github-fork-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/github/res/github-fork-2.png -------------------------------------------------------------------------------- /exercises/day01/github/res/github-fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/github/res/github-fork.png -------------------------------------------------------------------------------- /exercises/day01/markdown/01-basic/basic.md: -------------------------------------------------------------------------------- 1 | # Basic Markdown 2 | 3 | 4 | In here we have a basic `Markdown` file, where we just write words, add some basic formatting and they will be rendered in the Markdown previer. 5 | 6 | 7 | ## The previer 8 | 9 | 10 | `Visual Studio Code` has a native previewer. You can access it by clicking on top right as in following picture: 11 | 12 | ![](./res/mdpreview.png) 13 | 14 | 15 | However, it is very basic and does not show the result of some formatting. So, we recommend to install the following extension: 16 | 17 | ![](./res/mdextension.png) 18 | 19 | Unluckily, for gitpod we need to use also this extension. 20 | ![](./res/mdanother.png) 21 | 22 | 23 | However, you can use any other previer / editor. 24 | 25 | 26 | ## The formatting 27 | 28 | The text appear as it is but it can be formatted in some simple modes: 29 | 30 | ### Paragraphs 31 | By adding a \# level1 you make level 1 for tiles, etc. The above uses /### paragraphs 32 | 33 | 34 | 35 | ### Lists 36 | 37 | They can be of several types. 38 | 39 | This an unordered list, even with multiple levels 40 | - a point 41 | - another sublevel 42 | - yet another 43 | - defc3 44 | - same sublevel 45 | - anotehr point 46 | 47 | 48 | This is a numbered list, even with multiple levels 49 | 1. c3evc3 50 | 1. crev 51 | 2. cerwvc3r 52 | 3. cervf3 53 | 2. d34f423 54 | 1. dddd 55 | 2. cecfe3fc3 56 | 3. 3d3ef2 57 | 4. cev3r 58 | 59 | This is a task list, even with multiple levels 60 | 61 | - [x] ce3vc3 62 | - [x] cecwe 63 | - [x] ceceeeeeee 64 | - [ ] ce3vc4231 65 | - [ ] cewwsss 66 | - [ ] sssssssss 67 | - [x] ssffffffffffff 68 | - [x] done 69 | 70 | 71 | 72 | ### Text formatting 73 | 74 | You can use some formatting such as: 75 | 76 | - \*italics* gives *italics*, 77 | - \**bold** gives **bold**, 78 | - \~~barred~~ gives ~~barred~~ 79 | - \`highlighted\` gives `highlighted` 80 | etc. 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /exercises/day01/markdown/01-basic/res/mdanother.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/markdown/01-basic/res/mdanother.png -------------------------------------------------------------------------------- /exercises/day01/markdown/01-basic/res/mdextension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/markdown/01-basic/res/mdextension.png -------------------------------------------------------------------------------- /exercises/day01/markdown/01-basic/res/mdpreview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/markdown/01-basic/res/mdpreview.png -------------------------------------------------------------------------------- /exercises/day01/markdown/02-advanced/advanced.md: -------------------------------------------------------------------------------- 1 | # Advanced Markdown 2 | 3 | In here we have a slightly more adavanced `Markdown` file with code snippets, tables, pictures, rendered graphics, formulas, footnotes, etc. 4 | 5 | 6 | ## Code snippets 7 | 8 | In here are some examples of code snippets, 9 | 10 | ```c++ 11 | namespace utils { 12 | 13 | // it retrieves a value 14 | bool getit(const &size_t s) 15 | { 16 | static size_t _s {0}; 17 | s = _s++; 18 | return true; 19 | } 20 | 21 | } // namespace utils 22 | 23 | ``` 24 | 25 | **Listing**. This is a code listing formatted for C++. 26 | 27 | ```diff 28 | namespace utils { 29 | 30 | - // it retrieves a value 31 | - bool getit(const &size_t s) 32 | + // it retrieves a values, so we cannot use const !!!! 33 | + bool getit(&size_t s) 34 | { 35 | static size_t _s {0}; 36 | s = _s++; 37 | return true; 38 | } 39 | 40 | } // namespace utils 41 | 42 | ``` 43 | 44 | **Listing**. This is a code listing formatted for diff. 45 | 46 | 47 | 48 | ## Tables 49 | 50 | 51 | In here are some tables with different fromatting 52 | 53 | 54 | 55 | | Name | Role | Score | 56 | | ----------------- | ---------- | ----- | 57 | | Bill **Gates** | Defender | 0 | 58 | | Steve **Jobs** | Midfielder | 7 | 59 | | Steve **Wozniak** | Defender | 3 | 60 | | Paul **Allen** | Midfielder | 7 | 61 | 62 | **Table**. It is a table 63 | 64 | 65 | 66 | 67 | 68 | 69 | | Name | Role | Score | 70 | | :---------------: | :--------- | ----: | 71 | | Bill **Gates** | Defender | 0 | 72 | | Steve **Jobs** | Midfielder | 7 | 73 | | Steve **Wozniak** | Defender | 3 | 74 | | Paul **Allen** | Midfielder | 7 | 75 | 76 | **Table**. It is the same table with a different alignment 77 | 78 | ## Pictures 79 | 80 | In here is a picture 81 | 82 | 83 | 84 | ![](./res/download.png) 85 | 86 | **Figure**. It is a picture 87 | 88 | 89 | 90 | ## Mermaid diagrams 91 | 92 | See: https://mermaid.js.org/ 93 | 94 | 95 | ```mermaid 96 | --- 97 | title: A simple sequence diagram 98 | --- 99 | 100 | %% this is a comment 101 | 102 | sequenceDiagram 103 | Alice->>John: Hello John, how are you? 104 | John-->>Alice: Great! 105 | Alice-)John: See you later! 106 | 107 | ``` 108 | **Figure**. Here is a simple sequence diagram. See https://mermaid.js.org/syntax/sequenceDiagram.html 109 | 110 | 111 | ```mermaid 112 | --- 113 | title: A simple state diagram 114 | --- 115 | 116 | stateDiagram-v2 117 | [*] --> Still 118 | Still --> [*] 119 | 120 | Still --> Moving 121 | Moving --> Still 122 | Moving --> Crash 123 | Crash --> [*] 124 | 125 | ``` 126 | **Figure**. Here is a simple state diagram. See https://mermaid.js.org/syntax/stateDiagram.html 127 | 128 | 129 | ```mermaid 130 | 131 | stateDiagram 132 | direction TB 133 | 134 | accTitle: This is the accessible title 135 | accDescr: This is an accessible description 136 | 137 | classDef notMoving fill:white 138 | classDef movement font-style:italic; 139 | classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow 140 | 141 | [*] --> Still:::notMoving 142 | Still --> [*] 143 | Still --> Moving:::movement 144 | Moving --> Still 145 | Moving --> Crash:::movement 146 | Crash:::badBadEvent --> [*] 147 | 148 | 149 | ``` 150 | **Figure**. Here is a nicer simple state diagram. See https://mermaid.js.org/syntax/stateDiagram.html 151 | 152 | 153 | 154 | ## Use of footnotes 155 | 156 | In here are some examples of footnotes[^1]: 157 | 158 | 159 | Here's a simple footnote,[^2] and here's a longer one[^bignote], yet another one: 160 | 161 | > In a hole in the ground there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends 162 | of worms and an oozy smell, nor yet a dry, bare, sandy hole with nothing in it to sit down on or to eat: it was a hobbit-hole [^4], and that means comfort. 163 | 164 | 165 | ## Formulas 166 | 167 | 168 | See in [here](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/writing-mathematical-expressions) how GitHub uses formulas[^5]. 169 | 170 | This sentence uses `$` delimiters to show math inline: $\sqrt{3x-1}+(1+x)^2$ 171 | 172 | To add a math expression as a block, start a new line and delimit the expression with two dollar symbols $$. 173 | 174 | **The Cauchy-Schwarz Inequality** 175 | $$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)$$ 176 | 177 | 178 | 179 | ## Notes 180 | 181 | 182 | [^1]: A footnote may help in adding more details. See its support in [GitHub](https://github.blog/changelog/2021-09-30-footnotes-now-supported-in-markdown-fields/). 183 | 184 | [^2]: This is the first footnote. 185 | 186 | [^bignote]: Here's one with multiple paragraphs and code. 187 | 188 | Indent paragraphs keeping a new line before to include them in the footnote. 189 | 190 | addd inline code `int a{1};` or also something like that: 191 | ```C++ 192 | void caller(void *p) { } 193 | ``` 194 | 195 | Add as many paragraphs as you like. 196 | 197 | [^4]: See in here what is a hobbit-hole: "Hobbit lifestyles" 198 | 199 | [^5]: How GitHub uses formulas: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/writing-mathematical-expressions 200 | -------------------------------------------------------------------------------- /exercises/day01/markdown/02-advanced/res/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/markdown/02-advanced/res/download.png -------------------------------------------------------------------------------- /exercises/day01/markdown/03-samplereport/report.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Brief explanation of the application 4 | 5 | 6 | 7 | In here we write a brief description of the application running on the nucleoh7 board. 8 | 9 | 10 | 11 | 12 | ## Purpose of the application 13 | 14 | This application is a test program which interfaces over I2C a number of sensors: 15 | 16 | - one IMU Bosch BNO055, 17 | - one ADC ADS122C04 chip with two input channels, 18 | - two CDC AD7147 chips, which interface a skin patch former by 24 taxels. 19 | 20 | 21 | 22 | ## What the application does 23 | 24 | The application initializes the chip `BNO055`, the `ADS122C04` and two `AD7147`, starts a timer which triggers an acquisition chain every 10 ms and finally programs a GPIO to start data transmission over USART when triggered. 25 | 26 | The acquisition chain is done in the order (IMU, ADC-channel1, ADC-channel2, CDC), where the two CDC sensors are read in multiplex mode at every cycle. The data collected is stored in RAM and is transmitted over USART in binary mode when the GPIO detects a request. 27 | 28 | The application can be used for normal use when macro `macro_APPL_MODE_STANDARD` is defined but also to trace timing and and debug. In such a case pls use the other `macro_APPL*` macros inside the code. 29 | 30 | In this application we use a multithread system based onto `embot::os` to run a a single thread called `tMAIN`. We use the `embot::os` because it offers useful services and efficient event-based activation> However what the application does can be implemented using any other execution framework such as a superloop with activation flags. 31 | 32 | 33 | 34 | ## Architecture of the application 35 | 36 | This application runs with the `embot` environment which offers: 37 | 38 | - with `embot::os`: an RTOS environment with a fully pre-emptive scheduler, a number of template for threads (event-driven, periodic, callback executors, ...), services such as `theTimerManager` which manages periodic or one shot timers and insure that the associated action is executed; 39 | - with `embot::hw`: a a collection of device drivers for chips (e.g., `embot::hw::bno055` or `embot::hw::ad7147`) for required peripherals (e.g. `embot::hw::gpio`, `embot::hw::i2c`) and communication (`embot::hw::can`); the `embot::hw` is built upon the STM32 HAL drivers and is portable across a number of STM32 MPUs and boards by using the definitions and constants and functions contained in `embot::hw::bsp`; 40 | - with `embot::core`: a number of useful platform-independent functions and objects such as `embot::core::now()` to get system time, `embot::core::TimeFormatter` to express the time in string format and `embot::core::print()` to print strings to the ITM port. 41 | - with other namespaces such as `embot::app` and `embot::tools`: a collection of utility objects used by the application which in our case are `embot::app::theLEDmanager` and `embot::tools::Histogram` . 42 | 43 | The STM32 HAL driver required by `embot::hw` is included in the application by means of `stm32hal.h7.nucleoh7.v190.lib` and with the single inclusion API file `stm32hal.h`. 44 | 45 | The RTOS required by `embot::os` is included in the application by means of `osal.cm4.dbg.lib` and of its single inclusion API file `osal.h`. The file `eventviewer.c` is a companion file which allows to visualize in the KEIL environment the context switching of the scheduled threads. 46 | 47 | 48 | 49 | In here are pictures of the various groups of the project. 50 | 51 | ![](res/project.structure.jpg) 52 | 53 | **Figure**. The groups of the project. 54 | 55 | 56 | 57 | ## How the application works 58 | 59 | The applications starts from `main()` and launches the `embot::os` environment in the following way. 60 | 61 | 62 | 63 | ```C++ 64 | int main(void) 65 | { 66 | // configuration of the embot::os environment 67 | constexpr embot::os::InitThread::Config initcfg = { 4*1024, initSystem, nullptr }; 68 | constexpr embot::os::IdleThread::Config idlecfg = { 1024, nullptr, nullptr, onIdle }; 69 | constexpr embot::core::Callback onOSerror = { }; 70 | constexpr embot::os::Config osconfig {1000*embot::core::time1microsec, initcfg, idlecfg, onOSerror}; 71 | 72 | // embot::os::init() internally calls embot::hw::bsp::init() which also calls embot::core::init() 73 | embot::os::init(osconfig); 74 | 75 | // now i start the os 76 | // at first it is executed the tINIT thread in exclusive mode which calls initSystem() to init 77 | // user defined threads and then stops execution allowing the system to schedule all other threads. 78 | // note: function embot::os::start() is marked [[noreturn]] and hence ... it never returns 79 | embot::os::start(); 80 | } 81 | ``` 82 | 83 | **Code Listing**. The main(). 84 | 85 | 86 | 87 | The initialization function starts some `embot` services, such as `theTimerManager`, and then creates a single application thread called `tMAIN` . 88 | 89 | 90 | 91 | ```C++ 92 | void initSystem(embot::os::Thread *t, void* initparam) 93 | { 94 | 95 | embot::os::theTimerManager::getInstance().start({}); 96 | embot::os::theCallbackManager::getInstance().start({}); 97 | 98 | static const std::initializer_list allleds = {embot::hw::LED::one}; 99 | embot::app::theLEDmanager &theleds = embot::app::theLEDmanager::getInstance(); 100 | theleds.init(allleds); 101 | theleds.get(embot::hw::LED::one).pulse(2*embot::core::time1second); 102 | 103 | embot::os::EventThread::Config tMAINconfig { 104 | 6*1024, 105 | embot::os::Priority::high40, 106 | tMAIN_startup, 107 | nullptr, 108 | 50*embot::core::time1millisec, 109 | tMAIN_onevent 110 | }; 111 | 112 | // create the main thread 113 | thr = new embot::os::EventThread; 114 | // and start it 115 | thr->start(tMAINconfig, tMAIN); 116 | } 117 | ``` 118 | 119 | **Code Listing**. The startup of the system. 120 | 121 | 122 | 123 | In this case, the thread `tMAIN` is an event-driven thread which executes a `tMAIN_startup()` function and then it executes function `tMAIN_onevent()` only when some entity sends an event to it. In such a case it does what it must and then it returns control to the scheduler which in most cases will execute the `tIDLE` thread. 124 | 125 | In the picture below there is the thread activation diagram for our application. We can see that the thread `tTMRman` which belongs to `theTimerManager` service executes every 10 ms and triggers the execution of the thread `tMAIN` . 126 | 127 | 128 | 129 | ![](res/event.viewer.jpg) 130 | 131 | **Figure**. The thread activation diagram. 132 | 133 | 134 | 135 | All such behaviour is initialized in function `tMAIN_startup()` as following code shows. 136 | 137 | 138 | 139 | ```c++ 140 | static void s_chips_init() 141 | { 142 | ... 143 | 144 | constexpr uint32_t i2cspeed = 400000; 145 | 146 | embot::hw::bno055::Config bno055config { embot::hw::i2c::Descriptor { embot::hw::I2C::one, i2cspeed } }; 147 | embot::hw::bno055::init(embot::hw::BNO055::one, bno055config); 148 | 149 | constexpr embot::hw::bno055::Mode mode = embot::hw::bno055::Mode::ACCGYRO; 150 | constexpr embot::core::relTime timeout = 5*embot::core::time1millisec; 151 | embot::hw::bno055::set(embot::hw::BNO055::one, mode, timeout); 152 | 153 | embot::hw::ads122c04::Config adsconfig { embot::hw::i2c::Descriptor { embot::hw::I2C::one, i2cspeed } }; 154 | embot::hw::ads122c04::init(embot::hw::ADS122C04::one, adsconfig); 155 | 156 | embot::hw::ad7147::Config skconfig { embot::hw::i2c::Descriptor { embot::hw::I2C::one, i2cspeed } }; 157 | embot::hw::ad7147::init(embot::hw::AD7147::one, skconfig); 158 | embot::hw::ad7147::init(embot::hw::AD7147::two, skconfig); 159 | 160 | ... 161 | 162 | } 163 | 164 | void txrequest(void *p) 165 | { 166 | embot::os::Thread *t = reinterpret_cast(p); 167 | t->setEvent(evtDATAtransmit); 168 | } 169 | 170 | void tMAIN_startup(embot::os::Thread *t, void *param) 171 | { 172 | // init imu + adc + cdc 173 | s_chips_init(); 174 | 175 | #if defined(macro_enableEXTItransmit) 176 | // init the ext interrupt button 177 | embot::hw::button::init(buttonTX, {embot::hw::button::Mode::TriggeredOnRelease, {txrequest, t}, 0}); 178 | #endif 179 | 180 | ... 181 | embot::os::Timer *tmr = new embot::os::Timer; 182 | embot::os::Action act(embot::os::EventToThread(evtAcquisition, t)); 183 | embot::os::Timer::Config cfg{acquisitionPeriod, act, embot::os::Timer::Mode::forever, 0}; 184 | tmr->start(cfg); 185 | ... 186 | } 187 | ``` 188 | 189 | **Code Listing**. The startup of thread `tMAIN`. 190 | 191 | 192 | 193 | As first thing, the function `tMAIN_startup()` initializes the chips and the external interrupt responsible to issue a transmission request over USART. 194 | 195 | Then it starts a timer which sends every 10 ms the event `evtAcquisition` which starts the acquisition chain from the chips 196 | 197 | 198 | 199 | The actions which the thread tMAIN executes upon reception of the above events can seen in the following code. 200 | 201 | 202 | 203 | ```c++ 204 | void tMAIN_onevent(embot::os::Thread *t, embot::os::EventMask eventmask, void *param) 205 | { 206 | if(0 == eventmask) 207 | { // timeout ... 208 | return; 209 | } 210 | 211 | if(true == embot::core::binary::mask::check(eventmask, evtAcquisition)) 212 | { 213 | numberofCYCLE++; 214 | 215 | #if defined(macro_enableTRACE_activations) 216 | embot::core::TimeFormatter tf(embot::core::now()); 217 | embot::core::print("tMAIN_onevent(): evtAcquisition received @ time = " + 218 | tf.to_string(embot::core::TimeFormatter::Mode::full)); 219 | #endif 220 | s_imu_start(); 221 | ... 222 | } 223 | ... 224 | 225 | ``` 226 | 227 | **Code Listing**. Start of the acquisition chain. 228 | 229 | 230 | 231 | The acquisition chain starts with the the IMU with a call to the following code which: 232 | 233 | - logs the time of beginning of acquisition, 234 | - starts a reading request of IMU data in non-blocking mode with a termination callback which sends an event `evtIMUdataready` to the `tMAIN` thread. 235 | 236 | 237 | 238 | ```C++ 239 | void alertimudataisready(void *p) 240 | { 241 | thr->setEvent(evtIMUdataready); 242 | } 243 | 244 | static void s_imu_start() 245 | { 246 | imu_start = embot::core::now(); 247 | embot::core::Callback cbk(alertimudataisready, nullptr); 248 | embot::hw::bno055::acquisition(embot::hw::BNO055::one, embot::hw::bno055::Set::A, data, cbk); 249 | } 250 | ``` 251 | 252 | **Code Listing**. The reading request issues to the IMU. 253 | 254 | 255 | 256 | When the IMU data is ready, the I2C handler sends the activation event to the `tMAIN` which executes the following code to: 257 | 258 | - retrieve IMU data, 259 | - log the time of completion of acquisition, 260 | - start the acquisition of the second sensor in the chain 261 | 262 | And the acquisition chain goes on until the last sensor is read. All data retrieved by the sensors is cached in an array which is transmitted when the event `evtDATAtransmit` arrives, triggered by the button initialized in function `tMAIN_startup()`. 263 | 264 | 265 | 266 | ```c++ 267 | static void s_imu_get() 268 | { 269 | imu_stop = embot::core::now(); 270 | imu_acquisitiontime = imu_stop - imu_start; 271 | acc2transmit = {data.acc.x, data.acc.y, data.acc.z}; 272 | 273 | #if defined(macro_enableTRACE_histograms) 274 | histoIMU->add(imu_acquisitiontime); 275 | ... 276 | #endif 277 | } 278 | 279 | void tMAIN_onevent(embot::os::Thread *t, embot::os::EventMask eventmask, void *param) 280 | { 281 | ... 282 | 283 | if(true == embot::core::binary::mask::check(eventmask, evtIMUdataready)) 284 | { 285 | #if defined(macro_enableTRACE_activations) 286 | embot::core::TimeFormatter tf(embot::core::now()); 287 | embot::core::print("tMAIN_onevent(): evtIMUdataready received @ time = " + 288 | tf.to_string(embot::core::TimeFormatter::Mode::full)); 289 | #endif 290 | s_imu_get(); 291 | timeadc_start[0] = embot::core::now(); 292 | s_adc_start(embot::hw::ads122c04::Channel::one); 293 | timeadc_duration_of_acquisition_start[0] = embot::core::now() - timeadc_start[0]; 294 | } 295 | 296 | ``` 297 | 298 | **Code Listing**. The retrieval of data the IMU has just sent. 299 | 300 | 301 | 302 | ```c++ 303 | void tMAIN_onevent(embot::os::Thread *t, embot::os::EventMask eventmask, void *param) 304 | { 305 | ... 306 | 307 | if(true == embot::core::binary::mask::check(eventmask, evtDATAtransmit)) 308 | { 309 | #if defined(macro_enableTRACE_activations) 310 | embot::core::TimeFormatter tf(embot::core::now()); 311 | embot::core::print("tMAIN_onevent(): evtDATAtransmit received @ time = " + tf.to_string()); 312 | #endif 313 | s_transmit(); 314 | } 315 | } 316 | 317 | ``` 318 | 319 | **Code Listing**. The transmission of data over USART. 320 | 321 | 322 | 323 | 324 | 325 | 326 | ## The sensors' drivers 327 | 328 | 329 | 330 | The drivers of the sensors are implemented in the `embot::hw` namespace under these sub-namespaces: 331 | 332 | - the IMU is in `embot::hw::bno055` 333 | - the ADC is in `embot::hw::ads122c04` 334 | - the CDC is in `embot::hw::ad7147` 335 | 336 | They have dependencies from: 337 | 338 | - `embot::hw::i2c` for the I2C communication driver, 339 | - `embot::hw::bsp` for what may change from one board to another such as: 340 | - I2C pinout and handlers 341 | - I2C addresses of the chips 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | -------------------------------------------------------------------------------- /exercises/day01/markdown/03-samplereport/res/event.viewer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/markdown/03-samplereport/res/event.viewer.jpg -------------------------------------------------------------------------------- /exercises/day01/markdown/03-samplereport/res/imu-long.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/markdown/03-samplereport/res/imu-long.png -------------------------------------------------------------------------------- /exercises/day01/markdown/03-samplereport/res/imu-short.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/markdown/03-samplereport/res/imu-short.png -------------------------------------------------------------------------------- /exercises/day01/markdown/03-samplereport/res/pdf-acquisition-time-imu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/markdown/03-samplereport/res/pdf-acquisition-time-imu.jpg -------------------------------------------------------------------------------- /exercises/day01/markdown/03-samplereport/res/project.structure.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/exercises/day01/markdown/03-samplereport/res/project.structure.jpg -------------------------------------------------------------------------------- /exercises/day01/markdown/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | 4 | 5 | According to [wikipedia](https://en.wikipedia.org/wiki/Markdown): 6 | > Markdown is a lightweight markup language for creating formatted text using a plain-text editor. John Gruber and Aaron Swartz created Markdown in 2004 as a markup language that is appealing to human readers in its source code form. Markdown is widely used in blogging, instant messaging, online forums, collaborative software, documentation pages, and readme files. 7 | 8 | We shall use Markdown to document the final assigment of the `Modern C++` course. 9 | 10 | - A [basic](01-basic/basic.md) document. 11 | - An [advanced](02-advanced/advanced.md) document. 12 | - Example of a [report](./03-samplereport/report.md). 13 | 14 | 15 | Some references: 16 | 17 | - https://docs.github.com/en/get-started/writing-on-github 18 | - https://www.markdownguide.org/basic-syntax 19 | - https://www.markdownguide.org/cheat-sheet/ 20 | 21 | 22 | -------------------------------------------------------------------------------- /exercises/day02/cpp98/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) ubuntu", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/cpp98", 12 | "args": [], 13 | "cwd" : "${workspaceFolder}/build", 14 | "miDebuggerPath": "/usr/bin/gdb" 15 | }, 16 | { 17 | "name": "(gdb) gitpod", 18 | "type": "gdb", 19 | "request": "launch", 20 | "target": "${workspaceFolder}/build/cpp98", 21 | "cwd": "${workspaceRoot}", 22 | "valuesFormatting": "parseText" 23 | }, 24 | ] 25 | } -------------------------------------------------------------------------------- /exercises/day02/cpp98/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "string": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "*.tcc": "cpp", 8 | "cctype": "cpp", 9 | "clocale": "cpp", 10 | "cmath": "cpp", 11 | "compare": "cpp", 12 | "concepts": "cpp", 13 | "cstdarg": "cpp", 14 | "cstddef": "cpp", 15 | "cstdint": "cpp", 16 | "cstdio": "cpp", 17 | "cstdlib": "cpp", 18 | "cwchar": "cpp", 19 | "cwctype": "cpp", 20 | "deque": "cpp", 21 | "unordered_map": "cpp", 22 | "vector": "cpp", 23 | "exception": "cpp", 24 | "algorithm": "cpp", 25 | "functional": "cpp", 26 | "iterator": "cpp", 27 | "memory": "cpp", 28 | "memory_resource": "cpp", 29 | "numeric": "cpp", 30 | "random": "cpp", 31 | "string_view": "cpp", 32 | "system_error": "cpp", 33 | "tuple": "cpp", 34 | "type_traits": "cpp", 35 | "utility": "cpp", 36 | "initializer_list": "cpp", 37 | "iosfwd": "cpp", 38 | "iostream": "cpp", 39 | "istream": "cpp", 40 | "limits": "cpp", 41 | "new": "cpp", 42 | "numbers": "cpp", 43 | "ostream": "cpp", 44 | "stdexcept": "cpp", 45 | "streambuf": "cpp", 46 | "typeinfo": "cpp" 47 | } 48 | } -------------------------------------------------------------------------------- /exercises/day02/cpp98/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.20) 3 | 4 | set(ROOT_PROJECT_NAME cpp98) 5 | 6 | project( 7 | ${ROOT_PROJECT_NAME} 8 | VERSION 0.1.0.0 9 | 10 | DESCRIPTION "Modern C++, day02, cpp98" 11 | LANGUAGES CXX) 12 | 13 | include(../../shared/CMakeOptions.cmake) 14 | 15 | 16 | include_directories(include) 17 | 18 | # define a variable holding all the source files 19 | file(GLOB SOURCES "src/*.cpp") 20 | 21 | # add the files to the project 22 | add_executable(${ROOT_PROJECT_NAME} ${SOURCES}) 23 | 24 | -------------------------------------------------------------------------------- /exercises/day02/cpp98/include/cpp98.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // - include guard ---------------------------------------------------------------------------------------------------- 10 | 11 | #ifndef __CPP_98_H_ 12 | #define __CPP_98_H_ 13 | 14 | #include 15 | #include 16 | typedef unsigned int posv_t; 17 | 18 | // ------------------------------------------------------------------------------------------------------------------- 19 | // MODERNC++PREREQUISITES-forloop-api 20 | // C++98: the for loop [], page 4 21 | 22 | void test(); 23 | 24 | // ------------------------------------------------------------------------------------------------------------------- 25 | // MODERNC++PREREQUISITES-aminimalclass-api 26 | // C++98: a minimal class [] [], page 6 27 | // MODERNC++PREREQUISITES-aminimalclass-api 28 | // C++98: special member functions [] [], page 10 29 | 30 | namespace test01 { 31 | 32 | void run1(); // amimimalclass 33 | void run2(); // specialmemberfunctions 34 | 35 | #define LN_hasDTOR 36 | 37 | class LN 38 | { // Limited Number 39 | public: 40 | LN(const posv_t max, const posv_t val = 0); // ctor 41 | 42 | posv_t get() const; // getter 43 | void set(const posv_t val); // setter 44 | 45 | #if defined(LN_hasDTOR) 46 | ~LN(); 47 | #endif 48 | 49 | private: 50 | posv_t m_m; 51 | posv_t m_v; // implementation 52 | }; 53 | 54 | } // namespace test01 55 | 56 | 57 | // ------------------------------------------------------------------------------------------------------------------- 58 | // MODERNC++PREREQUISITES-ruleofthree-api 59 | // C++98: the rule of three [] [] [], page 13 60 | 61 | namespace test02 { 62 | 63 | void runit(); 64 | 65 | class BAD 66 | { // BAD: Array of Limited Numbers 67 | public: 68 | BAD(const size_t capacity, const posv_t max, const posv_t val = 0); // ctor 69 | 70 | posv_t get(const size_t pos) const; // getter 71 | void set(const size_t pos, const posv_t val); // setter 72 | 73 | private: 74 | size_t m_c; 75 | posv_t m_m; 76 | posv_t *m_vv; // implementation 77 | }; 78 | 79 | } // namespace test02 80 | 81 | // ------------------------------------------------------------------------------------------------------------------- 82 | // MODERNC++PREREQUISITES-ruleofthree-api-ok 83 | // C++98: the rule of three [] [] [] [], page 14 84 | 85 | namespace test03 { 86 | 87 | void runit(); 88 | 89 | class ALN 90 | { // Array of Limited Numbers 91 | public: 92 | ALN(const size_t capacity, const posv_t max, const posv_t val = 0); // ctor 93 | 94 | posv_t get(const size_t pos) const; // getter 95 | void set(const size_t pos, const posv_t val); // setter 96 | 97 | ALN(const ALN &other); // copy ctor 98 | ALN& operator=(const ALN &other); // copy assignment 99 | ~ALN(); // dtor 100 | 101 | private: 102 | size_t m_c; 103 | posv_t m_m; 104 | posv_t *m_vv; // implementation 105 | }; 106 | 107 | } // namespace test03 108 | 109 | 110 | // ------------------------------------------------------------------------------------------------------------------- 111 | // MODERNC++PREREQUISITES-composition-api 112 | // C++98: composition of classes [], page 15 113 | 114 | namespace test06 { 115 | 116 | void runit(); 117 | 118 | class LPAIR 119 | { 120 | public: 121 | LPAIR(const posv_t max, const posv_t v0 = 0, const posv_t v1 = 0); 122 | 123 | void get(posv_t &v0, posv_t &v1) const; 124 | void set(const posv_t v0, const posv_t v1); 125 | 126 | private: 127 | test01::LN ln0; 128 | test01::LN ln1; 129 | }; 130 | 131 | } // namespace test06 132 | 133 | // ------------------------------------------------------------------------------------------------------------------- 134 | // MODERNC++PREREQUISITES-inheritance-api 135 | // C++98: base class [], page 17 136 | // C++98: derived class [], page 19 137 | 138 | namespace test07 { 139 | 140 | void runit(); 141 | 142 | class Shape 143 | { 144 | public: 145 | Shape(const test06::LPAIR &position, size_t area); 146 | size_t getarea() const; 147 | void moveto(const test06::LPAIR &position); 148 | virtual void draw(); 149 | protected: 150 | test06::LPAIR _pos; 151 | size_t _area; 152 | }; 153 | 154 | 155 | class Square : public Shape 156 | { 157 | public: 158 | Square(const test06::LPAIR &position, const size_t len); 159 | void resize(size_t len); 160 | virtual void draw(); 161 | private: 162 | size_t _len; 163 | }; 164 | 165 | } // namespace test07 166 | 167 | // ------------------------------------------------------------------------------------------------------------------- 168 | // MODERNC++PREREQUISITES-interface-api 169 | // C++98: the interface class [], page 23 170 | 171 | namespace test04 { 172 | 173 | void runit(); 174 | 175 | class Person 176 | { // no ctor, no data. only: a virtual dtor + pure virtual functions 177 | public: 178 | virtual std::string getname() const = 0; 179 | virtual int getsomething() const = 0; 180 | virtual void setsomething(const int &v) = 0; 181 | virtual ~Person() {}; 182 | }; 183 | 184 | Person * generate(const std::string& name); 185 | 186 | } // namespace test04 187 | 188 | // ------------------------------------------------------------------------------------------------------------------- 189 | // MODERNC++PREREQUISITES-interface-api 190 | // another example of interface class 191 | 192 | namespace test05 { 193 | 194 | void runit(); 195 | 196 | struct DeviceDriver 197 | { 198 | enum Type { type0, type1 }; 199 | virtual int getID() const = 0; 200 | virtual void open() = 0; 201 | virtual void close() = 0; 202 | virtual int read() const = 0; 203 | virtual void write(const int &v) = 0; 204 | virtual ~DeviceDriver() {}; 205 | }; 206 | 207 | DeviceDriver * generate(const DeviceDriver::Type type, int ID); 208 | 209 | } // namespace test05 210 | 211 | // ------------------------------------------------------------------------------------------------------------------- 212 | // MODERNC++PREREQUISITES-pimpl-api 213 | // C++98: the PIMPL [], page 26 214 | 215 | namespace pimpl { 216 | 217 | void test(); 218 | 219 | class Parser 220 | { 221 | public: 222 | Parser(const char *params); 223 | ~Parser(); 224 | 225 | void parse(const char *input); 226 | 227 | private: 228 | Parser(const Parser&); // non copyable 229 | Parser& operator=(const Parser&); // 230 | 231 | struct Impl; // forward declataion of implementation class 232 | Impl* pImpl; // the PIMPL 233 | }; 234 | 235 | } 236 | 237 | // ------------------------------------------------------------------------------------------------------------------- 238 | // MODERNC++PREREQUISITES-stl-api 239 | // C++98: the std::vector<> [][][], page 31 240 | 241 | namespace test08 { 242 | 243 | void runit(); 244 | 245 | } // namespace test08 246 | 247 | 248 | #if 0 249 | namespace test11 { 250 | 251 | void runit(); 252 | 253 | } // namespace test11 254 | #endif 255 | 256 | #endif // include-guard 257 | 258 | 259 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 260 | 261 | 262 | -------------------------------------------------------------------------------- /exercises/day02/cpp98/src/cpp98.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | 10 | // -------------------------------------------------------------------------------------------------------------------- 11 | // - public interface 12 | // -------------------------------------------------------------------------------------------------------------------- 13 | 14 | #include "cpp98.h" 15 | 16 | 17 | // -------------------------------------------------------------------------------------------------------------------- 18 | // - external dependencies 19 | // -------------------------------------------------------------------------------------------------------------------- 20 | 21 | #include 22 | 23 | #include 24 | 25 | // -------------------------------------------------------------------------------------------------------------------- 26 | // - pimpl: private implementation (see scott meyers: item 22 of effective modern c++, item 31 of effective c++ 27 | // -------------------------------------------------------------------------------------------------------------------- 28 | 29 | 30 | 31 | // -------------------------------------------------------------------------------------------------------------------- 32 | // - all the rest 33 | // -------------------------------------------------------------------------------------------------------------------- 34 | 35 | // MODERNC++PREREQUISITES-forloop 36 | void test() 37 | { 38 | int count = 0; 39 | for(int i=0; i<42; i++) 40 | { 41 | count ++; 42 | } 43 | } 44 | 45 | namespace test01 { 46 | 47 | #if 0 48 | void runit() 49 | { 50 | run1(); 51 | run2(); 52 | } 53 | #endif 54 | 55 | // MODERNC++PREREQUISITES-aminimalclass-test 56 | void run1() 57 | { 58 | LN ln1(99); 59 | ln1.set(1); 60 | posv_t value = ln1.get(); 61 | value = value; 62 | } 63 | 64 | // MODERNC++PREREQUISITES-specialmemberfunctions-test 65 | void run2() 66 | { 67 | LN ln1(99, 1); 68 | // the following works fine using what the compiler implicitly generates: 69 | // copy assignment (ca), copy constructor (cc), destructor (dtor) 70 | LN lnx = ln1; // calls ca 71 | lnx = 7; // calls LN(7), then ca 72 | lnx = LN(3, 4); // calls ctor and then ca 73 | posv_t vv0 = lnx.get(); 74 | LN lny = LN(ln1); // calls cc, then ca 75 | posv_t vv1 = lny.get(); 76 | vv1 = vv1; 77 | } // dtor for: ln1, lnx, lny 78 | 79 | } // namespace test01 80 | 81 | 82 | // MODERNC++PREREQUISITES-aminimalclass-impl 83 | namespace test01 { 84 | 85 | LN::LN(const posv_t max, const posv_t val) : m_m(max), m_v(std::min(max, val)) 86 | { 87 | std::cout << "LN::CTOR -> " << "m_m = " << m_m << ", m_v = " << m_v << std::endl; 88 | } 89 | 90 | #if defined(LN_hasDTOR) 91 | LN::~LN() 92 | { 93 | std::cout << "LN::DTOR -> " << "m_m = " << m_m << ", m_v = " << m_v << std::endl; 94 | } 95 | #endif 96 | 97 | posv_t LN::get() const 98 | { 99 | return m_v; 100 | } 101 | 102 | void LN::set(const posv_t val) 103 | { 104 | m_v = std::min(val, m_m); 105 | } 106 | 107 | } // namespace test01 108 | 109 | 110 | // MODERNC++PREREQUISITES-ruleofthree-test 111 | namespace test02 { 112 | 113 | void runit() 114 | { 115 | BAD ln1(10, 99); 116 | 117 | ln1.set(0, 1); 118 | 119 | BAD ln2(20, 55); 120 | 121 | posv_t value0 = ln1.get(0); 122 | posv_t value1 = ln1.get(1); 123 | 124 | BAD lnx = ln1; 125 | lnx = BAD(15, 77); 126 | 127 | lnx = lnx; 128 | 129 | BAD lny = BAD(ln1); 130 | posv_t vv = lny.get(3); 131 | 132 | if(1 == vv) 133 | { 134 | lny.set(0, 3); 135 | } 136 | 137 | } 138 | 139 | 140 | } // namespace test02 141 | 142 | // MODERNC++PREREQUISITES-ruleofthree-impl 143 | namespace test02 { 144 | 145 | BAD::BAD(const size_t capacity, const posv_t max, const posv_t val) : 146 | m_c(capacity), m_m(max) 147 | { 148 | m_vv = new posv_t[m_c]; 149 | for(size_t i=0; imoveto(test06::LPAIR(100, 9, 9)); 300 | polym->draw(); 301 | } 302 | 303 | } 304 | 305 | // MODERNC++PREREQUISITES-inheritance-impl 306 | namespace test07 { 307 | 308 | Shape::Shape(const test06::LPAIR &position, size_t area) : _pos(position), _area(area) {} 309 | 310 | size_t Shape::getarea() const 311 | { 312 | return _area; 313 | } 314 | 315 | void Shape::moveto(const test06::LPAIR &position) 316 | { 317 | _pos = position; 318 | } 319 | 320 | void Shape::draw() 321 | { 322 | static size_t as_a_shape = 0; 323 | as_a_shape++; 324 | std::cout << "Shape::draw() is called" << std::endl; 325 | } 326 | 327 | Square::Square(const test06::LPAIR &position, const size_t len) : Shape(position, len*len), _len(len) {} 328 | 329 | void Square::resize(size_t len) 330 | { 331 | _len = len; 332 | // must now operate on protected members of Shape 333 | _area = len*len; 334 | } 335 | 336 | void Square::draw() 337 | { 338 | static size_t as_a_square = 0; 339 | as_a_square++; 340 | std::cout << "Square::draw() is called" << std::endl; 341 | } 342 | 343 | 344 | } // namespace test07 345 | 346 | 347 | 348 | // MODERNC++PREREQUISITES-interface-test 349 | namespace test04 { 350 | 351 | void runit() 352 | { 353 | Person *p = generate("Scott Meyers"); 354 | p->setsomething(3); 355 | int smt = p->getsomething(); 356 | smt = smt; 357 | 358 | delete p; 359 | } 360 | 361 | } 362 | 363 | // MODERNC++PREREQUISITES-interface-impl 364 | namespace test04 { 365 | 366 | class RealPerson: public Person 367 | { 368 | public: 369 | RealPerson(const std::string& name) : _n(name), _e(0) {} 370 | virtual ~RealPerson() {} 371 | std::string getname() const { return _n; } 372 | int getsomething() const { return _e; } 373 | void setsomething(const int &v) { _e = v; } 374 | private: 375 | std::string _n; 376 | int _e; 377 | }; 378 | 379 | Person * generate(const std::string& name) 380 | { 381 | return new RealPerson(name); 382 | } 383 | 384 | 385 | } // namespace test04 386 | 387 | 388 | // MODERNC++PREREQUISITES-interface-test 389 | namespace test05 { 390 | 391 | void runit() 392 | { 393 | DeviceDriver *d = generate(DeviceDriver::type0, 999); 394 | d->open(); 395 | d->write(100); 396 | int vv = d->read(); 397 | vv = vv; 398 | 399 | delete d; 400 | } 401 | } 402 | 403 | // MODERNC++PREREQUISITES-interface-test 404 | namespace test05 { 405 | class DD: public DeviceDriver { 406 | public: 407 | DD(const DeviceDriver::Type t, int id) : _t(t), _i(id) { _v = 0; } 408 | virtual ~DD() {} 409 | int getID() const { return _i; } 410 | void open() { } 411 | void close() { } 412 | int read() const { return _v; } 413 | void write(const int &v) { _v = v; } 414 | private: 415 | DeviceDriver::Type _t; 416 | int _i; 417 | int _v; 418 | }; 419 | 420 | 421 | DeviceDriver * generate(const DeviceDriver::Type type, int ID) 422 | { 423 | return new DD(type, ID); 424 | } 425 | 426 | } // namespace test05 427 | 428 | // ------------------------------------------------------------------------------------------------------------------- 429 | // MODERNC++PREREQUISITES-pimpl-api 430 | // C++98: the PIMPL [], page 26 431 | 432 | namespace pimpl { 433 | 434 | void test() 435 | { 436 | Parser parser("some options"); 437 | std::string str = "string to parse"; 438 | parser.parse(str.c_str()); 439 | } 440 | 441 | 442 | // the implementation 443 | 444 | struct Parser::Impl 445 | { 446 | Impl(const char *params) 447 | { 448 | // dont use it so far 449 | } 450 | 451 | void parse(const char *input) 452 | { 453 | // i just ... prints it as a string 454 | if(NULL == input) 455 | { 456 | return; 457 | } 458 | std::cout << "Parser::Impl::parse() is processing: " << input << std::endl; 459 | } 460 | 461 | }; 462 | 463 | 464 | // the interface 465 | 466 | Parser::Parser(const char *params) 467 | { 468 | pImpl = new Impl(params); 469 | } 470 | 471 | Parser::~Parser() 472 | { 473 | delete pImpl; 474 | } 475 | 476 | void Parser::parse(const char *input) 477 | { 478 | pImpl->parse(input); 479 | } 480 | 481 | } 482 | 483 | // MODERNC++PREREQUISITES-stl-test 484 | 485 | #include 486 | #include 487 | 488 | namespace test08 { 489 | 490 | void runit() 491 | { 492 | std::vector vv; 493 | vv.push_back(3); 494 | vv.push_back(1); 495 | vv.push_back(5); 496 | // now the vector contains three values: {3, 1, 5} 497 | std::cout << "vector vv contains " << vv.size() << " elements:" << std::endl; 498 | for(size_t i=0; i 11 | 12 | #include "cpp98.h" 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | std::cout << "Hello World! of Modern C++" << std::endl; 17 | 18 | 19 | #if 1 20 | 21 | // MODERNC++PREREQUISITES-forloop-run 22 | test(); 23 | 24 | // MODERNC++PREREQUISITES-aminimalclass-run 25 | test01::run1(); 26 | 27 | // MODERNC++PREREQUISITES-specialmemberfunctions-run 28 | test01::run2(); 29 | 30 | 31 | // MODERNC++PREREQUISITES-ruleofthree-run 32 | test02::runit(); 33 | 34 | // MODERNC++PREREQUISITES-ruleofthree-run-ok 35 | test03::runit(); 36 | 37 | 38 | // MODERNC++PREREQUISITES-composition-run 39 | test06::runit(); 40 | 41 | // MODERNC++PREREQUISITES-inheritance-run 42 | test07::runit(); 43 | 44 | // MODERNC++PREREQUISITES-interface-run 45 | test04::runit(); 46 | test05::runit(); 47 | 48 | // MODERNC++PREREQUISITES-pimpl-run 49 | pimpl::test(); 50 | 51 | // MODERNC++PREREQUISITES-stl-run 52 | test08::runit(); 53 | 54 | #endif 55 | 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /exercises/day03/mcore01/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) ubuntu", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/mcore01", 12 | "args": [], 13 | "cwd" : "${workspaceFolder}/build", 14 | "miDebuggerPath": "/usr/bin/gdb" 15 | }, 16 | { 17 | "name": "(gdb) gitpod", 18 | "type": "gdb", 19 | "request": "launch", 20 | "target": "${workspaceFolder}/build/mcore01", 21 | "cwd": "${workspaceRoot}", 22 | "valuesFormatting": "parseText" 23 | }, 24 | ] 25 | } -------------------------------------------------------------------------------- /exercises/day03/mcore01/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "string": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "*.tcc": "cpp", 8 | "cctype": "cpp", 9 | "clocale": "cpp", 10 | "cmath": "cpp", 11 | "compare": "cpp", 12 | "concepts": "cpp", 13 | "cstdarg": "cpp", 14 | "cstddef": "cpp", 15 | "cstdint": "cpp", 16 | "cstdio": "cpp", 17 | "cstdlib": "cpp", 18 | "cwchar": "cpp", 19 | "cwctype": "cpp", 20 | "deque": "cpp", 21 | "unordered_map": "cpp", 22 | "vector": "cpp", 23 | "exception": "cpp", 24 | "algorithm": "cpp", 25 | "functional": "cpp", 26 | "iterator": "cpp", 27 | "memory": "cpp", 28 | "memory_resource": "cpp", 29 | "numeric": "cpp", 30 | "random": "cpp", 31 | "string_view": "cpp", 32 | "system_error": "cpp", 33 | "tuple": "cpp", 34 | "type_traits": "cpp", 35 | "utility": "cpp", 36 | "initializer_list": "cpp", 37 | "iosfwd": "cpp", 38 | "iostream": "cpp", 39 | "istream": "cpp", 40 | "limits": "cpp", 41 | "new": "cpp", 42 | "numbers": "cpp", 43 | "ostream": "cpp", 44 | "stdexcept": "cpp", 45 | "streambuf": "cpp", 46 | "typeinfo": "cpp", 47 | "map": "cpp" 48 | } 49 | } -------------------------------------------------------------------------------- /exercises/day03/mcore01/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.20) 3 | 4 | set(ROOT_PROJECT_NAME mcore01) 5 | 6 | project( 7 | ${ROOT_PROJECT_NAME} 8 | VERSION 0.1.0.0 9 | 10 | DESCRIPTION "Modern C++, day03, core features part 1" 11 | LANGUAGES CXX) 12 | 13 | include(../../shared/CMakeOptions.cmake) 14 | 15 | 16 | include_directories(include) 17 | 18 | # define a variable holding all the source files 19 | file(GLOB SOURCES "src/*.cpp") 20 | 21 | # add the files to the project 22 | add_executable(${ROOT_PROJECT_NAME} ${SOURCES}) 23 | 24 | -------------------------------------------------------------------------------- /exercises/day03/mcore01/include/mcore01.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // - include guard ---------------------------------------------------------------------------------------------------- 10 | 11 | #ifndef __MCORE01_H_ 12 | #define __MCORE01_H_ 13 | 14 | 15 | // ------------------------------------------------------------------------------------------------------------------- 16 | // MODERNC++CORE-nullptr-api 17 | // 18 | 19 | namespace mcore01 { namespace ex01 { 20 | void run(); 21 | }} 22 | 23 | // ------------------------------------------------------------------------------------------------------------------- 24 | // MODERNC++CORE-auto-api 25 | // 26 | 27 | namespace mcore01::ex02 { 28 | void run(); 29 | } 30 | 31 | // ------------------------------------------------------------------------------------------------------------------- 32 | // MODERNC++CORE-typealiases-api 33 | // 34 | 35 | namespace mcore01::ex03 { 36 | void run(); 37 | } 38 | 39 | // ------------------------------------------------------------------------------------------------------------------- 40 | // MODERNC++CORE-initializerlist-api 41 | // 42 | 43 | namespace mcore01::ex04 { 44 | void run(); 45 | } 46 | 47 | // ------------------------------------------------------------------------------------------------------------------- 48 | // MODERNC++CORE-uniforminitialization-api 49 | // 50 | 51 | namespace mcore01::ex05 { 52 | void run(); 53 | } 54 | 55 | #endif // include-guard 56 | 57 | 58 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 59 | 60 | 61 | -------------------------------------------------------------------------------- /exercises/day03/mcore01/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | 10 | #include 11 | 12 | #include "mcore01.h" 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | std::cout << "Hello World! of Modern C++" << std::endl; 17 | 18 | // nullptr 19 | mcore01::ex01::run(); 20 | 21 | // auto 22 | mcore01::ex02::run(); 23 | 24 | // typealiases 25 | mcore01::ex03::run(); 26 | 27 | // initializerlist 28 | mcore01::ex04::run(); 29 | 30 | // uniforminitialization 31 | mcore01::ex05::run(); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /exercises/day03/mcore01/src/mcore01.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | 10 | // -------------------------------------------------------------------------------------------------------------------- 11 | // - public interface 12 | // -------------------------------------------------------------------------------------------------------------------- 13 | 14 | #include "mcore01.h" 15 | 16 | 17 | // -------------------------------------------------------------------------------------------------------------------- 18 | // - external dependencies 19 | // -------------------------------------------------------------------------------------------------------------------- 20 | 21 | #include 22 | 23 | #include 24 | 25 | // -------------------------------------------------------------------------------------------------------------------- 26 | // - all the rest 27 | // -------------------------------------------------------------------------------------------------------------------- 28 | 29 | 30 | // nullptr 31 | 32 | namespace mcore01 { namespace ex01 { 33 | 34 | void f(int a); 35 | void f(char *a); 36 | 37 | 38 | void run() 39 | { 40 | f(0); // calls f(int a) 41 | // f(NULL); // calls f(int a): it is not what we wanted 42 | f(nullptr); // calls f(char *a) 43 | } 44 | 45 | 46 | void f(int a) 47 | { 48 | std::cout << "called f(int a)" << std::endl; 49 | } 50 | 51 | void f(char *a) 52 | { 53 | std::cout << "called f(char *a)" << std::endl; 54 | } 55 | 56 | }} 57 | 58 | #include 59 | #include 60 | #include 61 | #include 62 | 63 | // auto 64 | 65 | namespace mcore01::ex02 { 66 | 67 | 68 | // slide 3 69 | auto add(const int a, const int b) -> int { return a+b; } // C++11 70 | auto multiply(const int a, const int b) { return a*b; } // C++14 71 | 72 | 73 | void run() 74 | { 75 | auto something {0}; 76 | something ++; 77 | std::cout << "something has value: " << something << std::endl; 78 | 79 | // slide 1 80 | { 81 | auto i = 42; // int 82 | auto d = 42.5; // double 83 | auto s = "text"; // char const * 84 | auto v = { 1, 2, 3 }; // std::initializer_list 85 | } 86 | 87 | // slide 1 extra 88 | { 89 | auto v = { 1, 2, 3 }; // std::initializer_list } 90 | auto s1 = std::string {"text"}; // std::string 91 | auto v1 = std::vector { 1, 2, 3 }; // std::vector 92 | 93 | 94 | const char * ccc = s1.c_str(); 95 | // ccc = s.c_str(); 96 | 97 | size_t size = v1.size(); 98 | size_t sizemaybe = v.size(); 99 | v1.push_back(3); 100 | // v.push_back(2); 101 | } 102 | 103 | // slide 2 104 | { 105 | auto b = new char[10] { 0 }; // char* 106 | auto bb = new char[3] { 1, 2, 3 }; // char* 107 | auto s1 = std::string {"text"}; // std::string 108 | auto v1 = std::vector { 1, 2, 3 }; // std::vector 109 | auto p = std::make_shared(42); // std::shared_ptr 110 | } 111 | 112 | // slide 3 113 | { 114 | 115 | 116 | auto x = multiply(3, 2); 117 | 118 | 119 | } 120 | 121 | // slide 4 122 | { 123 | auto half = [](const double v) { return v/2.0; }; 124 | auto result = half(8.0); 125 | } 126 | 127 | // slide 5 128 | { 129 | auto half = [](const auto a) { return a/2; }; 130 | constexpr double ninepointzero = 9.0; 131 | constexpr int eleven = 11; 132 | auto result1 = half(ninepointzero); // it is 4.5 (double) 133 | auto result2 = half(eleven); // it is 5 (int) 134 | auto x = result2; 135 | x = x; 136 | } 137 | 138 | 139 | // slide 6 140 | { 141 | 142 | auto v = std::vector{ 1, 2, 3 }; 143 | int size1 = v.size(); // actually size() returns size_t … 144 | auto size2 = v.size(); // correct type size_t 145 | 146 | } 147 | 148 | // slide 7 149 | { 150 | auto v = std::vector{ 1, 2, 3 }; 151 | int size1 = v.size(); // actually size() returns size_t … 152 | auto size2 = v.size(); // correct type size_t 153 | } 154 | 155 | // slide 8 156 | { 157 | 158 | std::map m; // given this map … 159 | // we just want to iterate 160 | for (auto it = m.cbegin(); it != m.cend(); ++it) 161 | { /*...*/ } 162 | 163 | // we don’t care about the type of the iterator it 164 | for(std::map::const_iterator it = m.cbegin(); 165 | it != m.cend(); ++it) 166 | { /*...*/ } 167 | 168 | } 169 | } 170 | 171 | 172 | 173 | } 174 | 175 | // type aliases 176 | 177 | namespace mcore01::ex03 { 178 | 179 | using byte = unsigned char; 180 | using array10b_t = byte[10]; 181 | using fpWorker = void (*)(void); 182 | void dosomething() 183 | { 184 | static array10b_t data = {0}; 185 | data[0]++; 186 | } 187 | void caller(fpWorker f) { f(); } 188 | void f1() { caller(dosomething); } 189 | 190 | typedef void (*FP0)(int &, const std::string&); // typedef 191 | 192 | // same meaning as above 193 | using FP1 = void (*)(int &, const std::string&); // alias declaration 194 | 195 | void ff(int &a, const std::string& s) 196 | { 197 | if(false == s.empty()) 198 | { 199 | a++; 200 | } 201 | } 202 | 203 | void run() 204 | { 205 | 206 | f1(); 207 | f1(); 208 | 209 | FP1 fptr = ff; 210 | 211 | int a = 3; 212 | fptr(a, ""); 213 | 214 | a = a; 215 | 216 | 217 | 218 | } 219 | 220 | } 221 | 222 | // initializer list 223 | 224 | namespace mcore01::ex04 { 225 | 226 | template 227 | struct S { 228 | std::vector v; 229 | S(std::initializer_list l) : v(l) { std::cout << "size = " << l.size(); } 230 | void append(std::initializer_list l) { v.insert(v.end(), l.begin(), l.end()); } 231 | }; 232 | 233 | 234 | size_t afun(const std::initializer_list &l) 235 | { 236 | static size_t s {0}; 237 | s = l.size(); 238 | return s; 239 | } 240 | 241 | void run() 242 | { 243 | 244 | // slide 1 245 | { 246 | // void afun(const std::initializer_list &l); 247 | auto ilis = { 10, 20, 30 }; // the type of ilis is initializer_list 248 | auto ss = afun(ilis); 249 | auto ilistr = { "hello", "world" } ; 250 | } 251 | 252 | 253 | // slide 2 254 | { 255 | std::array a3 = {1, 2, 3}; 256 | std::map mm1 = { {1, "one"}, {2, "two"} }; 257 | std::map mm2 { {3, "three"}, {4, "four"} }; 258 | 259 | } 260 | 261 | // slide 4 262 | { 263 | S s = {1, 2, 3, 4, 5}; // copy list-initialization 264 | s.append({6, 7, 8}); // list-initialization in function call 265 | } 266 | 267 | 268 | } 269 | 270 | 271 | 272 | 273 | } 274 | 275 | // uniform initialization 276 | namespace mcore01::ex05 { 277 | 278 | 279 | void run() 280 | { 281 | 282 | // slide 2 283 | { 284 | int i { 42 }; double d { 1.2 }; 285 | int arr1[3] { 1, 2, 3 }; int* arr2 = new int[3]{ 1, 2, 3 }; 286 | 287 | std::vector v { 1, 2, 3 }; 288 | std::vector v1 {}; 289 | std::map m { {1, "one"}, { 2, "two" } }; 290 | 291 | int arr[] = {3, 9, 27, 81}; 292 | std::vector vec98 (arr, arr + sizeof(arr) / sizeof(arr[0]) ); 293 | 294 | } 295 | 296 | // slide 3 297 | { 298 | class FAQ { 299 | std::string question {"*"}; 300 | int answer {42}; 301 | public: 302 | FAQ() = default; 303 | FAQ(const std::string &q, int a) : question(q), answer(a) {} 304 | void print() const { std::cout << "the answer is: " << answer << ". the question was: " << question << std::endl; } 305 | }; 306 | 307 | FAQ f0{}; 308 | FAQ f2{ "what?", 42}; 309 | f2.print(); 310 | 311 | } 312 | 313 | // slide 4 314 | { 315 | struct fee { 316 | std::array a {0, 0}; 317 | fee() = default; 318 | fee(int v1, int v2 = 1) : a{v1, v2} {} // useless 319 | fee(std::initializer_list l) 320 | { 321 | if(l.size() == 2) 322 | { 323 | auto a {l.size()}; 324 | a++; 325 | } 326 | } 327 | }; 328 | 329 | fee f { 1, 2 }; // calls constructor with initializer_list; 330 | 331 | 332 | 333 | } 334 | 335 | 336 | } 337 | 338 | } 339 | 340 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 341 | 342 | 343 | 344 | 345 | -------------------------------------------------------------------------------- /exercises/day03/test/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) ubuntu", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/test", 12 | "args": [], 13 | "cwd" : "${workspaceFolder}/build", 14 | "miDebuggerPath": "/usr/bin/gdb" 15 | }, 16 | { 17 | "name": "(gdb) gitpod", 18 | "type": "gdb", 19 | "request": "launch", 20 | "target": "${workspaceFolder}/build/test", 21 | "cwd": "${workspaceRoot}", 22 | "valuesFormatting": "parseText" 23 | }, 24 | ] 25 | } -------------------------------------------------------------------------------- /exercises/day03/test/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "string": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "*.tcc": "cpp", 8 | "cctype": "cpp", 9 | "clocale": "cpp", 10 | "cmath": "cpp", 11 | "compare": "cpp", 12 | "concepts": "cpp", 13 | "cstdarg": "cpp", 14 | "cstddef": "cpp", 15 | "cstdint": "cpp", 16 | "cstdio": "cpp", 17 | "cstdlib": "cpp", 18 | "cwchar": "cpp", 19 | "cwctype": "cpp", 20 | "deque": "cpp", 21 | "unordered_map": "cpp", 22 | "vector": "cpp", 23 | "exception": "cpp", 24 | "algorithm": "cpp", 25 | "functional": "cpp", 26 | "iterator": "cpp", 27 | "memory": "cpp", 28 | "memory_resource": "cpp", 29 | "numeric": "cpp", 30 | "random": "cpp", 31 | "string_view": "cpp", 32 | "system_error": "cpp", 33 | "tuple": "cpp", 34 | "type_traits": "cpp", 35 | "utility": "cpp", 36 | "initializer_list": "cpp", 37 | "iosfwd": "cpp", 38 | "iostream": "cpp", 39 | "istream": "cpp", 40 | "limits": "cpp", 41 | "new": "cpp", 42 | "numbers": "cpp", 43 | "ostream": "cpp", 44 | "stdexcept": "cpp", 45 | "streambuf": "cpp", 46 | "typeinfo": "cpp" 47 | } 48 | } -------------------------------------------------------------------------------- /exercises/day03/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.20) 3 | 4 | set(ROOT_PROJECT_NAME test) 5 | 6 | project( 7 | ${ROOT_PROJECT_NAME} 8 | VERSION 0.1.0.0 9 | 10 | DESCRIPTION "Modern C++, test" 11 | LANGUAGES CXX) 12 | 13 | include(../../shared/CMakeOptions.cmake) 14 | 15 | 16 | include_directories(include) 17 | 18 | # define a variable holding all the source files 19 | file(GLOB SOURCES "src/*.cpp") 20 | 21 | # add the files to the project 22 | add_executable(${ROOT_PROJECT_NAME} ${SOURCES}) 23 | 24 | -------------------------------------------------------------------------------- /exercises/day03/test/docs/report.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Printing objects 4 | 5 | 6 | 7 | In here is described the implementation of two printing objects, `printClient` and `printServer`, as per request of the test assignment in [here](../../../day01/assignment/TestAssigment.md). 8 | 9 | 10 | 11 | ## Brief introduction 12 | 13 | The exercise asks to develop two objects which acts as a printing client and a printing server. They must hide implementation with the PIMPL idiom and present minimal interface. 14 | 15 | Also, a test must be prepared so that a given sequence of strings is passed to the client which sends to the server for the actual print. 16 | 17 | 18 | 19 | ## Some details 20 | 21 | In here are some details. 22 | 23 | ### The interface 24 | 25 | I have defined a minimal interface using pure virtual classes. 26 | 27 | ```C++ 28 | 29 | namespace printer { 30 | 31 | class IFclient 32 | { 33 | public: 34 | virtual bool send(const std::string &str) = 0; 35 | virtual ~IFclient() {}; 36 | }; 37 | 38 | class IFserver 39 | { 40 | public: 41 | virtual bool receive(const std::string &str) = 0; 42 | virtual ~IFserver() {}; 43 | }; 44 | 45 | } // namespace printer { 46 | ``` 47 | 48 | **Code Listing**. The client just needs to send a string and the server to accept it. 49 | 50 | 51 | 52 | ### The `printServer` 53 | 54 | I have used the PIMPL with following public API. Apart from the functions required by the PIMPL and the `IFserver` interface, I have added a `initialise()` method which just adds a name to the server. It is not strictly required but it may be useful. 55 | 56 | The internals of the `printerServer` will print the received string maybe prefixed by the name of the server. 57 | 58 | ```C++ 59 | namespace printer { 60 | 61 | class printerServer: public IFserver 62 | { 63 | public: 64 | 65 | struct Config 66 | { 67 | std::string name; 68 | Config() : name("") {} 69 | Config(const std::string n) : name(n) {} 70 | }; 71 | 72 | printerServer(); 73 | ~printerServer(); 74 | 75 | bool initialise(const Config &config); 76 | bool receive(const std::string &str); 77 | 78 | private: 79 | printerServer(const printerServer&); 80 | printerServer& operator=(const printerServer&); 81 | 82 | struct Impl; 83 | Impl* pImpl; 84 | }; 85 | 86 | } // namespace printer { 87 | 88 | ``` 89 | 90 | **Code Listing**. The class `printerServer`. 91 | 92 | 93 | 94 | ### The `printClient` 95 | 96 | In here as well I have added a `initialise()` method which just adds a name to the server. That is purely cosmetic. 97 | 98 | The internals of the `printerClient` will send the string to a server. But which one, and how? I have solved it by adding a `IFserver *` inside the `printerClient::Config`. Well, that is important. 99 | 100 | ```C++ 101 | namespace printer { 102 | 103 | class printerClient : public IFclient 104 | { 105 | public: 106 | 107 | struct Config 108 | { 109 | IFserver * srv; // NOTE: so that the Impl can use srv->receive() 110 | std::string name; 111 | Config() : srv(NULL), name("") {} 112 | Config(IFserver *s, std::string n) : srv(s), name(n) {} 113 | }; 114 | 115 | printerClient(); 116 | ~printerClient(); 117 | 118 | bool initialise(const Config &config); 119 | bool send(const std::string &str); 120 | 121 | private: 122 | printerClient(const printerClient&); 123 | printerClient& operator=(const printerClient&); 124 | 125 | struct Impl; 126 | Impl* pImpl; 127 | }; 128 | 129 | 130 | } // namespace printer { 131 | 132 | ``` 133 | 134 | **Code Listing**. The class `printerClient`. 135 | 136 | 137 | 138 | ### The test 139 | 140 | I have decide to write a specific test for the two objects. The test just creates a client and a server and makes the client print to the server. In here are the used API. 141 | 142 | 143 | 144 | ```C++ 145 | 146 | namespace printer { namespace test { 147 | 148 | // they retrieve the pattern and print it 149 | std::vector & getpattern(); 150 | bool print(const std::vector& ss); 151 | 152 | // they obtain or release a server or a client. 153 | IFclient * obtain(IFserver *s, const std::string& name = ""); 154 | bool release(printer::IFclient *cln); 155 | IFserver * obtain(const std::string& name = ""); 156 | bool release(printer::IFserver *srv); 157 | 158 | // it tests one server and one client 159 | bool test(printer::IFserver *srv, printer::IFclient *cln); 160 | 161 | // it tests two clients sending to the same server 162 | bool test(printer::IFserver *srv, printer::IFclient *cln0, printer::IFclient *cln1); 163 | 164 | }} // namespace printer { namespace test { 165 | 166 | ``` 167 | 168 | **Code Listing**. The test namespace. 169 | 170 | 171 | 172 | And in here is the caller 173 | 174 | 175 | 176 | 177 | 178 | ```C++ 179 | /* 180 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 181 | * Author: Marco Accame 182 | * email: marco.accame@iit.it 183 | */ 184 | 185 | 186 | #include "printerTest.h" 187 | 188 | int main(int argc, char *argv[]) 189 | { 190 | printer::IFserver *srv = NULL; 191 | printer::IFclient *cln = NULL; 192 | 193 | srv = printer::test::obtain("SRV"); 194 | cln = printer::test::obtain(srv, "CLN"); 195 | 196 | printer::test::test(srv, cln); 197 | 198 | printer::test::release(srv); 199 | printer::test::release(cln); 200 | 201 | return 0; 202 | } 203 | 204 | 205 | ``` 206 | 207 | **Code Listing**. The test caller. 208 | 209 | 210 | 211 | ## How to compile and run 212 | 213 | From folder `exercises/day04` digit: 214 | 215 | ```bash 216 | day04$ mkdir build 217 | day04$ cd build 218 | day04/build$ cmake -DCMAKE_CXX_STANDARD="98" .. 219 | day04/build$ make 220 | day04/build$ ./test 221 | test() will use one printerClient and one printerServer 222 | ... start 223 | The pattern is: 224 | hello 225 | world 226 | of 227 | modern 228 | C++ 229 | ... 230 | The printer client obtains: 231 | SRV: from CLN: hello 232 | SRV: from CLN: world 233 | SRV: from CLN: of 234 | SRV: from CLN: modern 235 | SRV: from CLN: C++ 236 | ... end 237 | day04/build$ 238 | ``` 239 | 240 | **Listing**. Compile instructions 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /exercises/day03/test/include/printerClient.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | // - include guard ---------------------------------------------------------------------------------------------------- 9 | 10 | #ifndef __PRINTERCLIENT_H_ 11 | #define __PRINTERCLIENT_H_ 12 | 13 | 14 | #include "printerIF.h" 15 | #include 16 | 17 | namespace printer { 18 | 19 | class printerClient : public IFclient 20 | { 21 | public: 22 | 23 | struct Config 24 | { 25 | IFserver * srv; 26 | std::string name; 27 | Config() : srv(NULL), name("") {} 28 | Config(IFserver *s, std::string n) : srv(s), name(n) {} 29 | }; 30 | 31 | printerClient(); 32 | ~printerClient(); 33 | 34 | bool initialise(const Config &config); 35 | bool send(const std::string &str); 36 | 37 | private: 38 | printerClient(const printerClient&); 39 | printerClient& operator=(const printerClient&); 40 | 41 | struct Impl; 42 | Impl* pImpl; 43 | }; 44 | 45 | 46 | } // namespace printer { 47 | 48 | 49 | #endif // include-guard 50 | 51 | 52 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 53 | 54 | 55 | -------------------------------------------------------------------------------- /exercises/day03/test/include/printerIF.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | // - include guard ---------------------------------------------------------------------------------------------------- 9 | 10 | #ifndef __PRINTERIF_H_ 11 | #define __PRINTERIF_H_ 12 | 13 | 14 | 15 | #include 16 | 17 | namespace printer { 18 | 19 | 20 | class IFclient 21 | { 22 | public: 23 | virtual bool send(const std::string &str) = 0; 24 | virtual ~IFclient() {}; 25 | }; 26 | 27 | class IFserver 28 | { 29 | public: 30 | virtual bool receive(const std::string &str) = 0; 31 | virtual ~IFserver() {}; 32 | }; 33 | 34 | 35 | } // namespace printer { 36 | 37 | 38 | #endif // include-guard 39 | 40 | 41 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 42 | 43 | 44 | -------------------------------------------------------------------------------- /exercises/day03/test/include/printerServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | // - include guard ---------------------------------------------------------------------------------------------------- 9 | 10 | #ifndef __PRINTERSERVER_H_ 11 | #define __PRINTERSERVER_H_ 12 | 13 | 14 | #include 15 | 16 | #include "printerIF.h" 17 | 18 | namespace printer { 19 | 20 | class printerServer: public IFserver 21 | { 22 | public: 23 | 24 | struct Config 25 | { 26 | std::string name; 27 | Config() : name("") {} 28 | Config(const std::string n) : name(n) {} 29 | }; 30 | 31 | printerServer(); 32 | ~printerServer(); 33 | 34 | bool initialise(const Config &config); 35 | bool receive(const std::string &str); 36 | 37 | private: 38 | printerServer(const printerServer&); 39 | printerServer& operator=(const printerServer&); 40 | 41 | struct Impl; 42 | Impl* pImpl; 43 | }; 44 | 45 | 46 | } // namespace printer { 47 | 48 | 49 | #endif // include-guard 50 | 51 | 52 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 53 | 54 | 55 | -------------------------------------------------------------------------------- /exercises/day03/test/include/printerTest.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | // - include guard ---------------------------------------------------------------------------------------------------- 9 | 10 | #ifndef __PRINTERTEST_H_ 11 | #define __PRINTERTEST_H_ 12 | 13 | #include "printerIF.h" 14 | #include "printerClient.h" 15 | #include "printerServer.h" 16 | 17 | #include 18 | #include 19 | 20 | namespace printer { namespace test { 21 | 22 | // they retrieve the pattern and print it 23 | std::vector & getpattern(); 24 | bool print(const std::vector& ss); 25 | 26 | // they obtain or release a server or a client. 27 | IFclient * obtain(IFserver *s, const std::string& name = ""); 28 | bool release(printer::IFclient *cln); 29 | IFserver * obtain(const std::string& name = ""); 30 | bool release(printer::IFserver *srv); 31 | 32 | // it tests one server and one client 33 | bool test(printer::IFserver *srv, printer::IFclient *cln); 34 | 35 | // it tests two clients sending to the same server 36 | bool test(printer::IFserver *srv, printer::IFclient *cln0, printer::IFclient *cln1); 37 | 38 | }} // namespace printer { namespace test { 39 | 40 | 41 | #endif // include-guard 42 | 43 | 44 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 45 | 46 | 47 | -------------------------------------------------------------------------------- /exercises/day03/test/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | #include "printerTest.h" 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | printer::IFserver *srv = NULL; 14 | printer::IFclient *cln = NULL; 15 | 16 | srv = printer::test::obtain("SRV"); 17 | cln = printer::test::obtain(srv, "CLN"); 18 | 19 | printer::test::test(srv, cln); 20 | 21 | printer::test::release(srv); 22 | printer::test::release(cln); 23 | 24 | #if 0 25 | printer::IFclient *cln1 = NULL; 26 | srv = printer::test::obtain("SRV"); 27 | cln = printer::test::obtain(srv, "CLN"); 28 | cln1 = printer::test::obtain(srv, "CLN1"); 29 | 30 | printer::test::test(srv, cln, cln1); 31 | 32 | printer::test::release(srv); 33 | printer::test::release(cln); 34 | printer::test::release(cln1); 35 | #endif 36 | 37 | return 0; 38 | } 39 | 40 | 41 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 42 | 43 | 44 | -------------------------------------------------------------------------------- /exercises/day03/test/src/printerClient.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | // - public interface 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "printerClient.h" 14 | 15 | 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | // - external dependencies 18 | // -------------------------------------------------------------------------------------------------------------------- 19 | 20 | #include "printerServer.h" 21 | 22 | // -------------------------------------------------------------------------------------------------------------------- 23 | // - pimpl: private implementation (see scott meyers: item 22 of effective modern c++, item 31 of effective c++ 24 | // -------------------------------------------------------------------------------------------------------------------- 25 | 26 | 27 | 28 | namespace printer { 29 | 30 | 31 | struct printerClient::Impl 32 | { 33 | bool _initted; 34 | Config _config; 35 | 36 | Impl() 37 | { 38 | _initted = false; 39 | _config.srv = NULL; 40 | } 41 | 42 | bool initialise(const Config &config) 43 | { 44 | if(true == _initted) 45 | { 46 | return false;; 47 | } 48 | 49 | if(NULL == config.srv) 50 | { 51 | return false; 52 | } 53 | 54 | _config = config; 55 | if(_config.name == "") 56 | { 57 | _config.name = "Client"; 58 | } 59 | _initted = true; 60 | 61 | return true; 62 | } 63 | 64 | 65 | bool send(const std::string &str) 66 | { 67 | if(false == _initted) 68 | { 69 | return false; 70 | } 71 | 72 | bool r = false; 73 | 74 | // this implementation calls printerServer. 75 | // others can send the string over a socket or to another thread or to a shared memory area 76 | 77 | r = _config.srv->receive("from " + _config.name + ": " + str); 78 | 79 | return r; 80 | } 81 | 82 | }; 83 | 84 | 85 | } 86 | 87 | 88 | // -------------------------------------------------------------------------------------------------------------------- 89 | // - the class 90 | // -------------------------------------------------------------------------------------------------------------------- 91 | 92 | 93 | 94 | namespace printer { 95 | 96 | printerClient::printerClient() 97 | { 98 | pImpl = new Impl; 99 | } 100 | 101 | printerClient::~printerClient() 102 | { 103 | delete pImpl; 104 | } 105 | 106 | bool printerClient::initialise(const Config &config) 107 | { 108 | return pImpl->initialise(config); 109 | } 110 | 111 | bool printerClient::send(const std::string &str) 112 | { 113 | return pImpl->send(str); 114 | } 115 | 116 | } 117 | 118 | 119 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 120 | 121 | 122 | -------------------------------------------------------------------------------- /exercises/day03/test/src/printerServer.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | // - public interface 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "printerServer.h" 14 | 15 | 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | // - external dependencies 18 | // -------------------------------------------------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | // -------------------------------------------------------------------------------------------------------------------- 23 | // - pimpl: private implementation (see scott meyers: item 22 of effective modern c++, item 31 of effective c++ 24 | // -------------------------------------------------------------------------------------------------------------------- 25 | 26 | 27 | 28 | namespace printer { 29 | 30 | 31 | struct printerServer::Impl 32 | { 33 | 34 | bool _initted; 35 | Config _config; 36 | 37 | Impl() 38 | { 39 | _initted = false; 40 | }; 41 | 42 | bool initialise(const Config &config) 43 | { 44 | if(true == _initted) 45 | { 46 | return false;; 47 | } 48 | 49 | _config = config; 50 | if(_config.name == "") 51 | { 52 | _config.name = "Server"; 53 | } 54 | _initted = true; 55 | return true; 56 | } 57 | 58 | 59 | bool receive(const std::string &str) 60 | { 61 | if(false == _initted) 62 | { 63 | return false; 64 | } 65 | // do something 66 | 67 | std::cout << _config.name << ": " << str << std::endl; 68 | 69 | return true; 70 | } 71 | 72 | }; 73 | 74 | 75 | } 76 | 77 | 78 | // -------------------------------------------------------------------------------------------------------------------- 79 | // - the class 80 | // -------------------------------------------------------------------------------------------------------------------- 81 | 82 | 83 | 84 | namespace printer { 85 | 86 | printerServer::printerServer() 87 | { 88 | pImpl = new Impl; 89 | } 90 | 91 | printerServer::~printerServer() 92 | { 93 | delete pImpl; 94 | } 95 | 96 | bool printerServer::initialise(const Config &config) 97 | { 98 | return pImpl->initialise(config); 99 | } 100 | 101 | bool printerServer::receive(const std::string &str) 102 | { 103 | return pImpl->receive(str); 104 | } 105 | 106 | } 107 | 108 | 109 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 110 | 111 | 112 | -------------------------------------------------------------------------------- /exercises/day03/test/src/printerTest.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | // - public interface 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "printerTest.h" 14 | 15 | 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | // - external dependencies 18 | // -------------------------------------------------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | 23 | #include "printerServer.h" 24 | #include "printerClient.h" 25 | 26 | #include 27 | 28 | // -------------------------------------------------------------------------------------------------------------------- 29 | // - the code 30 | // -------------------------------------------------------------------------------------------------------------------- 31 | 32 | namespace printer { namespace test { 33 | 34 | std::vector strings; 35 | #if 0 36 | // it is not c++98 37 | std::vector strings 38 | { 39 | "hello", 40 | "world", 41 | "of", 42 | "modern", 43 | "c++" 44 | }; 45 | #endif 46 | 47 | bool get(std::vector &pattern) 48 | { 49 | pattern = getpattern(); 50 | return true; 51 | } 52 | 53 | std::vector & getpattern() 54 | { 55 | if(strings.empty()) 56 | { 57 | strings.push_back("hello"); 58 | strings.push_back("world"); 59 | strings.push_back("of"); 60 | strings.push_back("modern"); 61 | strings.push_back("C++"); 62 | } 63 | return strings; 64 | } 65 | 66 | bool print(const std::vector& ss) 67 | { 68 | std::cout << "The pattern is:" << std::endl; 69 | for(size_t i=0; iinitialise(cC); 83 | 84 | return pClient; 85 | } 86 | 87 | 88 | bool release(printer::IFclient *cln) 89 | { 90 | delete cln; 91 | return true; 92 | } 93 | 94 | IFserver * obtain(const std::string& name) 95 | { 96 | printer::printerServer *pServer = new printer::printerServer; 97 | printer::printerServer::Config cS(name); 98 | pServer->initialise(cS); 99 | 100 | return pServer; 101 | } 102 | 103 | bool release(printer::IFserver *srv) 104 | { 105 | delete srv; 106 | return true; 107 | } 108 | 109 | bool test(printer::IFserver *srv, printer::IFclient *cln) 110 | { 111 | 112 | bool r = false; 113 | 114 | std::cout << "test() will use one printerClient and one printerServer" << std::endl; 115 | std::cout << "... start" << std::endl; 116 | 117 | std::vector &ss = getpattern(); 118 | print(ss); 119 | 120 | std::cout << "The printer client obtains:" << std::endl; 121 | for(size_t i=0; isend(s); 125 | } 126 | 127 | 128 | std::cout << "... end" << std::endl << std::endl; 129 | 130 | r = true; 131 | return r; 132 | 133 | } 134 | 135 | bool test(printer::IFserver *srv, printer::IFclient *cln0, printer::IFclient *cln1) 136 | { 137 | bool r = false; 138 | 139 | std::cout << "test() will use two one printerClient and one printerServer" << std::endl; 140 | std::cout << "... start" << std::endl; 141 | 142 | std::vector &ss = getpattern(); 143 | print(ss); 144 | 145 | std::cout << "The first printer client obtains:" << std::endl; 146 | for(size_t i=0; isend(s); 150 | } 151 | 152 | std::cout << "The second printer client obtains:" << std::endl; 153 | for(size_t i=0; isend(s); 157 | } 158 | 159 | std::cout << "... end" << std::endl << std::endl; 160 | 161 | r = true; 162 | return r; 163 | 164 | } 165 | 166 | 167 | 168 | 169 | }} // namespace printer { namespace test { 170 | 171 | 172 | 173 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 174 | 175 | 176 | -------------------------------------------------------------------------------- /exercises/day04/mcore02/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) ubuntu", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/mcore02", 12 | "args": [], 13 | "cwd" : "${workspaceFolder}/build", 14 | "miDebuggerPath": "/usr/bin/gdb" 15 | }, 16 | { 17 | "name": "(gdb) gitpod", 18 | "type": "gdb", 19 | "request": "launch", 20 | "target": "${workspaceFolder}/build/mcore02", 21 | "cwd": "${workspaceRoot}", 22 | "valuesFormatting": "parseText" 23 | }, 24 | ] 25 | } -------------------------------------------------------------------------------- /exercises/day04/mcore02/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "string": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "*.tcc": "cpp", 8 | "cctype": "cpp", 9 | "clocale": "cpp", 10 | "cmath": "cpp", 11 | "compare": "cpp", 12 | "concepts": "cpp", 13 | "cstdarg": "cpp", 14 | "cstddef": "cpp", 15 | "cstdint": "cpp", 16 | "cstdio": "cpp", 17 | "cstdlib": "cpp", 18 | "cwchar": "cpp", 19 | "cwctype": "cpp", 20 | "deque": "cpp", 21 | "unordered_map": "cpp", 22 | "vector": "cpp", 23 | "exception": "cpp", 24 | "algorithm": "cpp", 25 | "functional": "cpp", 26 | "iterator": "cpp", 27 | "memory": "cpp", 28 | "memory_resource": "cpp", 29 | "numeric": "cpp", 30 | "random": "cpp", 31 | "string_view": "cpp", 32 | "system_error": "cpp", 33 | "tuple": "cpp", 34 | "type_traits": "cpp", 35 | "utility": "cpp", 36 | "initializer_list": "cpp", 37 | "iosfwd": "cpp", 38 | "iostream": "cpp", 39 | "istream": "cpp", 40 | "limits": "cpp", 41 | "new": "cpp", 42 | "numbers": "cpp", 43 | "ostream": "cpp", 44 | "stdexcept": "cpp", 45 | "streambuf": "cpp", 46 | "typeinfo": "cpp", 47 | "map": "cpp", 48 | "bitset": "cpp" 49 | } 50 | } -------------------------------------------------------------------------------- /exercises/day04/mcore02/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.20) 3 | 4 | set(ROOT_PROJECT_NAME mcore02) 5 | 6 | project( 7 | ${ROOT_PROJECT_NAME} 8 | VERSION 0.1.0.0 9 | 10 | DESCRIPTION "Modern C++, day03, core features part 2" 11 | LANGUAGES CXX) 12 | 13 | include(../../shared/CMakeOptions.cmake) 14 | 15 | 16 | include_directories(include) 17 | 18 | # define a variable holding all the source files 19 | file(GLOB SOURCES "src/*.cpp") 20 | 21 | # add the files to the project 22 | add_executable(${ROOT_PROJECT_NAME} ${SOURCES}) 23 | 24 | -------------------------------------------------------------------------------- /exercises/day04/mcore02/include/mcore02.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // - include guard ---------------------------------------------------------------------------------------------------- 10 | 11 | #ifndef __MCORE02_H_ 12 | #define __MCORE02_H_ 13 | 14 | 15 | // ------------------------------------------------------------------------------------------------------------------- 16 | // MODERNC++CORE-array 17 | // 18 | 19 | namespace mcore02 { namespace ex06 { 20 | void run(); 21 | }} 22 | 23 | // ------------------------------------------------------------------------------------------------------------------- 24 | // MODERNC++CORE-rangebasedloop 25 | // 26 | 27 | namespace mcore02::ex07 { 28 | void run(); 29 | } 30 | 31 | // ------------------------------------------------------------------------------------------------------------------- 32 | // MODERNC++CORE-constexpr 33 | // 34 | 35 | namespace mcore02::ex08 { 36 | void run(); 37 | } 38 | 39 | // ------------------------------------------------------------------------------------------------------------------- 40 | // MODERNC++CORE-scoped enum 41 | // 42 | 43 | namespace mcore02::ex09 { 44 | void run(); 45 | } 46 | 47 | // ------------------------------------------------------------------------------------------------------------------- 48 | // MODERNC++CORE-override 49 | // 50 | 51 | namespace mcore02::ex10 { 52 | void run(); 53 | } 54 | 55 | #endif // include-guard 56 | 57 | 58 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 59 | 60 | 61 | -------------------------------------------------------------------------------- /exercises/day04/mcore02/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | 10 | #include 11 | 12 | #include "mcore02.h" 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | std::cout << "Hello World! of Modern C++" << std::endl; 17 | 18 | // std::array<> 19 | mcore02::ex06::run(); 20 | 21 | // range based loop 22 | mcore02::ex07::run(); 23 | 24 | // constexpr 25 | mcore02::ex08::run(); 26 | 27 | // enum+constexpr 28 | mcore02::ex09::run(); 29 | 30 | // override 31 | mcore02::ex10::run(); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /exercises/day04/mcore02/src/mcore02.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | 10 | // -------------------------------------------------------------------------------------------------------------------- 11 | // - public interface 12 | // -------------------------------------------------------------------------------------------------------------------- 13 | 14 | #include "mcore02.h" 15 | 16 | 17 | // -------------------------------------------------------------------------------------------------------------------- 18 | // - external dependencies 19 | // -------------------------------------------------------------------------------------------------------------------- 20 | 21 | #include 22 | 23 | #include 24 | 25 | // -------------------------------------------------------------------------------------------------------------------- 26 | // - all the rest 27 | // -------------------------------------------------------------------------------------------------------------------- 28 | 29 | 30 | // std::array 31 | 32 | #include 33 | #include 34 | 35 | namespace mcore02 { namespace ex06 { 36 | 37 | struct T1 38 | { 39 | T1() = default; 40 | T1(size_t a, size_t b) : pa(a, b) {} 41 | void fill(size_t a, size_t b) { pa = {a, b}; } 42 | void print() const { std::cout << "T1 = (" << pa.first << ", " << pa.second << ")" << std::endl; } 43 | private: 44 | std::pair pa {0, 0}; 45 | }; 46 | 47 | constexpr size_t numberof {8}; 48 | 49 | void run() 50 | { 51 | std::array anarrayofT1 = {}; 52 | 53 | size_t s = anarrayofT1.size(); 54 | anarrayofT1.at(2).fill(1, 2); 55 | anarrayofT1[0] = {3, 4}; 56 | 57 | anarrayofT1[0].print(); 58 | } 59 | 60 | }} 61 | 62 | #include 63 | #include 64 | #include 65 | #include 66 | 67 | // range based llop 68 | 69 | namespace mcore02::ex07 { 70 | 71 | 72 | void run() 73 | { 74 | 75 | // slide 1 76 | { 77 | std::vector fibo {0, 1, 1, 2, 3, 5, 8, 13}; 78 | std::vector names {}; 79 | for(const auto &a : fibo) { 80 | names.push_back("name = " + std::to_string(a)); 81 | } 82 | for(const auto &na : names) { 83 | std::cout << na << std::endl; 84 | } 85 | } 86 | 87 | // slide 2 88 | { 89 | std::vector fibo {0, 1, 1, 2, 3, 5, 8, 13}; 90 | std::vector names {}; 91 | for(auto a : fibo) { 92 | a++; 93 | } 94 | for(const auto &a : fibo) { 95 | names.push_back("name = " + std::to_string(a)); 96 | } 97 | for(const auto &na : names) { 98 | std::cout << na << std::endl; 99 | } 100 | } 101 | 102 | // slide 3 103 | { 104 | 105 | } 106 | 107 | } 108 | 109 | 110 | 111 | } 112 | 113 | // constexpr 114 | 115 | namespace mcore02::ex08 { 116 | 117 | constexpr unsigned int factorial(const unsigned int n) 118 | { 119 | return n > 1 ? n * factorial(n-1) : 1; 120 | } 121 | 122 | constexpr size_t f3 = factorial(3); 123 | constexpr size_t f4 = factorial(4); 124 | 125 | 126 | struct P3D { 127 | static constexpr double MAX {9.0}; 128 | 129 | double const x_; double const y_; double const z_; 130 | constexpr P3D(const double x = 0, const double y = 0, const double z = 0) 131 | : x_{x}, y_{y}, z_{z} {} 132 | constexpr double get_x() const {return x_;} 133 | constexpr double get_y() const {return y_;} 134 | constexpr double get_z() const {return z_;} 135 | }; 136 | 137 | 138 | void run() 139 | { 140 | if(f4 > f3) 141 | { 142 | std::cout << "factorial(3) = " << f3 << std::endl; 143 | } 144 | 145 | constexpr P3D pd3 {1.0, 2.0, 20.0}; 146 | 147 | auto x = pd3.get_x(); 148 | 149 | 150 | } 151 | 152 | } 153 | 154 | // enum+constexpr 155 | 156 | #include 157 | namespace mcore02::ex09 { 158 | 159 | template // // C++14 [Meyers, pag. 73] 160 | constexpr auto toUType(E enumerator) noexcept { 161 | return static_cast>(enumerator); 162 | } 163 | 164 | 165 | 166 | template 167 | struct eMap { 168 | static_assert(toUType(max) < (8*sizeof(unsigned long long)), "size error"); 169 | std::bitset mapp; 170 | constexpr eMap(const std::initializer_list &li) { 171 | unsigned long long m = 0; 172 | for(auto &e : li) m |= (static_cast(1) << toUType(e)); 173 | mapp = m; 174 | } 175 | constexpr bool available(E e) const { return mapp[toUType(e)]; } 176 | }; 177 | 178 | enum class Led : std::uint8_t { red = 0, green = 1, blue = 2, white = 63, max = white }; 179 | 180 | constexpr eMap theLEDs {Led::red, Led::blue}; 181 | 182 | void dosomething() 183 | { 184 | volatile int a {0}; 185 | std::cout << "a = " << a << std::endl; 186 | } 187 | 188 | void doit() 189 | { 190 | volatile int b {1}; 191 | std::cout << "b = " << b << std::endl; 192 | } 193 | 194 | void run() 195 | { 196 | if(theLEDs.available(Led::green)) { // resolved at compile time. 197 | dosomething(); // on armclang compiler with 0 optimization … 198 | } // no code is generated. 199 | 200 | if(theLEDs.available(Led::red)) { // resolved at compile time. 201 | doit(); // on armclang compiler with 0 optimization … 202 | } 203 | } 204 | 205 | } 206 | 207 | // override 208 | namespace mcore02::ex10 { 209 | 210 | void run() 211 | { 212 | 213 | 214 | } 215 | 216 | } 217 | 218 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 219 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /exercises/day04/modernpimpl/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) ubuntu", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/mpimpl", 12 | "args": [], 13 | "cwd" : "${workspaceFolder}/build", 14 | "miDebuggerPath": "/usr/bin/gdb" 15 | }, 16 | { 17 | "name": "(gdb) gitpod", 18 | "type": "gdb", 19 | "request": "launch", 20 | "target": "${workspaceFolder}/build/mpimpl", 21 | "cwd": "${workspaceRoot}", 22 | "valuesFormatting": "parseText" 23 | }, 24 | ] 25 | } -------------------------------------------------------------------------------- /exercises/day04/modernpimpl/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "string": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "*.tcc": "cpp", 8 | "cctype": "cpp", 9 | "clocale": "cpp", 10 | "cmath": "cpp", 11 | "compare": "cpp", 12 | "concepts": "cpp", 13 | "cstdarg": "cpp", 14 | "cstddef": "cpp", 15 | "cstdint": "cpp", 16 | "cstdio": "cpp", 17 | "cstdlib": "cpp", 18 | "cwchar": "cpp", 19 | "cwctype": "cpp", 20 | "deque": "cpp", 21 | "unordered_map": "cpp", 22 | "vector": "cpp", 23 | "exception": "cpp", 24 | "algorithm": "cpp", 25 | "functional": "cpp", 26 | "iterator": "cpp", 27 | "memory": "cpp", 28 | "memory_resource": "cpp", 29 | "numeric": "cpp", 30 | "random": "cpp", 31 | "string_view": "cpp", 32 | "system_error": "cpp", 33 | "tuple": "cpp", 34 | "type_traits": "cpp", 35 | "utility": "cpp", 36 | "initializer_list": "cpp", 37 | "iosfwd": "cpp", 38 | "iostream": "cpp", 39 | "istream": "cpp", 40 | "limits": "cpp", 41 | "new": "cpp", 42 | "numbers": "cpp", 43 | "ostream": "cpp", 44 | "stdexcept": "cpp", 45 | "streambuf": "cpp", 46 | "typeinfo": "cpp" 47 | }, 48 | "C_Cpp.errorSquiggles": "disabled" 49 | } -------------------------------------------------------------------------------- /exercises/day04/modernpimpl/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.20) 3 | 4 | set(ROOT_PROJECT_NAME mpimpl) 5 | 6 | project( 7 | ${ROOT_PROJECT_NAME} 8 | VERSION 0.1.0.0 9 | 10 | DESCRIPTION "Modern C++, Use of PIMPL" 11 | LANGUAGES CXX) 12 | 13 | include(../../shared/CMakeOptions.cmake) 14 | 15 | 16 | include_directories(include) 17 | 18 | # define a variable holding all the source files 19 | file(GLOB SOURCES "src/*.cpp") 20 | 21 | # add the files to the project 22 | add_executable(${ROOT_PROJECT_NAME} ${SOURCES}) 23 | 24 | -------------------------------------------------------------------------------- /exercises/day04/modernpimpl/README.md: -------------------------------------------------------------------------------- 1 | In here are some basic objects using the PIMPL 2 | -------------------------------------------------------------------------------- /exercises/day04/modernpimpl/include/modernprinter.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | // - include guard ---------------------------------------------------------------------------------------------------- 9 | 10 | #ifndef __MODERNPRINTER_H_ 11 | #define __MODERNPRINTER_H_ 12 | 13 | #include 14 | #include 15 | 16 | namespace modern::printer { 17 | 18 | class Client 19 | { 20 | public: 21 | 22 | struct Config 23 | { 24 | static constexpr const char *defaultname {"Client"}; 25 | const char * name {defaultname}; 26 | constexpr Config() = default; 27 | constexpr Config(const char *n) : name((nullptr != n) ? n : defaultname) {} 28 | }; 29 | 30 | Client(); 31 | ~Client(); 32 | 33 | bool initialise(const Config &config); 34 | bool send(const std::string &str); 35 | 36 | Client(const Client&) = delete; // non copyable 37 | Client& operator=(const Client&) = delete; // non copyable 38 | Client(Client&&) = delete; // non moveable 39 | Client& operator=(Client&&) = delete; // non moveable 40 | 41 | private: 42 | struct Impl; 43 | std::unique_ptr pImpl; 44 | }; 45 | 46 | 47 | class theServer 48 | { 49 | public: 50 | static theServer& getInstance(); 51 | 52 | struct Config 53 | { 54 | static constexpr const char *defaultname {"theServer"}; 55 | const char * name {defaultname}; 56 | constexpr Config() = default; 57 | constexpr Config(const char *n) : name((nullptr != n) ? n : defaultname) {} 58 | }; 59 | 60 | bool initialise(const Config &config); 61 | bool receive(const std::string &str); 62 | 63 | theServer(const theServer&) = delete; // non copyable 64 | theServer& operator=(const theServer&) = delete; // non copyable 65 | theServer(theServer&&) = delete; // non moveable 66 | theServer& operator=(theServer&&) = delete; // non moveable 67 | 68 | private: 69 | theServer(); 70 | private: 71 | struct Impl; 72 | std::unique_ptr pImpl; 73 | }; 74 | 75 | } 76 | 77 | 78 | #endif // include-guard 79 | 80 | 81 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 82 | 83 | 84 | -------------------------------------------------------------------------------- /exercises/day04/modernpimpl/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | #include "modernprinter.h" 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | modern::printer::Client *c {nullptr}; 14 | modern::printer::Client cli {}; 15 | 16 | { // first scope 17 | modern::printer::theServer &srv = modern::printer::theServer::getInstance(); 18 | srv.initialise({}); 19 | srv.receive("hello, i am the server and i am ready to accept a string from a client"); 20 | } 21 | 22 | { // second scope: at exit client01 calls its ctor 23 | modern::printer::Client client01 {}; 24 | client01.initialise({"Client01"}); 25 | client01.send("first test print"); 26 | } 27 | 28 | { // third scope: at exit cl does not call its ctor 29 | modern::printer::Client *cl = new modern::printer::Client; 30 | cl->initialise({"Client02ptr"}); 31 | cl->send("second test print"); 32 | c = cl; 33 | // cli = *cl; // can call the copy assignment operator? 34 | } 35 | 36 | delete c; 37 | 38 | 39 | 40 | return 0; 41 | } 42 | 43 | 44 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 45 | 46 | 47 | -------------------------------------------------------------------------------- /exercises/day04/modernpimpl/src/moderprinter.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | // - public interface 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "modernprinter.h" 14 | 15 | 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | // - external dependencies 18 | // -------------------------------------------------------------------------------------------------------------------- 19 | 20 | #include 21 | #include 22 | 23 | // -------------------------------------------------------------------------------------------------------------------- 24 | // - pimpl: private implementation (see scott meyers: item 22 of effective modern c++, item 31 of effective c++ 25 | // -------------------------------------------------------------------------------------------------------------------- 26 | 27 | 28 | 29 | struct modern::printer::Client::Impl 30 | { 31 | bool _initted {false}; 32 | Config _config {}; 33 | 34 | Impl() = default; 35 | 36 | bool initialise(const Config &config) 37 | { 38 | if(true == _initted) 39 | { 40 | return false; 41 | } 42 | 43 | _config = config; 44 | _initted = true; 45 | 46 | return _initted; 47 | } 48 | 49 | 50 | bool send(const std::string &str) 51 | { 52 | auto r {false}; 53 | 54 | if(false == _initted) 55 | { 56 | return r; 57 | } 58 | 59 | 60 | 61 | // this implementation calls printer::Server. 62 | // others can send the string over a socket or to another thread or to a shared memory area 63 | 64 | r = modern::printer::theServer::getInstance().receive(std::string(_config.name) + ": " + str); 65 | // r = _config.srv->receive("from " + _config.name + ": " + str); 66 | 67 | return r; 68 | } 69 | 70 | }; 71 | 72 | 73 | struct modern::printer::theServer::Impl 74 | { 75 | bool _initted {false}; 76 | Config _config {}; 77 | 78 | Impl() = default; 79 | 80 | bool initialise(const Config &config) 81 | { 82 | if(true == _initted) 83 | { 84 | return false; 85 | } 86 | 87 | _config = config; 88 | _initted = true; 89 | 90 | return _initted; 91 | } 92 | 93 | 94 | bool receive(const std::string &str) 95 | { 96 | bool r {false}; 97 | 98 | if(false == _initted) 99 | { 100 | return r; 101 | } 102 | 103 | // do something 104 | 105 | 106 | std::cout << _config.name << ": " << str << std::endl; 107 | r = true; 108 | 109 | return r; 110 | } 111 | 112 | }; 113 | 114 | 115 | 116 | 117 | 118 | // -------------------------------------------------------------------------------------------------------------------- 119 | // - the class 120 | // -------------------------------------------------------------------------------------------------------------------- 121 | 122 | 123 | 124 | namespace modern::printer { 125 | 126 | Client::Client() : pImpl(std::make_unique()) {} 127 | Client::~Client() = default; 128 | 129 | 130 | bool Client::initialise(const Config &config) 131 | { 132 | return pImpl->initialise(config); 133 | } 134 | 135 | bool Client::send(const std::string &str) 136 | { 137 | return pImpl->send(str); 138 | } 139 | 140 | } 141 | 142 | namespace modern::printer { 143 | 144 | theServer& theServer::getInstance() 145 | { 146 | static theServer instance; 147 | return instance; 148 | } 149 | 150 | theServer::theServer() 151 | { 152 | pImpl = std::make_unique(); 153 | } 154 | 155 | bool theServer::initialise(const Config &config) 156 | { 157 | return pImpl->initialise(config); 158 | } 159 | 160 | bool theServer::receive(const std::string &str) 161 | { 162 | return pImpl->receive(str); 163 | } 164 | 165 | } 166 | 167 | 168 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 169 | 170 | 171 | -------------------------------------------------------------------------------- /exercises/day05/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | 3 | set(ROOT_PROJECT_NAME lambda_algo_containers) 4 | 5 | project(${ROOT_PROJECT_NAME}) 6 | 7 | include(../shared/CMakeOptions.cmake) 8 | 9 | add_executable(${PROJECT_NAME} main.cpp) 10 | -------------------------------------------------------------------------------- /exercises/day05/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | { 8 | std::vector numbers; 9 | numbers.push_back(1); 10 | numbers.push_back(2); 11 | numbers.push_back(3); 12 | numbers.push_back(4); 13 | numbers.push_back(5); 14 | 15 | for (int i = 0; i< numbers.size(); i++) { 16 | 17 | numbers[i] = numbers[i] * 2; 18 | std::cout << numbers[i] << " "; 19 | } 20 | std::cout << std::endl; 21 | } 22 | 23 | { 24 | // TODO: Rewrite the above code using modern c++ using algorithm and lambda 25 | 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /exercises/day06/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | 3 | set(ROOT_PROJECT_NAME smart_pointers) 4 | 5 | set(CMAKE_CXX_STANDARD 14) 6 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 7 | set(CMAKE_BUILD_TYPE debug) 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") 9 | 10 | project(${ROOT_PROJECT_NAME}) 11 | 12 | include(../shared/CMakeOptions.cmake) 13 | 14 | add_executable(${PROJECT_NAME} main.cpp) 15 | -------------------------------------------------------------------------------- /exercises/day06/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Point { 5 | double X{0.0}; 6 | double Y{0.0}; 7 | Point(double _x, double _y): X(_x), Y(_y) {}; 8 | }; 9 | 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | { 14 | // Block with raw pointer lifecycle 15 | double* d = new double (1.0); 16 | Point* pt = new Point(1.0, 2.0); // Two-d Point class 17 | // Dereference and call member functions 18 | *d = 2.0; 19 | (*pt).X = 3.0; // Modify x coordinate 20 | (*pt).Y = 3.0; // Modify y coordinate 21 | std::cout<X<<" "<Y<X = 5.0; // Modify x coordinate 24 | pt->Y = 6.0; // Modify y coordinate 25 | std::cout<X<<" "<Y<X<<" "<Y<X = 5.0; // Modify x coordinate 48 | pt2->Y = 6.0; // Modify y coordinate 49 | std::cout<X<<" "<Y< 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | //using namespace std; 10 | 11 | int data = 123; 12 | bool isDataReady = false; 13 | std::mutex mymutex; 14 | std::condition_variable c_var; 15 | const auto number_of_iteration = 5; 16 | 17 | void consumer() 18 | { 19 | std::cout << std::endl << std::endl << "******* Consumer: created *************" << std::endl; 20 | auto i=0; 21 | while(true) 22 | { 23 | 24 | std::cout << std::endl << std::endl << "Consumer: ------------- iteration num " << i+1 << std::endl; 25 | std::unique_lock ul(mymutex); //note we use unique_lock instead of lock_guard 26 | c_var.wait(ul, [](){return isDataReady;}); //the check is useful for avoiding spurious wake 27 | 28 | std::cout << "Consumer: I received the notification " << std::endl; //and wait function has locked the mutex, so I can change the data in shared memory 29 | 30 | int mydata = data; //get the data 31 | isDataReady = false; 32 | ul.unlock(); 33 | 34 | //consume data outside the critical section 35 | std::cout << "Consumer: my data is " << mydata << std::endl; 36 | i++; 37 | } 38 | 39 | } 40 | 41 | void producer() 42 | { 43 | std::cout << std::endl << std::endl << "********* Producer: created ***********" << std::endl; 44 | auto i=0; 45 | while(true) 46 | { 47 | 48 | std::cout << std::endl << std::endl << "Producer: ------------- iteration num " << i+1 << std::endl; 49 | //1. prepare the data 50 | int dataProd = std::rand(); 51 | std::cout << "Producer: my data is " << dataProd << std::endl; 52 | 53 | //2. pass the data in the shared memory 54 | { 55 | std::lock_guard ul(mymutex); 56 | std::cout << "Producer: enter in critical section ..." << dataProd << std::endl; 57 | 58 | data = dataProd; 59 | isDataReady = true; 60 | } 61 | 62 | std::cout << "Producer: I'm abut to notify ... " << dataProd << std::endl; 63 | c_var.notify_one(); //Here I have only one thread, otherwise I caould call notify_all() 64 | std::cout << "Producer: I'm abut to sleep ... " << dataProd << std::endl; 65 | std::this_thread::sleep_for(std::chrono::seconds(5)); 66 | i++; 67 | } 68 | 69 | } 70 | 71 | int main () 72 | { 73 | std::thread consumer_th (consumer); 74 | std::thread producer_th (producer); 75 | 76 | producer_th.join(); 77 | consumer_th.join(); 78 | 79 | std::cout << "main ending..." < 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void accumulate(std::vector::iterator first, 9 | std::vector::iterator last, 10 | std::promise accumulate_promise) 11 | { 12 | int sum = std::accumulate(first, last, 0); 13 | std::this_thread::sleep_for(std::chrono::seconds(3)); //simulate to do some work 14 | std::cout << "I'm in accumulate... I'm about to set the result in promise.." < barrier) 19 | { 20 | std::this_thread::sleep_for(std::chrono::seconds(1)); 21 | barrier.set_value(); 22 | } 23 | 24 | 25 | int square(std::future f) 26 | { 27 | std::cout << "I'm in square... I'm wainting the input.." < myfuture = std::async(generateString, "Valentia", "Gaggero"); 48 | std::cout << "main: the result of generateString is: \"" << myfuture.get() << "\""< crash !!!! 50 | 51 | 52 | 53 | // ---- 2) Demonstrate using promise to pass a value to the thread in the future. 54 | std::cout << std::endl<< std::endl<< "--------------------------------------------------" < square_promise; 57 | std::future square_future = square_promise.get_future(); 58 | std::thread square_thread (square, std::move(square_future)); 59 | 60 | int input; 61 | std::cout << "Please digit the number for square func:" <>input; 63 | square_promise.set_value(input); 64 | square_thread.join(); 65 | 66 | 67 | // ---- 2.1 ) Demonstrate using promise to pass a value to the thread in the future. 68 | std::cout << std::endl<< std::endl<< "--------------------------------------------------" < square_promise2; //movable only class 71 | std::future square_future2 = square_promise2.get_future(); 72 | std::future square_fu = std::async(std::launch::async, square, std::move(square_future2)); 73 | 74 | std::cout << "Please digit the number:" <>input; 76 | square_promise2.set_value(input); 77 | 78 | std::cout << "main: the result of square is: " << square_fu.get() < to get the result from a thread. 83 | 84 | std::cout << std::endl<< std::endl<< "--------------------------------------------------" < numbers = { 1, 2, 3, 4, 5, 6 }; 87 | std::promise accumulate_promise; 88 | std::future accumulate_future = accumulate_promise.get_future(); 89 | std::thread work_thread(accumulate, numbers.begin(), numbers.end(), 90 | std::move(accumulate_promise)); 91 | std::cout << "main: I'm waiting the accumulate result .... " < to get the result from a thread. 98 | std::vector numbers = { 1, 2, 3, 4, 5, 6 }; 99 | std::promise accumulate_promise; 100 | std::future accumulate_future = accumulate_promise.get_future(); 101 | std::thread work_thread(accumulate, numbers.begin(), numbers.end(), 102 | std::move(accumulate_promise)); 103 | 104 | 105 | // ---- 3) Demonstrate using promise to pass a value to the thread in the future. 106 | std::promise square_promise; 107 | std::future square_future = square_promise.get_future(); 108 | std::thread square_thread (square, std::move(square_future)); 109 | 110 | 111 | //future::get() will wait until the future has a valid result and retrieves it. 112 | //Calling wait() before get() is not needed 113 | std::cout << "main: I'm waiting the accumulate result .... " < 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | template 8 | T add (T a, T b) requires std::integral{ 9 | return a+b; 10 | } 11 | 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | { 16 | char a_char{10}; 17 | char b_char(10); 18 | 19 | int a_int{10}; 20 | int b_int{20}; 21 | 22 | double a_double{10}; 23 | double b_double{10}; 24 | 25 | // auto result = add(...,...); 26 | //std::cout<<"The result is "< in the PIMPL idiom. 17 | 18 | In particular, Scott Meyers in his book `Effective Modern C++` in item 22 suggested something such as in 19 | the exercises. 20 | 21 | ### Use of PIMPL in a singleton 22 | 23 | Mixing up Scott Meyers' C++98 book `More Effective C++` (item 26) and `Effective Modern C++` (item 22) we have a singleton w/ unique pointers, non copiable nor moveable, that can be used in multithread environment. 24 | 25 | See exercises. 26 | 27 | 28 | -------------------------------------------------------------------------------- /exercises/day09/morepimpl/include/modernpimpl.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | // - include guard ---------------------------------------------------------------------------------------------------- 9 | 10 | #ifndef __MODERNPIMPL_H_ 11 | #define __MODERNPIMPL_H_ 12 | 13 | #include 14 | #include 15 | 16 | 17 | 18 | namespace modern::pimpl::v00 { 19 | 20 | class Widget { 21 | public: 22 | Widget(); 23 | 24 | void doit(); 25 | 26 | private: 27 | struct Impl; // use smart pointer 28 | std::unique_ptr pImpl; // and pointer to it 29 | }; 30 | 31 | } 32 | 33 | 34 | namespace modern::pimpl::v01 { 35 | 36 | // {copiable, moveable} = {false, false} 37 | // ruleofzero = false. but needed. 38 | class Widget { 39 | public: 40 | Widget(); 41 | ~Widget(); 42 | 43 | void doit(); 44 | 45 | private: 46 | struct Impl; // use smart pointer 47 | std::unique_ptr pImpl; // and pointer to it 48 | }; 49 | 50 | } 51 | 52 | 53 | namespace modern::pimpl::v02 { 54 | 55 | // {copiable, moveable} = {false, true} 56 | // ruleofzero = false. but needed. 57 | class Widget { 58 | public: 59 | Widget(); 60 | ~Widget(); 61 | 62 | Widget(Widget&& rhs); // move constructor 63 | Widget& operator=(Widget&& rhs); // move assignment 64 | 65 | void doit(); 66 | 67 | private: 68 | struct Impl; // use smart pointer 69 | std::unique_ptr pImpl; // and pointer to it 70 | }; 71 | 72 | } 73 | 74 | 75 | 76 | namespace modern::pimpl::v03 { 77 | 78 | // {copiable, moveable} = {true, true} 79 | // ruleoffive = true. 80 | class Widget { 81 | public: 82 | Widget(); 83 | ~Widget(); 84 | 85 | Widget(const Widget& rhs); // copy constructor 86 | Widget& operator=(const Widget& rhs); // copy assignment 87 | 88 | Widget(Widget&& rhs); // move constructor 89 | Widget& operator=(Widget&& rhs); // move assignment 90 | 91 | void doit(); 92 | 93 | private: 94 | struct Impl; // use smart pointer 95 | std::unique_ptr pImpl; // and pointer to it 96 | }; 97 | 98 | } 99 | 100 | 101 | namespace modern::pimpl::v04 { 102 | 103 | // better use = delete to tell that we dont have a property. for example 104 | // {copiable, moveable} = {false, false} 105 | // ruleoffive = true. 106 | class Widget { 107 | public: 108 | Widget(); 109 | ~Widget(); 110 | 111 | Widget(const Widget& rhs) = delete; 112 | Widget& operator=(const Widget& rhs) = delete; 113 | 114 | Widget(Widget&& rhs) = delete; 115 | Widget& operator=(Widget&& rhs) = delete; 116 | 117 | void doit(); 118 | 119 | private: 120 | struct Impl; // use smart pointer 121 | std::unique_ptr pImpl; // and pointer to it 122 | }; 123 | 124 | } 125 | 126 | namespace modern::pimpl::v05 { 127 | 128 | 129 | // {copiable, moveable} = {true, true} 130 | // ruleoffive = true. 131 | class Widget { 132 | public: 133 | Widget(); 134 | 135 | 136 | void doit(); 137 | 138 | private: 139 | struct Impl; // use smart pointer 140 | std::shared_ptr pImpl; // and pointer to it 141 | }; 142 | 143 | } 144 | 145 | namespace modern::pimpl::singleton { 146 | 147 | // the Scott Meyers' singleton plus others: 148 | // - Item 26: Limiting the number of objects of a class, Scott Meyers, More Effective C++, 1996 149 | // - Item 22: When using the Pimpl Idiom, define special member functions in the implementation file, 150 | // Scott Meyers, Effective Modern C++, ? 151 | // - Modern C++ Design: Generic Programming and Design Patterns Applied, By Andrei Alexandrescu, chapter 6. 152 | // - https://www.modernescpp.com/index.php/creational-patterns-singleton 153 | 154 | 155 | // i explicitely say that it is non-copiable and non-moveable 156 | // but also if i don't say it ... nothing changes in normal usage 157 | #define EXPLICITELY_NON_COPIABLE_MOVABLE 158 | 159 | // it solves: 160 | // - Static Initialization Order Fiasco 161 | // - multithread access because of https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables 162 | // If multiple threads attempt to initialize the same static local variable concurrently, 163 | // the initialization occurs exactly once. 164 | 165 | class theOne 166 | { 167 | theOne(); 168 | struct Impl; 169 | std::unique_ptr pImpl; 170 | ~theOne() = default; // possible because the dtor is used inside getInstance() after Impl definition 171 | public: 172 | static theOne& getInstance(); 173 | 174 | void doit(); 175 | 176 | #if defined(EXPLICITELY_NON_COPIABLE_MOVABLE) 177 | theOne(const theOne&) = delete; // non copyable 178 | theOne& operator=(const theOne&) = delete; // non copyable 179 | theOne(theOne&&) = delete; // non moveable 180 | theOne& operator=(theOne&&) = delete; // non moveable 181 | #endif 182 | 183 | }; 184 | 185 | 186 | } 187 | 188 | #endif // include-guard 189 | 190 | 191 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 192 | 193 | 194 | -------------------------------------------------------------------------------- /exercises/day09/morepimpl/include/widget98.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | // - include guard ---------------------------------------------------------------------------------------------------- 9 | 10 | #ifndef __WIDGET98_H_ 11 | #define __WIDGET98_H_ 12 | 13 | 14 | 15 | namespace cpp98::pimpl { 16 | 17 | class Widget { 18 | public: 19 | Widget(); 20 | ~Widget(); // needed 21 | 22 | void doit(); 23 | 24 | private: 25 | struct Impl; // declare implementation struct 26 | Impl *pImpl; // and pointer to it 27 | }; 28 | }; 29 | 30 | 31 | #endif // include-guard 32 | 33 | 34 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 35 | 36 | 37 | -------------------------------------------------------------------------------- /exercises/day09/morepimpl/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | 10 | #include "widget98.h" 11 | #include "modernpimpl.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | { // widget 98 16 | cpp98::pimpl::Widget widget98; 17 | widget98.doit(); 18 | } 19 | 20 | // { // modern widget v00 21 | // modern::pimpl::v00::Widget widget00; 22 | // widget00.doit(); 23 | // } 24 | 25 | { // modern widget v01: 26 | // - non copiable (unique ptr), 27 | // - non moveable (does not know how to do it because of item 17) 28 | modern::pimpl::v01::Widget widget01; 29 | widget01.doit(); 30 | //modern::pimpl::v01::Widget w01a = widget01; 31 | //modern::pimpl::v01::Widget w01b = std::move(widget01); 32 | } 33 | 34 | { // modern widget v02: 35 | // - non copiable (unique ptr), 36 | // - moveable 37 | modern::pimpl::v02::Widget widget02; 38 | widget02.doit(); 39 | // modern::pimpl::v02::Widget w02a = widget02; 40 | modern::pimpl::v02::Widget w02b = std::move(widget02); 41 | } 42 | 43 | { // modern widget v03: 44 | // - copiable despite the unique_ptr, 45 | // - moveable 46 | modern::pimpl::v03::Widget widget03; 47 | widget03.doit(); 48 | modern::pimpl::v03::Widget w03a = widget03; 49 | modern::pimpl::v03::Widget w03b = std::move(widget03); 50 | w03a = w03a; 51 | } 52 | 53 | { // modern widget v04: 54 | // - non copiable, 55 | // - non moveable 56 | 57 | modern::pimpl::v04::Widget widget04; 58 | widget04.doit(); 59 | // modern::pimpl::v04::Widget w04a = widget04; 60 | // modern::pimpl::v04::Widget w04b = std::move(widget04); 61 | // w04a = w04a; 62 | } 63 | 64 | { // modern widget v05: shared pointer 65 | // - copiable, 66 | // - moveable 67 | 68 | modern::pimpl::v05::Widget widget05; 69 | widget05.doit(); 70 | modern::pimpl::v05::Widget w05a = widget05; 71 | modern::pimpl::v05::Widget w05b = std::move(widget05); 72 | w05a = w05a; 73 | } 74 | 75 | { // modern singleton: 76 | // - non copiable, 77 | // - non moveable 78 | // - non destructable ?? why should I define the ctor? the compiler will do that for me 79 | 80 | modern::pimpl::singleton::theOne &theone = modern::pimpl::singleton::theOne::getInstance(); 81 | theone.doit(); 82 | 83 | modern::pimpl::singleton::theOne &theone1 = modern::pimpl::singleton::theOne::getInstance(); 84 | 85 | // modern::pimpl::singleton::theOne another(theone); 86 | // modern::pimpl::singleton::theOne maybethesame = std::move(theone); 87 | } 88 | 89 | return 1; 90 | } 91 | 92 | 93 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 94 | 95 | 96 | -------------------------------------------------------------------------------- /exercises/day09/morepimpl/src/modernpimpl.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | // - public interface 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "modernpimpl.h" 14 | 15 | 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | // - external dependencies 18 | // -------------------------------------------------------------------------------------------------------------------- 19 | 20 | #include 21 | #include 22 | 23 | // -------------------------------------------------------------------------------------------------------------------- 24 | // - pimpl: private implementation (see scott meyers: item 22 of effective modern c++, item 31 of effective c++ 25 | // -------------------------------------------------------------------------------------------------------------------- 26 | 27 | // - v00 28 | 29 | struct modern::pimpl::v00::Widget::Impl 30 | { 31 | std::string _name {"hello"}; 32 | 33 | void doit() 34 | { 35 | std::cout << _name << std::endl; 36 | } 37 | }; 38 | 39 | 40 | namespace modern::pimpl::v00 { 41 | 42 | Widget::Widget() // allocate data members for 43 | : pImpl(std::make_unique()) // std::unique_ptr 44 | {} // via std::make_unique 45 | 46 | 47 | void Widget::doit() 48 | { 49 | pImpl->doit(); 50 | } 51 | 52 | } 53 | 54 | // - v01 55 | 56 | struct modern::pimpl::v01::Widget::Impl 57 | { 58 | std::string _name {"hello"}; 59 | 60 | void doit() 61 | { 62 | std::cout << _name << std::endl; 63 | } 64 | }; 65 | 66 | 67 | namespace modern::pimpl::v01 { 68 | 69 | Widget::Widget() // allocate data members for 70 | : pImpl(std::make_unique()) // std::unique_ptr 71 | {} // via std::make_unique 72 | 73 | Widget::~Widget() = default; 74 | 75 | void Widget::doit() 76 | { 77 | pImpl->doit(); 78 | } 79 | 80 | } 81 | 82 | // - v02 83 | 84 | struct modern::pimpl::v02::Widget::Impl 85 | { 86 | std::string _name {"hello"}; 87 | 88 | void doit() 89 | { 90 | std::cout << _name << std::endl; 91 | } 92 | }; 93 | 94 | namespace modern::pimpl::v02 { 95 | 96 | Widget::Widget() // allocate data members for 97 | : pImpl(std::make_unique()) // std::unique_ptr 98 | {} // via std::make_unique 99 | 100 | Widget::~Widget() = default; 101 | 102 | Widget::Widget(Widget&& rhs) = default; // definitions 103 | Widget& Widget::operator=(Widget&& rhs) = default; 104 | 105 | void Widget::doit() 106 | { 107 | pImpl->doit(); 108 | } 109 | 110 | } 111 | 112 | // - v03 113 | 114 | 115 | struct modern::pimpl::v03::Widget::Impl 116 | { 117 | std::string _name {"hello"}; 118 | 119 | void doit() 120 | { 121 | std::cout << _name << std::endl; 122 | } 123 | }; 124 | 125 | namespace modern::pimpl::v03 { 126 | 127 | Widget::Widget() // allocate data members for 128 | : pImpl(std::make_unique()) // std::unique_ptr 129 | {} // via std::make_unique 130 | 131 | Widget::~Widget() = default; 132 | 133 | Widget::Widget(Widget&& rhs) = default; // definitions 134 | Widget& Widget::operator=(Widget&& rhs) = default; // ... default is fine 135 | 136 | Widget::Widget(const Widget& rhs) // copy ctor 137 | : pImpl(std::make_unique(*rhs.pImpl)) // cannot be default 138 | {} 139 | 140 | Widget& Widget::operator=(const Widget& rhs) // copy operator= 141 | { // cannot be default 142 | *pImpl = *rhs.pImpl; 143 | return *this; 144 | } 145 | 146 | void Widget::doit() 147 | { 148 | pImpl->doit(); 149 | } 150 | 151 | } 152 | 153 | 154 | // - v04 155 | 156 | 157 | struct modern::pimpl::v04::Widget::Impl 158 | { 159 | std::string _name {"hello"}; 160 | 161 | void doit() 162 | { 163 | std::cout << _name << std::endl; 164 | } 165 | }; 166 | 167 | namespace modern::pimpl::v04 { 168 | 169 | Widget::Widget() // allocate data members for 170 | : pImpl(std::make_unique()) // std::unique_ptr 171 | {} // via std::make_unique 172 | 173 | Widget::~Widget() = default; 174 | 175 | void Widget::doit() 176 | { 177 | pImpl->doit(); 178 | } 179 | 180 | } 181 | 182 | // - v05 183 | 184 | 185 | struct modern::pimpl::v05::Widget::Impl 186 | { 187 | std::string _name {"hello"}; 188 | 189 | void doit() 190 | { 191 | std::cout << _name << std::endl; 192 | } 193 | }; 194 | 195 | namespace modern::pimpl::v05 { 196 | 197 | Widget::Widget() // allocate data members for 198 | : pImpl(std::make_shared()) // std::shared_ptr 199 | {} // via std::make_shared 200 | 201 | 202 | void Widget::doit() 203 | { 204 | pImpl->doit(); 205 | } 206 | 207 | } 208 | 209 | 210 | // singleton 211 | 212 | struct modern::pimpl::singleton::theOne::Impl 213 | { 214 | std::string _name {"theOne"}; 215 | 216 | void doit() 217 | { 218 | std::cout <<_name << std::endl; 219 | } 220 | 221 | // if Impl() allocates or gets HW resources, then you can 222 | // use a init() / deinit() pair accessible to the public API 223 | // it is wise to call a deinit() in the ~Impl() if not deinitted yet. 224 | 225 | }; 226 | 227 | 228 | namespace modern::pimpl::singleton { 229 | 230 | theOne& theOne::getInstance() 231 | { 232 | static theOne instance; 233 | return instance; 234 | } 235 | 236 | // theOne::~theOne() = default; // i can move it in the declation of the class 237 | 238 | theOne::theOne() : pImpl(std::make_unique()) {}; 239 | 240 | void theOne::doit() 241 | { 242 | pImpl->doit(); 243 | } 244 | 245 | } 246 | 247 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 248 | 249 | 250 | -------------------------------------------------------------------------------- /exercises/day09/morepimpl/src/widget98.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2023 iCub Tech - Istituto Italiano di Tecnologia 4 | * Author: Marco Accame 5 | * email: marco.accame@iit.it 6 | */ 7 | 8 | 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | // - public interface 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "widget98.h" 14 | 15 | 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | // - external dependencies 18 | // -------------------------------------------------------------------------------------------------------------------- 19 | 20 | #include 21 | #include 22 | 23 | // -------------------------------------------------------------------------------------------------------------------- 24 | // - pimpl: private implementation (see scott meyers: item 22 of effective modern c++, item 31 of effective c++ 25 | // -------------------------------------------------------------------------------------------------------------------- 26 | 27 | 28 | 29 | struct cpp98::pimpl::Widget::Impl 30 | { 31 | std::string _name;; 32 | 33 | Impl() 34 | { 35 | _name = "hello"; 36 | } 37 | 38 | void doit() 39 | { 40 | std::cout << _name << std::endl; 41 | } 42 | }; 43 | 44 | 45 | namespace cpp98::pimpl { 46 | 47 | Widget::Widget() // allocate data members for 48 | : pImpl(new Impl) // this Widget object 49 | {} 50 | 51 | Widget::~Widget() // destroy data members for 52 | { delete pImpl; } // this object 53 | 54 | void Widget::doit() 55 | { 56 | pImpl->doit(); 57 | } 58 | 59 | } 60 | 61 | 62 | 63 | // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- 64 | 65 | 66 | -------------------------------------------------------------------------------- /exercises/day09/moveSemantic/exerciseMoveSem.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) Fondazione Istituto Italiano di Tecnologia (IIT) 2 | // All Rights Reserved. 3 | 4 | //author Valentina Gaggero 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | static int numCopiesMade = 0; 16 | static int numMovedObj=0; 17 | 18 | 19 | class BigObject 20 | { 21 | enum { DataSize = 100000 }; 22 | public: 23 | 24 | BigObject() 25 | : data{new int[DataSize]} 26 | { 27 | std::cout << "BigObject constructor" << std::endl; 28 | std::generate(data, data + DataSize, rand); 29 | } 30 | 31 | ~BigObject() 32 | { 33 | std::cout << "BigObject deconstructor" << std::endl;; 34 | if(data!=nullptr) 35 | delete[] data; 36 | 37 | } 38 | 39 | BigObject(const BigObject &other) 40 | : data{new int[DataSize]} 41 | { 42 | std::cout << "BigObject copy constructor" << std::endl; 43 | numCopiesMade++; 44 | std::copy(other.data, other.data + DataSize, data); 45 | } 46 | 47 | 48 | 49 | BigObject& operator=(const BigObject &other) 50 | { 51 | std::cout << "BigObject copy-assignment operator" << std::endl; 52 | // copy+swap idiom, exception safe 53 | BigObject copy(other); 54 | using std::swap; 55 | swap(copy.data, data); 56 | return *this; 57 | } 58 | 59 | //insert here the move constructor 60 | 61 | //insert here the move-assignment object 62 | 63 | 64 | void setNewValueAtIndex(int index, int newvalue) 65 | { 66 | if(index myvec; 91 | 92 | }; 93 | 94 | BigObject createObject() 95 | { 96 | BigObject myobj; 97 | myobj.setNewValueAtIndex(1, 100); 98 | return myobj; 99 | } 100 | 101 | 102 | 103 | int main() 104 | { 105 | BigObject obj1 = createObject(); 106 | //1) check if the RVO optimization has been applied. 107 | if(numMovedObj == 0) 108 | { 109 | std::cout << "RVO optimization has been applied!!!!"<< std::endl<< std::endl; 110 | } 111 | else 112 | { 113 | std::cout << "NO RVO optimization has been applied!!!!"<< std::endl<< std::endl; 114 | } 115 | 116 | ContainerOfObject container; 117 | std::cout << "INIT: number of copies = " << numCopiesMade << ". Number of moves = "<< numMovedObj << ". The container has " << container.size() << " elements." << std::endl<< std::endl; 118 | 119 | container.addObject(obj1); 120 | std::cout << "FIRST: number of copies = " << numCopiesMade << ". Number of moves = "<< numMovedObj << ". The container has " << container.size() << " elements." << std::endl<< std::endl; 121 | 122 | container.addObject(std::move(obj1)); 123 | std::cout << "SECOND: number of copies = " << numCopiesMade << ". Number of moves = "<< numMovedObj << ". The container has " << container.size() << " elements." << std::endl<< std::endl; 124 | 125 | obj1.setNewValueAtIndex(2, 33); 126 | 127 | BigObject obj2= BigObject(); 128 | 129 | #warning question 6: put here the code 130 | //QUESTION 6: create obj3 from a temporary BigObject. Here are possible 2 solutions. Can you find both?? 131 | 132 | 133 | #warning question 7: put here the code 134 | //QUESTION 7: add 10 BigObject to the container in order to avoid copies. 135 | 136 | } 137 | -------------------------------------------------------------------------------- /exercises/day09/moveSemantic/instructionMoveSemanticsExercise.md: -------------------------------------------------------------------------------- 1 | # Move semantics exercise 2 | 3 | In the provided code `exerciseMoveSem.cpp` you can find the definition of a copiable class. 4 | 5 | 1. Make BigObject a movable class also 6 | 2. Overload ContainerOfObject::addObject function for temporaries. 7 | 3. compile and run the code. ` g++ -std=c++11 exerciseMoveSem.cpp -o exeMoveSem` `./exeMoveSem` 8 | 4. check if RVO has been applied. What is RVO?? 9 | 5. the program should crash! Why? fix it please! 10 | 6. create obj3 and obj4 from a temporary BigObject. Here are possible 2 solutions? Can you find both?? see `#warning question 6:` 11 | 7. add 10 BigObject to the container in order to avoid copies. `#warning question 7:` -------------------------------------------------------------------------------- /exercises/shared/CMakeOptions.cmake: -------------------------------------------------------------------------------- 1 | 2 | 3 | # unless you run: 4 | # > ccmake .. -DCMAKE_BUILD_TYPE=Debug/Release/... 5 | # the default compilation mode will be Debug 6 | if(NOT CMAKE_BUILD_TYPE) 7 | set(CMAKE_BUILD_TYPE "Debug" CACHE STRING 8 | "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." 9 | FORCE) 10 | endif() 11 | 12 | # unless you run: 13 | # > ccmake .. -DCMAKE_CXX_STANDARD=11 14 | # with values taken from https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#prop_gbl:CMAKE_CXX_KNOWN_FEATURES 15 | # we just use 11 16 | if(NOT CMAKE_CXX_STANDARD) 17 | set(CMAKE_CXX_STANDARD "11" CACHE STRING 18 | "Choose the c++, options are: 98 11 14 17 20." 19 | FORCE) 20 | endif() 21 | 22 | 23 | # https://cmake.org/cmake/help/latest/manual/cmake-compile-features.7.html#requiring-language-standards 24 | # at least ... but maybe more 25 | # target_compile_features(test_library PRIVATE ${CXXSTD}) 26 | # so i will use: 27 | #set(CMAKE_CXX_STANDARD 11) 28 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 29 | set(CMAKE_CXX_EXTENSIONS OFF) 30 | -------------------------------------------------------------------------------- /program/2022-23/Modern-C++-2022-23.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/program/2022-23/Modern-C++-2022-23.pdf -------------------------------------------------------------------------------- /program/2023-24/Modern-C++-2023-24.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/program/2023-24/Modern-C++-2023-24.pdf -------------------------------------------------------------------------------- /program/2024-25/modern-c++-2024-25.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/program/2024-25/modern-c++-2024-25.pdf -------------------------------------------------------------------------------- /slides/day01/modern-c++-01-a-presentation-202x.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day01/modern-c++-01-a-presentation-202x.pdf -------------------------------------------------------------------------------- /slides/day01/modern-c++-01-b-toolchain-202x.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day01/modern-c++-01-b-toolchain-202x.pdf -------------------------------------------------------------------------------- /slides/day02/modern-c++-02-prerequisites.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day02/modern-c++-02-prerequisites.pdf -------------------------------------------------------------------------------- /slides/day03-04/modern-c++-03-04-thebasics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day03-04/modern-c++-03-04-thebasics.pdf -------------------------------------------------------------------------------- /slides/day05/Modern_C++_Programming_Course_–algo_containers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day05/Modern_C++_Programming_Course_–algo_containers.pdf -------------------------------------------------------------------------------- /slides/day05/Modern_C++_Programming_Course_–lambda.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day05/Modern_C++_Programming_Course_–lambda.pdf -------------------------------------------------------------------------------- /slides/day06/Modern_C++_Programming_Course_–smart_pointers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day06/Modern_C++_Programming_Course_–smart_pointers.pdf -------------------------------------------------------------------------------- /slides/day06/moveSemantics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day06/moveSemantics.pdf -------------------------------------------------------------------------------- /slides/day07/multithreading.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day07/multithreading.pdf -------------------------------------------------------------------------------- /slides/day08/Modern_C++_Programming_Course_– C++20.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icub-training/material_modern-cpp/9a931bf61da9a66a2a756f099791ca5fce2215b9/slides/day08/Modern_C++_Programming_Course_– C++20.pdf -------------------------------------------------------------------------------- /slides/day09/README.md: -------------------------------------------------------------------------------- 1 | The lesson is `Hands on Code`. 2 | 3 | We shall discuss some code proposed by the students or the exercises on this repository under [day09](../../exercises/day09). -------------------------------------------------------------------------------- /slides/day10/README.md: -------------------------------------------------------------------------------- 1 | The lesson is `Correction of the assignment`. 2 | 3 | We shall discuss a possible solution for the assignment plus different solutions proposed by the students. --------------------------------------------------------------------------------