1
0
mirror of https://github.com/kamranahmedse/developer-roadmap.git synced 2025-08-21 08:31:50 +02:00

Migrate C++ roadmap

This commit is contained in:
Kamran Ahmed
2025-03-21 15:05:33 +00:00
parent ff5609b722
commit b32adbe3c5
157 changed files with 5639 additions and 17558 deletions

View File

@@ -11,6 +11,14 @@ import react from '@astrojs/react';
// https://astro.build/config
export default defineConfig({
site: 'https://roadmap.sh/',
vite: {
server: {
allowedHosts: [
'roadmap.sh',
'port3k.kamranahmed.info',
],
},
},
markdown: {
shikiConfig: {
theme: 'dracula',

View File

@@ -1,47 +0,0 @@
# Raw Pointers and `new` and `delete` operators
Raw pointers in C++ are low-level constructs that directly hold a memory address. They can be used for manually allocating memory, creating dynamic arrays, and passing values efficiently, among other things.
## `new` Operator
The `new` operator is used to allocate memory on the heap. The memory allocated using `new` remains available until you explicitly deallocate it using the corresponding `delete` operator.
Here's an example of using the `new` operator:
```cpp
int* ptr = new int; // Dynamically allocates an int on the heap
*ptr = 42; // Assigns the value 42 to the allocated int
```
## `delete` Operator
The `delete` operator is used to deallocate memory that has been allocated using `new`. After memory is deallocated, it's available to be reallocated for other purposes. Failing to properly deallocate memory can lead to memory leaks.
Here's an example of using the `delete` operator:
```cpp
int* ptr = new int; // Dynamically allocates an int on the heap
*ptr = 42; // Assigns the value 42 to the allocated int
delete ptr; // Deallocates the memory assigned to ptr
```
## `new[]` and `delete[]` Operators
The `new[]` and `delete[]` operators are used for allocating and deallocating memory for an array of objects. The syntax for `new[]` and `delete[]` is very similar to that of `new` and `delete`.
Here's an example of using the `new[]` and `delete[]` operators:
```cpp
int n = 10;
int* arr = new int[n]; // Dynamically allocates an array of 10 integers on the heap
// Set some values in the array
for (int i = 0; i < n; i++) {
arr[i] = i;
}
delete[] arr; // Deallocates the memory assigned to the array
```
In summary, raw pointers, and `new` and `delete` operators allow manual memory management in C++, providing control over allocation and deallocation. Make sure to always deallocate memory allocated with `new` or `new[]`, to avoid memory leaks in your programs.

View File

@@ -1,28 +0,0 @@
# Memory Leakage
Memory leakage occurs when a program allocates memory in the heap but does not release the memory back to the operating system when it is no longer needed. Over time, this leads to exhaustion of available memory, resulting in low system performance or crashes.
In C++, when you use raw pointers, you need to manage the memory allocation and deallocation manually. In many cases, you will use the `new` keyword to allocate memory for an object in the heap and use `delete` keyword to deallocate that memory when it's no longer needed. Forgetting to do this can cause memory leaks.
Here's an example:
```cpp
void create_memory_leak() {
int* ptr = new int[100]; // Allocating memory in the heap for an array of integers
// Some code...
// Code to deallocate the memory is missing: delete[] ptr;
} // ptr goes out of scope, memory block allocated is not deallocated, causing a memory leak.
```
To avoid memory leaks, you should always ensure that memory is deallocated before a pointer goes out of scope or is reassigned. Some ways to achieve this include using the C++ smart pointers (`std::unique_ptr`, `std::shared_ptr`), RAII (Resource Acquisition Is Initialization) techniques, and containers from the C++ standard library that manage memory allocation internally (e.g., `std::vector`, `std::string`).
For example, this code will not have a memory leak:
```cpp
#include <memory>
void no_memory_leak() {
std::shared_ptr<int[]> ptr = std::make_shared<int[]>(100); // Allocating memory in the heap for an array of integers using shared_ptr
// Some code...
} // shared_ptr goes out of scope and it will automatically deallocate the memory block assigned to it.
```

View File

@@ -1,52 +0,0 @@
# Weak Pointer
A `weak_ptr` is a type of smart pointer in C++ that adds a level of indirection and safety to a raw pointer. It is mainly used to break reference cycles in cases where two objects have shared pointers to each other, or when you need a non-owning reference to an object that is managed by a `shared_ptr`.
A `weak_ptr` does not increase the *ownership* reference count of the object it points to, which is a key difference between `weak_ptr` and `shared_ptr`. The control block associated with the object maintains two counts: one for the number of `shared_ptr`s (ownership count) and another for the number of `weak_ptr`s (weak count). The existence of `weak_ptr`s does not prevent the object from being deleted; the object is destroyed once the last `shared_ptr` that owns it is destroyed or reset, even if `weak_ptr`s are still referencing the object. However, the control block itself is not deallocated until both the ownership count reaches zero and the weak count also reaches zero, allowing `weak_ptr`s to safely detect whether the object has already been deleted.
To use a `weak_ptr`, you must convert it to a `shared_ptr` using the `lock()` function, which tries to create a new `shared_ptr` that shares ownership of the object. If successful, the object's reference count is increased and you can use the returned `shared_ptr` to safely access the object.
Here's an example of using `weak_ptr`:
```cpp
#include <iostream>
#include <memory>
class MyClass {
public:
void DoSomething() {
std::cout << "Doing something...\n";
}
};
int main() {
std::weak_ptr<MyClass> weak;
{
std::shared_ptr<MyClass> shared = std::make_shared<MyClass>();
weak = shared;
if (auto sharedFromWeak = weak.lock()) {
sharedFromWeak->DoSomething(); // Safely use the object
std::cout << "Shared uses count: " << sharedFromWeak.use_count() << '\n'; // 2
}
}
// shared goes out of scope and the MyClass object is destroyed
if (auto sharedFromWeak = weak.lock()) {
// This block will not be executed because the object is destroyed
}
else {
std::cout << "Object has been destroyed\n";
}
return 0;
}
```
In this example, we create a `shared_ptr` named `shared` that manages a `MyClass` object. By assigning it to a `weak_ptr` named `weak`, we store a non-owning reference to the object. Inside the inner scope, we create a new `shared_ptr` named `sharedFromWeak` using `weak.lock()` to safely use the object. After the inner scope, the `MyClass` object is destroyed since `shared` goes out of scope, and any further attempt to create a `shared_ptr` from `weak` will fail as the object is already destroyed.
Learn more from the following resources:
- [@article@CPP Reference](https://en.cppreference.com/w/cpp/memory/weak_ptr)

View File

@@ -1,50 +0,0 @@
# Shared Pointer
A `shared_ptr` is a type of smart pointer in C++ that allows multiple pointers to share ownership of a dynamically allocated object. The object will be automatically deallocated only when the last `shared_ptr` that points to it is destroyed.
When using a `shared_ptr`, the reference counter is automatically incremented every time a new pointer is created, and decremented when each pointer goes out of scope. Once the reference counter reaches zero, the system will clean up the memory.
## Code Example
Here's an example of how to use `shared_ptr`:
```cpp
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "Constructor is called." << std::endl; }
~MyClass() { std::cout << "Destructor is called." << std::endl; }
};
int main() {
// create a shared pointer to manage the MyClass object
std::shared_ptr<MyClass> ptr1(new MyClass());
{
// create another shared pointer and initialize it with the previously created pointer
std::shared_ptr<MyClass> ptr2 = ptr1;
std::cout << "Inside the inner scope." << std::endl;
// both pointers share the same object, and the reference counter has been increased to 2
}
std::cout << "Outside the inner scope." << std::endl;
// leaving the inner scope will destroy ptr2, and the reference counter is decremented to 1
// the main function returns, ptr1 goes out of scope, and the reference counter becomes 0
// this causes the MyClass object to be deleted and the destructor is called
}
```
Output:
```
Constructor is called.
Inside the inner scope.
Outside the inner scope.
Destructor is called.
```
In this example, `ptr1` and `ptr2` share ownership of the same object. The object is only destroyed when both pointers go out of scope and the reference counter becomes zero.

View File

@@ -1,66 +0,0 @@
# Unique Pointer (`unique_ptr`)
`std::unique_ptr` is a smart pointer provided by the C++ Standard Library. It is a template class that is used for managing single objects or arrays.
`unique_ptr` works on the concept of *exclusive ownership* - meaning only one `unique_ptr` is allowed to own an object at a time. This ownership can be transferred or moved, but it cannot be shared or copied.
This concept helps to prevent issues like dangling pointers, reduce memory leaks, and eliminates the need for manual memory management. When the `unique_ptr` goes out of scope, it automatically deletes the object it owns.
Let's take a look at some basic examples of using `unique_ptr`:
## Creating a unique_ptr
```cpp
#include <iostream>
#include <memory>
int main() {
std::unique_ptr<int> p1(new int(5)); // Initialize with pointer to a new integer
std::unique_ptr<int> p2 = std::make_unique<int>(10); // Preferred method (C++14 onwards)
std::cout << *p1 << ", " << *p2 << std::endl;
return 0;
}
```
## Transferring Ownership
```cpp
#include <iostream>
#include <memory>
int main() {
std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = std::move(p1); // Ownership is transferred from p1 to p2
if (p1) {
std::cout << "p1 owns the object" << std::endl;
} else if (p2) {
std::cout << "p2 owns the object" << std::endl;
}
return 0;
}
```
## Using unique_ptr with Custom Deleters
```cpp
#include <iostream>
#include <memory>
struct MyDeleter {
void operator()(int* ptr) {
std::cout << "Custom Deleter: Deleting pointer" << std::endl;
delete ptr;
}
};
int main() {
std::unique_ptr<int, MyDeleter> p1(new int(5), MyDeleter());
return 0; // Custom Deleter will be called when p1 goes out of scope
}
```
Remember that since unique_ptr has exclusive ownership, you cannot use it when you need shared access to an object. For such cases, you can use `std::shared_ptr`.

View File

@@ -1,45 +0,0 @@
# Function Overloading
Function overloading is a type of static polymorphism in C++ where multiple functions with the same name but different sets of parameters are defined in the same scope. This allows you to use the same function name for multiple tasks by providing different arguments while calling the function. The appropriate function to call is determined during compile-time based on the number and types of the arguments passed.
To overload a function, simply define another function with the same name but a different set of parameters. The compiler will automatically choose the correct function to call based on the provided arguments.
## Examples
Here's an example illustrating function overloading:
```cpp
#include <iostream>
void print(int num) {
std::cout << "Printing int: " << num << std::endl;
}
void print(double num) {
std::cout << "Printing double: " << num << std::endl;
}
void print(char const *str) {
std::cout << "Printing string: " << str << std::endl;
}
int main() {
print(5);
print(3.14);
print("Hello, world!");
return 0;
}
```
In this example, three overloaded functions named `print` are defined. They each take a different type of argument: `int`, `double`, and `char const *`. When calling `print()` with different arguments like `5`, `3.14`, or `"Hello, world!"`, the appropriate function is chosen based on the type of the provided argument.
The output of this program would be:
```
Printing int: 5
Printing double: 3.14
Printing string: Hello, world!
```
Keep in mind that the number of parameters and their types should be different for two functions to be overloaded.

View File

@@ -1,65 +0,0 @@
# Virtual Methods
Virtual methods are a key aspect of dynamic polymorphism in C++. They allow subclass methods to override the methods of their base class, so the appropriate method is called depending on the actual type of an object at runtime.
To declare a method as virtual, simply use the `virtual` keyword in the method's declaration in the base class. This tells the compiler that the method should be treated as a virtual method, allowing it to be overridden by derived classes.
## Code Example
Here's an example demonstrating virtual methods:
```cpp
#include <iostream>
// Base class
class Shape {
public:
virtual double area() const {
return 0;
}
};
// Derived class
class Circle : public Shape {
public:
Circle(double r) : radius(r) {}
// Override the base class method
double area() const override {
return 3.14 * radius * radius;
}
private:
double radius;
};
// Derived class
class Rectangle : public Shape {
public:
Rectangle(double w, double h) : width(w), height(h) {}
// Override the base class method
double area() const override {
return width * height;
}
private:
double width;
double height;
};
int main() {
Circle c(5);
Rectangle r(4, 6);
Shape* shape = &c;
std::cout << "Circle's area: " << shape->area() << std::endl;
shape = &r;
std::cout << "Rectangle's area: " << shape->area() << std::endl;
return 0;
}
```
In this example, we define a base class `Shape` that has a virtual method `area`. This method is then overridden by the derived classes `Circle` and `Rectangle`. By using a virtual method and a base class pointer to the derived objects, we can invoke the appropriate `area` method based on the actual object type at runtime.

View File

@@ -1,51 +0,0 @@
# Virtual Tables
Virtual Tables (or Vtable) are a mechanism used by C++ compilers to support dynamic polymorphism. In dynamic polymorphism, the appropriate function is called at runtime, depending on the actual object type.
When a class contains a virtual function, the compiler creates a virtual table for that class. This table contains function pointers to the virtual functions defined in the class. Each object of that class has a pointer to its virtual table (_vptr_, virtual pointer), which is automatically initialized by the compiler during object construction.
## Example
Let's consider the following example:
```cpp
class Base {
public:
virtual void function1() {
std::cout << "Base::function1" << std::endl;
}
virtual void function2() {
std::cout << "Base::function2" << std::endl;
}
};
class Derived : public Base {
public:
void function1() override {
std::cout << "Derived::function1" << std::endl;
}
void function3() {
std::cout << "Derived::function3" << std::endl;
}
};
int main() {
Base* obj = new Derived(); // create a Derived object and assign a pointer of type Base*
obj->function1(); // calls Derived::function1, due to dynamic polymorphism
obj->function2(); // calls Base::function2
delete obj;
return 0;
}
```
In this example, when a `Derived` object is created, the compiler generates a Vtable for `Derived` class, containing pointers to its virtual functions:
- `Derived::function1` (overridden from `Base`)
- `Base::function2` (inherits from Base)
The `_vptr_` pointer in the `Derived` object points to this Vtable. When the `function1` is called on the `Base` pointer pointing to the `Derived` object, the function pointer in the Vtable is used to call the correct function (in this case, `Derived::function1`). Similarly, the call to `function2` calls `Base::function2`, since it's the function pointer stored in the Vtable for `Derived` class.
Note that `function3` is not part of the Vtable, as it is not a virtual function.

View File

@@ -1,75 +0,0 @@
# Google Test (gtest)
Google Test, also known as gtest or googletest, is a C++ testing framework developed by Google. It provides a user-friendly API for writing test cases and is designed for use in a range of applications, from simple unit tests to complex system-level tests.
## Getting Started with Google Test
To use Google Test in your project, follow these steps:
- Download the source code from the [GoogleTest GitHub repository](https://github.com/google/googletest).
- Build and install Google Test on your system. Instructions for various platforms can be found in the [README](https://github.com/google/googletest/blob/main/googletest/README.md) file.
- Include the necessary headers and link against the Google Test library in your project.
## Writing a Test with Google Test
Here's an example of how to write a simple test using Google Test:
- **Include the necessary headers**
```cpp
#include "gtest/gtest.h"
```
- **Write the functions you want to test**
Suppose we have a simple function to test:
```cpp
int add(int a, int b) {
return a + b;
}
```
- **Write the test cases**
To create a test case, use the `TEST()` macro, which takes two arguments: the test suite name and the test case name.
```cpp
// Test the 'add' function.
TEST(AdditionTest, PositiveNumbers) {
EXPECT_EQ(3, add(1, 2));
EXPECT_EQ(5, add(2, 3));
}
TEST(AdditionTest, NegativeNumbers) {
EXPECT_EQ(-3, add(-1, -2));
EXPECT_EQ(-5, add(-2, -3));
}
```
- **Write a `main()` function**
In order to run the tests, include a `main()` function that initializes Google Test and runs the tests.
```cpp
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
```
- **Compile and run the tests**
Compile your test program with the Google Test library and run the test executable.
## More Features
Google Test offers a wide range of features to make testing easier, such as:
- **Test Fixtures**: Test fixtures allow you to reuse the same set of objects for multiple tests. You can define a test fixture by creating a class that inherits from `::testing::Test` and writing setup and teardown methods.
- **Assertions**: Google Test provides a variety of assertion macros to help you verify your code's behavior. Some common ones include `EXPECT_EQ`, `EXPECT_TRUE`, `EXPECT_FALSE`, `ASSERT_EQ`, `ASSERT_TRUE`, and `ASSERT_FALSE`.
- **Parameterized Tests**: Google Test supports parameterized tests, allowing you to run the same test with different inputs easily.
- **Death Tests**: Google Test allows you to write tests that verify if your code terminates correctly or with the expected error message.
For more information about Google Test and its features, refer to the [official documentation](https://github.com/google/googletest/blob/main/docs/primer.md).

View File

@@ -1,37 +0,0 @@
# Qt Framework
Qt is an open-source, cross-platform framework for creating high-performance applications with interactive user interfaces. It is mainly used for developing GUI applications but can also be used for creating non-GUI applications like console tools and servers.
Qt provides a wide range of C++ libraries and seamless integration with popular IDEs, making it easier for developers to create feature-rich applications. It offers a comprehensive development environment, including tools for designing, coding, debugging, and profiling applications.
## Key Features
- **Cross-platform**: Qt can create applications that run on different platforms (e.g., Windows, macOS, Linux, Android, iOS) without any platform-specific code.
- **Modular Libraries**: Qt consists of several modular libraries, including QtCore (core non-GUI functionality), QtGui (GUI-related classes), QtWidgets (GUI widgets), and QtNetwork (networking support).
- **Signals and Slots**: Qt provides a unique mechanism to handle events called "signals and slots", which allows safe and flexible inter-object communication.
- **OpenGL Integration**: Qt supports rendering 2D and 3D graphics using OpenGL, making it suitable for game development and other graphical applications.
## Code Example
Here's a simple example of a "Hello, World!" application using Qt:
```cpp
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label("Hello, World!");
label.show();
return app.exec();
}
```
In this example, we include the necessary header files, create QApplication and QLabel objects, display the label with a "Hello, World!" message, and execute the application.
To compile and run this example, you need to install the Qt library and configure your development environment to use it.
For more information and tutorials about Qt, you can refer to the [official Qt documentation](https://doc.qt.io/qt-5/index.html).

View File

@@ -1,96 +0,0 @@
# Catch2
Catch2 is a modern, C++-native, test framework for unit tests, TDD, and BDD. It is a single-header library, meaning you only need to include one header file (`catch.hpp`) to start using it. Catch2 is fast, easy to use, and supports various test styles.
## Features
- **Single-header:** Just `#include "catch.hpp"` and start writing tests.
- **Test cases:** Declare test cases using the `TEST_CASE` macro.
- **Sections:** Divide test cases into sections using `SECTION` macro.
- **BDD:** Behavior-Driven Development style supported with `SCENARIO`, `GIVEN`, `WHEN`, `THEN`.
- **Matchers:** Use rich built-in matchers for more expressive assertions.
- **Test discovery:** Catch2 automatically discovers your test cases and sections.
## Code examples
## Basic test case
```cpp
#define CATCH_CONFIG_MAIN // Tells Catch to provide a main() function
#include "catch.hpp"
int add(int a, int b) {
return a + b;
}
TEST_CASE("Addition") {
REQUIRE(add(2, 3) == 5);
}
```
## Sections
```cpp
TEST_CASE("Sections example") {
int a = 1;
SECTION("incrementing a") {
a++;
REQUIRE(a == 2);
}
SECTION("decrementing a") {
a--;
REQUIRE(a == 0);
}
}
```
## BDD style
```cpp
SCENARIO("vector can be sized and resized", "[vector]") {
std::vector<int> v;
GIVEN("A vector with some items") {
v.push_back(1);
v.push_back(2);
v.push_back(3);
REQUIRE(v.size() == 3);
WHEN("the size is increased") {
v.resize(5);
THEN("the size and contents change") {
REQUIRE(v.size() == 5);
REQUIRE(v[3] == 0);
REQUIRE(v[4] == 0);
}
}
WHEN("the size is reduced") {
v.resize(2);
THEN("the size changes but not the contents") {
REQUIRE(v.size() == 2);
REQUIRE(v[0] == 1);
REQUIRE(v[1] == 2);
}
}
}
}
```
## Matchers
```cpp
TEST_CASE("Matchers example") {
std::string str = "Hello, world!";
CHECK_THAT(str, Catch::Matchers::StartsWith("Hello"));
CHECK_THAT(str, Catch::Matchers::EndsWith("world!"));
CHECK_THAT(str, Catch::Matchers::Contains("lo, wo"));
}
```
For more information, visit the [Catch2 GitHub repository](https://github.com/catchorg/Catch2).

View File

@@ -1,69 +0,0 @@
# Orbit Profiler
Orbit Profiler is a performance profiler for C++ applications. It is designed to provide developers with real-time feedback on their application's performance and help them identify performance bottlenecks. It supports both Windows and Linux platforms, profiling both local and remote processes.
**Major features of Orbit Profiler:**
- Sampling-based profiling
- Instrumentation-based profiling
- Callstacks collection
- Frame-based measurements using scopes macros
## Usage
- **Include OrbitProfiler.h**: First, you need to include the `OrbitProfiler.h` header file in your project:
```cpp
#include "OrbitProfiler.h"
```
- **Starting and Stopping the profiler**: Use `ORBET_START` and `ORBIT_STOP` to start and stop the profiler.
```cpp
ORBIT_START();
// Your application code here
ORBIT_STOP();
```
- **Instrumenting scopes**: Use the `ORBET_SCOPE` macro to annotate the scope of the function you want to measure:
```cpp
void ExampleFunction() {
ORBIT_SCOPE("Example Function");
// Function content here
}
```
- **Visualizing the captured data**: Orbit Profiler provides a **Session View** that displays the captured data and allows you to navigate through the timeline, analyze data, and identify performance bottlenecks.
## Example
For demonstration purposes, consider the following example of a simple C++ application:
```cpp
#include "OrbitProfiler.h"
void FunctionA() {
ORBIT_SCOPE("Function A");
// Function A code here
}
void FunctionB() {
ORBIT_SCOPE("Function B");
// Function B code here
}
int main() {
ORBIT_START();
FunctionA();
FunctionB();
ORBIT_STOP();
return 0;
}
```
By using Orbit Profiler, we are able to pinpoint performance issues in FunctionA and FunctionB and optimize our application accordingly.
For more information, refer to the [official Orbit Profiler GitHub repository](https://github.com/google/orbit).

View File

@@ -1,71 +0,0 @@
# PyTorch C++
PyTorch C++ is the C++ API (Application Programming Interface) for PyTorch. It is also known as LibTorch, which is a library that provides almost all the functionality of PyTorch accessible through C++ language. The main goal of providing a C++ API is to enable high-performance integration with other deep learning platforms and enable seamless operation in enterprise and production-level systems.
## Installation
To use the PyTorch C++ API, you need to install the LibTorch distribution. Follow the instructions on the [official PyTorch C++ API page](https://pytorch.org/cppdocs/installing.html) to install the library based on your platform and requirements.
## Example: Tensors
```cpp
#include <iostream>
#include <torch/torch.h>
int main() {
// Create a 3x3 matrix with zeros.
torch::Tensor a = torch::zeros({3, 3});
std::cout << a << std::endl;
// Create a 2x2 matrix with ones and convert to float.
torch::Tensor b = torch::ones({2, 2}).to(torch::kFloat);
std::cout << b << std::endl;
// Create a random tensor size 2x2 and specify its type.
torch::Tensor c = torch::randint(0, 10, {2, 2}, torch::kInt);
std::cout << c << std::endl;
// Perform element-wise addition.
auto sum = b + c.to(torch::kFloat);
std::cout << sum << std::endl;
}
```
## Example: Creating a Custom Module
```cpp
#include <iostream>
#include <torch/torch.h>
// Define a custom module.
struct Net : torch::nn::Module {
Net() {
fc1 = register_module("fc1", torch::nn::Linear(784, 64));
fc2 = register_module("fc2", torch::nn::Linear(64, 10));
}
torch::Tensor forward(torch::Tensor x) {
x = x.view({-1, 784});
x = torch::relu(fc1->forward(x));
x = torch::log_softmax(fc2->forward(x), 1);
return x;
}
torch::nn::Linear fc1{nullptr};
torch::nn::Linear fc2{nullptr};
};
int main() {
// Create an instance of the custom module.
Net net;
// Use the custom module.
torch::Tensor input = torch::randn({2, 1, 28, 28});
torch::Tensor output = net.forward(input);
std::cout << output << std::endl;
return 0;
}
```
In these examples, we demonstrated how to use various tensor operations and how to create a custom neural network module with PyTorch C++. For more detailed information and tutorials, visit the [official PyTorch C++ documentation](https://pytorch.org/cppdocs/).

View File

@@ -1 +0,0 @@
# Frameworks

View File

@@ -1 +0,0 @@
#

View File

@@ -1,45 +0,0 @@
# Boost C++ Libraries
Boost is a collection of high-quality and widely-used C++ libraries that are designed to help developers write efficient and portable code. They are modular and can be included in your projects as needed. Boost libraries provide various functionalities, including support for parallelism, multithreading, memory management, string manipulation, and advanced data structures.
## Notable Components
Here's a list of some popular Boost libraries:
- **Boost.Asio**: Provides network and low-level I/O services.
- **Boost.Bimap**: A bidirectional map data structure.
- **Boost.Filesystem**: Offers portable file system operations.
- **Boost.Graph**: Implements various graph algorithms and data structures.
- **Boost.Multithreading**: Offers multithreading, synchronization, and thread management tools.
## Usage
- First, download and install the Boost libraries according to the [documentation](https://www.boost.org/doc/libs/1_76_0/more/getting_started/index.html).
- After installation, include necessary headers in your C++ code and start using Boost facilities.
Here's an example using `boost::filesystem` (*NOTE: Boost.Filesystem is now part of the C++17 standard library*):
```cpp
#include <iostream>
#include <boost/filesystem.hpp>
int main() {
boost::filesystem::path path("directory_path");
if (boost::filesystem::exists(path)) {
std::cout << "Path: " << path << " exists!" << std::endl;
if (boost::filesystem::is_directory(path)) {
std::cout << "Path: " << path << " is a directory." << std::endl;
} else if (boost::filesystem::is_regular_file(path)) {
std::cout << "Path: " << path << " is a regular file." << std::endl;
}
} else {
std::cout << "Path: " << path << " does not exist!" << std::endl;
}
return 0;
}
```
For a more detailed guide, refer to the [official Boost documentation](https://www.boost.org/doc/libs/).

View File

@@ -1,57 +0,0 @@
# OpenCV
**OpenCV (Open Source Computer Vision Library)** is an open-source computer vision and machine learning software library. It was built to provide a common infrastructure for computer vision applications and to accelerate the use of machine perception in commercial products. OpenCV contains over 2,500 optimized algorithms for real-time computer vision and is actively used by a large community of programmers, researchers, and industries worldwide.
The library has interfaces for C++, Python, Java, and MATLAB/Octave, and is widely used in various computer vision fields, such as:
- 2D and 3D image processing
- Facial recognition and face detection
- Object detection and recognition
- Machine learning
Here's a simple example using OpenCV in C++ to read and display an image:
**Prerequisite**: Install OpenCV for C++ on your system (e.g., by following the [official installation guide](https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html)).
```cpp
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
int main(int argc, char** argv) {
if (argc != 2) {
std::cout << "Usage: display_image ImageToLoadAndDisplay" << std::endl;
return -1;
}
cv::Mat image;
image = cv::imread(argv[1], cv::IMREAD_COLOR);
if (!image.data) {
std::cout << "Could not open or find the image" << std::endl;
return -1;
}
cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE);
cv::imshow("Display window", image);
cv::waitKey(0);
return 0;
}
```
This example reads an image from the given input path (`argv[1]`) and displays it in a window. The `cv::imread()` function is used to read the image, and the `cv::imshow()` function displays it in the created window.
Remember to compile the code, linking the necessary libraries:
```
g++ -o display_image display_image.cpp `pkg-config --cflags --libs opencv4`
```
And run the executable with an image path as an argument:
```
./display_image path/to/image.jpg
```
For more advanced examples and detailed documentation on how to use OpenCV, please visit the [official OpenCV documentation](https://docs.opencv.org/master/).

View File

@@ -1,76 +0,0 @@
# Poco
Poco (also known as POCO C++ Libraries) is a collection of open-source class libraries, which simplifies the creation of network-centric, portable, and maintainable software in C++.
## Overview
Poco library provides functionality for various areas, such as:
- Networking: HTTP, FTP, SMTP, POP3, and other internet protocols
- File handling: FileSystem, Path, File, and Directory classes
- XML processing: XML parsing and DOM manipulation
- Logging: Loggers, levels, channels, patterns, etc.
- Data manipulation: Stream, ByteBuffer, Buffer, etc.
- Multithreading and synchronization: Threads, Mutex, Event, and Condition
## Code Example
Here's an example demonstrating an HTTP client using the Poco library:
```cpp
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPMessage.h>
#include <Poco/StreamCopier.h>
#include <iostream>
#include <string>
using namespace Poco::Net;
using namespace Poco;
int main()
{
try
{
// Prepare the request
URI uri("http://example.com");
HTTPClientSession session(uri.getHost(), uri.getPort());
HTTPRequest request(HTTPRequest::HTTP_GET, uri.getPath(), HTTPMessage::HTTP_1_1);
request.setContentType("application/json");
session.sendRequest(request);
// Process the response
HTTPResponse response;
std::istream& responseStream = session.receiveResponse(response);
if (response.getStatus() == HTTPResponse::HTTP_OK)
{
// Successful
std::string responseBody;
StreamCopier::copyToString(responseStream, responseBody);
std::cout << "Response: " << responseBody << std::endl;
}
else
{
// Error
std::cout << "Error: " << response.getStatus() << " " << response.getReason() << std::endl;
}
}
catch(const Exception& e)
{
std::cerr << "Error: " << e.displayText() << std::endl;
return -1;
}
return 0;
}
```
In the above example, Poco is used to send an HTTP GET request and process the response. It manages tasks like connecting to the server, handling exceptions, and managing HTTP headers.
Learn more from the following resources:
- [@article@Official Docs for Poco Library](https://docs.pocoproject.org/)

View File

@@ -1,79 +0,0 @@
# Protocol Buffers (protobuf)
Protocol Buffers, or protobuf, is a language and platform-neutral data serialization format developed by Google. It is used to efficiently serialize structured data for use in communications protocols, data storage, and more. It is extensible, as it allows you to define your own custom data structures called "messages" with various scalar and complex field types.
Here is a brief summary of protobuf and how to use it in C++:
- **Define your `.proto` file:** Create a `.proto` file that defines the structure of your messages.
*Example:*
```
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
string email = 3;
}
```
- **Compile the `.proto` file:** You need to compile your `.proto` file to generate C++ classes for serialization and deserialization.
*Example:*
```sh
protoc --cpp_out=. person.proto
```
This will generate two files: `person.pb.cc` and `person.pb.h` that contains the C++ class definitions.
- **Include protobuf library and generated files into your C++ code:** You'll need to include the protobuf library and the generated files in your main C++ code.
*Example:*
```cpp
#include <iostream>
#include <fstream>
#include "person.pb.h"
int main () {
GOOGLE_PROTOBUF_VERIFY_VERSION; // Verify that protobuf library headers match library version
// Serialize a Person message
Person person;
person.set_name("Sam");
person.set_age(35);
person.set_email("sam@example.com");
// Save the data to a file
std::ofstream output("person.bin", ios::binary);
person.SerializeToOstream(&output);
output.close();
// Deserialize the message from the file
Person input_person;
std::ifstream input("person.bin", ios::binary);
input_person.ParseFromIstream(&input);
input.close();
// Print the deserialized message
std::cout << "Name: " << input_person.name() << std::endl;
std::cout << "Age: " << input_person.age() << std::endl;
std::cout << "Email: " << input_person.email() << std::endl;
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
```
- **Compile and link your C++ code:** Finally, compile your C++ code and link it to the protobuf library.
*Example:*
```sh
g++ -std=c++11 -o main main.cpp person.pb.cc -lprotobuf
```
For more information and examples, you can refer to the [official protobuf C++ tutorial](https://developers.google.com/protocol-buffers/docs/cpptutorial).

View File

@@ -1,129 +0,0 @@
# gRPC
gRPC (gRPC Remote Procedure Calls) is an open-source Remote Procedure Call (RPC) framework that runs on various programming languages, including C++. gRPC is designed to be high-performance, efficient, and scalable, making it ideal for microservice architectures and other applications with high performance requirements.
gRPC uses the Protocol Buffers (Protobuf) serialization format for message exchange and method definition. Protocol Buffers enable more efficient and smaller serialization compared to other formats like JSON or XML.
## Protocol Buffers
In gRPC, you start by defining service definitions and message structures in `.proto` files. You can define data structures and service interfaces using a compact, language-neutral, platform-neutral binary format.
Here's an example of how that might look:
```proto
syntax = "proto3";
package example;
// The gRPC service definition
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The Request message definition
message HelloRequest {
string name = 1;
}
// The Reply message definition
message HelloReply {
string message = 1;
}
```
After defining the `.proto` file, you use the `protoc` compiler to generate the corresponding C++ code for your application.
## gRPC C++ Server
To create a gRPC server in C++, you first need to implement the service interface generated by the `protoc` compiler. Here's an example implementation for the `Greeter` service:
```cpp
#include <grpcpp/grpcpp.h>
#include "example.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using example::HelloRequest;
using example::HelloReply;
using example::Greeter;
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};
void RunServer() {
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;
ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
}
int main(int argc, char** argv) {
RunServer();
return 0;
}
```
## gRPC C++ Client
Similarly, to create a gRPC C++ client, you use the generated code from `protoc` compiler and connect to a server:
```cpp
#include <grpcpp/grpcpp.h>
#include "example.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using example::HelloRequest;
using example::HelloReply;
using example::Greeter;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel) : stub_(Greeter::NewStub(channel)) {}
std::string SayHello(const std::string& user) {
HelloRequest request;
request.set_name(user);
HelloReply reply;
ClientContext context;
Status status = stub_->SayHello(&context, request, &reply);
if (status.ok()) {
return reply.message();
} else {
std::cout << "RPC failed" << std::endl;
return "RPC failed";
}
}
private:
std::unique_ptr<Greeter::Stub> stub_;
};
int main(int argc, char** argv) {
GreeterClient greeter(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
std::string user("world");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;
return 0;
}
```
This is a basic example demonstrating the client-server communication using gRPC in C++. More advanced features like bi-directional streaming, error handling, and authentication can also be used in gRPC. For more information, you can refer to the [gRPC C++ documentation](https://grpc.io/docs/languages/cpp/).

View File

@@ -1,5 +0,0 @@
# TensorFlow
TensorFlow is an open-source machine learning library developed by researchers and engineers from the Google Brain team. It is designed for building, training, and deploying deep learning models. TensorFlow provides a set of tools for ML, deep learning, and numerical computation using data flow graphs. TensorFlow can process computations on GPUs and TPUs, which speed up training time and ensures efficient model deployment.
You can visit TensorFlow's official website (https://www.tensorflow.org/) and their GitHub repository (https://github.com/tensorflow/tensorflow) for more information, tutorials, and resources.

View File

@@ -1,70 +0,0 @@
# Pybind11
Pybind11 is a lightweight header-only library that seamlessly integrates C++ code with Python, allowing users to easily expose C++11 code to the Python ecosystem. This is achieved by providing `Python` bindings that can interact with functions and classes written in `C++`. It offers an API similar to the Boost.Python library but requires less code, thus leading to better performance.
Pybind11 helps in creating library extensions, bringing high-performance C++ code into Python programs, and using Python's flexibility for rapid development while still benefiting from the efficiency of C++.
### Code Examples
Here are a few examples of Pybind11 for understanding the concept better:
- Exposing a C++ function to Python:
```cpp
#include <pybind11/pybind11.h>
int add(int a, int b) {
return a + b;
}
PYBIND11_MODULE(example, m) {
m.def("add", &add, "A function that adds two numbers");
}
```
Running the above example will create a Python module named `example`, containing a single function `add`. You can use this new function in Python as follows:
```python
import example
result = example.add(1, 2)
print(result) # Output: 3
```
- Exposing a C++ class to Python:
```cpp
#include <pybind11/pybind11.h>
namespace py = pybind11;
class MyTestClass {
public:
MyTestClass(const std::string &name) : name_(name) { }
const std::string &name() const { return name_; }
void setName(const std::string &name) { name_ = name; }
private:
std::string name_;
};
PYBIND11_MODULE(example, m) {
py::class_<MyTestClass>(m, "MyTestClass")
.def(py::init<const std::string &>())
.def("name", &MyTestClass::name)
.def("setName", &MyTestClass::setName);
}
```
After compiling the code and importing it into Python, you can create `MyTestClass` instances and call their `name()` and `setName(string)` methods:
```python
import example
obj = example.MyTestClass("some_name")
print(obj.name()) # Output: some_name
obj.setName("new_name")
print(obj.name()) # Output: new_name
```

View File

@@ -1,59 +0,0 @@
# Spdlog
`spdlog` is a fast, header-only, C++ logging library. It provides a simple and efficient way to add diagnostic logging to your C++ application.
## Features:
- Header-only, no need to build or link a library
- Highly configurable, including support for custom log sinks (e.g. writing to a file or a database)
- Asynchronous and synchronous logging modes
- Preprocessor-based format string checks to catch bugs at compile-time
- Easy to extend with custom formatters, sinks, and levels
## Usage example:
Include the `spdlog` header, create a logger object, and use it to log messages:
```cpp
#include "spdlog/spdlog.h"
int main() {
// Create a logger with the name "example_logger"
auto logger = spdlog::stdout_color_mt("example_logger");
// Log messages with various severity levels
logger->info("Welcome to spdlog!");
logger->warn("Warning message");
logger->error("Error message");
return 0;
}
```
## Custom sink example:
Here's an example of creating a logger with a custom sink that writes to a text file:
```cpp
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
int main() {
// Create a file sink to write logs to "logs.txt"
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs.txt");
// Create a logger with the file sink and the name "example_logger"
auto logger = std::make_shared<spdlog::logger>("example_logger", file_sink);
// Register the logger
spdlog::register_logger(logger);
// Log messages
logger->info("Welcome to spdlog!");
logger->warn("Warning message");
logger->error("Error message");
return 0;
}
```
For more examples and detailed documentation, visit the [spdlog GitHub repository](https://github.com/gabime/spdlog).

View File

@@ -1,59 +0,0 @@
# OpenCL
OpenCL (Open Computing Language) is a framework for writing programs that enables you to execute code on heterogeneous platforms consisting of CPUs, GPUs, and other processors. It is primarily used for parallel programming, and it can be employed to improve the performance of various applications, including gaming, image and video rendering, and scientific computing.
## Overview
OpenCL provides a standardized programming interface, allowing you to target different devices such as graphics cards from different vendors. You can program in C with OpenCL C or C++ with OpenCL C++ kernel language, which are based on the ISO C99 and C++14 respectively, with specific extensions, built-ins, and features to exploit device parallelism.
## Key Concepts
- Platform: A collection of devices and software features provided by a vendor.
- Device: A processing unit that can execute OpenCL code, e.g., a CPU or a GPU.
- Command queue: A sequence of instructions to be executed on a device.
- Kernel: A parallelized function that is executed on OpenCL devices.
- Buffer: A memory object that stores a specific amount of data (e.g., an array of integers or floats) that is accessible by both the host and devices.
## Sample Code
Here is a simple OpenCL code example that illustrates how to implement vector addition:
```cpp
#include <CL/cl.h>
#include <iostream>
#include <vector>
const char *kernelSource = "__kernel void vector_add(__global int *A, __global int *B, __global int *C, const int N) {"
" int i = get_global_id(0);"
" if (i < N) {"
" C[i] = A[i] + B[i];"
" }"
"}";
int main() {
// Initialize data vectors
std::vector<int> A = {1, 2, 3};
std::vector<int> B = {4, 5, 6};
std::vector<int> C(A.size());
// Set up OpenCL environment, devices, and context
// ... omitted for brevity ...
// Create memory buffers for A, B, and C
// ... omitted for brevity ...
// Create kernel from source and set kernel arguments
// ... omitted for brevity ...
// Execute kernel using command queue and read output buffer
// ... omitted for brevity ...
// Output results
for (size_t i = 0; i < A.size(); ++i) {
std::cout << A[i] << " + " << B[i] << " = " << C[i] << std::endl;
}
return 0;
}
```
This code snippet demonstrates the basic structure of an OpenCL program in C++. There are additional details required in order to set up the environment, devices, and context, as well as creating the memory buffers, kernel, and command queue. You can find complete examples and more information in the [official OpenCL Programming Guide](https://www.khronos.org/files/opencl22-reference-guide.pdf).

View File

@@ -1,69 +0,0 @@
# fmt
`fmt` is a modern C++ formatting library that provides an easy and efficient way to format text and print it to various outputs. The library offers a high level of compatibility with C++ standards, making it suitable for various applications and platforms. `fmt` emphasizes simplicity, extensibility, and type safety.
## Features
- Supports positional and named arguments for better readability in complex formatting tasks
- Supports format string syntax similar to Python's `str.format()`
- Provides compile-time format string checks for type safety
- Extensive documentation and user-friendly API
## Example Usage
Here are some examples of how to use the `fmt` library:
## Basic Usage
```cpp
#include <fmt/core.h>
int main() {
fmt::print("Hello, world!\n");
return 0;
}
```
## Formatting with Positional Arguments
```cpp
#include <fmt/core.h>
int main() {
fmt::print("The answer is {}.\n", 42);
fmt::print("{1}, {0}!\n", "world", "Hello");
return 0;
}
```
## Formatting with Named Arguments
```cpp
#include <fmt/core.h>
int main() {
fmt::print("Hello, {name}!\n", fmt::arg("name", "world"));
return 0;
}
```
## Using Format String Syntax
```cpp
#include <fmt/core.h>
int main() {
fmt::print("{:<30}", "left-aligned");
fmt::print("{:>30}", "right-aligned");
fmt::print("{:^30}", "center-aligned");
fmt::print("{:*^30}", "center-aligned");
fmt::print("int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
fmt::print("{:.2f}", 3.1415926);
fmt::print("{:010.2f}", 3.1415926);
return 0;
}
```
For more information, you can refer to the official [fmt documentation](https://fmt.dev/latest/index.html).

View File

@@ -1,84 +0,0 @@
# Ranges v3
Ranges v3 is a C++ library designed to work with ranges of values, rather than individual values. It provides a set of utilities and algorithms to manipulate and transform ranges of values in an efficient and expressive way. The library is inspired by the Range concept proposed for inclusion in the C++ standard library for C++20.
---
## Overview
Ranges v3 includes three main components:
- **Range adaptors:** These are composable algorithms that transform a range into a new range. They help to create lazy views over the data without actually modifying it.
- **Action adaptors:** These are algorithms that modify a range in-place. For example, sorting or filtering elements in a container directly.
- **Trait concepts and utility functions:** Provide tools for working with range types, like determining if a type is a range, getting the iterator type for a range, etc.
---
## Code examples
Here are some code examples of using the Ranges v3 library:
## Including the library
First, you need to include the appropriate header files from the library. To use the entire Ranges v3 library, you can simply include the `range/v3/all.hpp` header file:
```cpp
#include <range/v3/all.hpp>
```
## Using range adaptors
You can use range adaptors to manipulate and transform ranges. For example, you can use the `view::filter` and `view::transform` adaptors to create a new range containing only even numbers and then square them:
```cpp
#include <iostream>
#include <range/v3/all.hpp>
using namespace ranges;
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5, 6};
// Create a new range containing only even numbers, and then square them.
auto even_squares = numbers | view::filter([](int n) { return n % 2 == 0; })
| view::transform([](int n) { return n * n; });
// Print the even_squares range.
for (auto n : even_squares) {
std::cout << n << ' ';
}
// Output: 4 16 36
return 0;
}
```
## Using action adaptors
Action adaptors are used to modify ranges in-place. For example, you can use the `action::sort` and `action::unique` adaptors to sort and remove duplicate elements from a container:
```cpp
#include <iostream>
#include <range/v3/all.hpp>
using namespace ranges;
int main() {
std::vector<int> numbers = {5, 3, 1, 4, 4, 2, 2};
// Sort the numbers and remove duplicates.
numbers |= action::sort | action::unique;
// Print the modified numbers vector.
for (auto n : numbers) {
std::cout << n << ' ';
}
// Output: 1 2 3 4 5
return 0;
}
```
Ranges v3 provides a wide range of adaptors and actions to work with ranges in a more expressive and efficient way. You can explore more in the [official documentation](https://github.com/ericniebler/range-v3/blob/master/doc/index.md).

View File

@@ -1 +0,0 @@
# Libraries

Some files were not shown because too many files have changed in this diff Show More