https://github.com/shucharjer/atom.utils
A headers-only util library in C++20, including reflection, structures, and some magic. | 一个仅有头文件的C++20基础工具库,包括反射、结构和一些魔法。
https://github.com/shucharjer/atom.utils
cpp cpp20 cpp20-library headers-only modern-cpp reflection utils
Last synced: 8 months ago
JSON representation
A headers-only util library in C++20, including reflection, structures, and some magic. | 一个仅有头文件的C++20基础工具库,包括反射、结构和一些魔法。
- Host: GitHub
- URL: https://github.com/shucharjer/atom.utils
- Owner: Shucharjer
- License: mit
- Created: 2024-12-24T14:54:53.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-05-01T14:38:43.000Z (9 months ago)
- Last Synced: 2025-05-09T01:47:37.984Z (8 months ago)
- Topics: cpp, cpp20, cpp20-library, headers-only, modern-cpp, reflection, utils
- Language: C++
- Homepage:
- Size: 636 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- License: LICENSE
Awesome Lists containing this project
README
# atom.utils
[简体中文](readme_zh.md) | English
atom.utils is a collection of basic tools used in the atom engine.
It is a headers-only modern C++ library that is easy to link in various projects.
Now it includes some data structures (such as sparse_map, compressed_pair, spin_lock, etc.) as well as reflection and its corresponding serialization.
The purpose of this library is to provide easy-to-use modern C++ basic tools to help users quickly build content in modern C++.
## Quick start
### Compiler requirements
This library only supports C++20 or higher, so, make sure your compiler supports C++20.
- g++ 10 above;
- clang++13 above;
- msvc 14.29 above.
### Install & Compile
#### Manually Install
1. Clone this repo
```shell
git clone https://github.com/Shucahrjer/atom.utils
cd atom.utils
```
2. build
```shell
cmake -B build
# or you could add other args, such as cmake -DCMAKE_C_COMPILER="clang" -DCMAKE_CXX_COMPILER="clang++" -DCMAKE_MAKE_PROGRAM="ninja" -G "Ninja" -B build
cd build
cmake --build . --config debug
```
3. install
```shell
cmake --install . # --prefix
```
4. start dev
## Intro
### Table of Contents
Core
Pair
Pipeline and Closure
Adaptor Closure
Closure
Range
Reflection
No Macro Reflection
Custom Reflection
Support for Serialization
Structures
dense_map
dense_set
Thread
Thread Pool
Coroutine
Spin Lock
Hybrid Lock
Signal
Lambda
Delegate
Sink
Dispatcher
Memory
Memory Pool
Allocator
Destroyer
Storage
around_ptr
The following content is based on such a statement
```c++
using namespace atom::utils;
```
### Core
#### `pipeline_base`&`pipline_result`&`closure`
Since C++20 does not have the range adapter closure in C++23, the closure type has to be introduced and supported in C++20
As the name implies, `pipeline_base` is the base class that scope closures need to inherit, `pipline_result` is the result of pipeline operations, and `closure` is the closure
```c++
struct get_vector_fn {
template
std::vector operator()(Args&&... args) {
return std::vector(std::forward(args)...);
}
};
auto closure = make_closure();
// A vector of 10 elements
auto vector = closure(10);
```
You can use `pipeline_base` to quickly build a scope closure. For example:
```c++
struct empty_view {
using pipeline_tag = pipeline_tag;
template
requires std::is_default_constructible_v
constexpr auto operator()(Rng&& range) const {
return Rng{};
}
};
constexpr inline empty_view empty;
...
// do pipeline operation between a range and a range closure
std::vector vector = { 2, 3, 4, 6 };
auto empty_vector = vector | empty;
assert(empty_vector.empty());
// do pipeline operator between two range closures
auto closure = empty | std::views::reverse;
auto another_empty_vector = vector | closure;
assert(another_empty_vector.empty());
```
### Range
As we all know, std::ranges::to provided in C++23 is a very useful function that can build a container of another type from a range of one type with simple syntax.
Now, it has been brought to C++20. If you use C++23, the implementation in the standard library will be called.
```c++
auto map = std::map{{1, 2}, {2, 1}, {465, 0}, {53, 634}};
auto values = map | std::views::values;
auto vector = ranges::to(values);
```
It is almost the implementation in the standard library, except that C++20 does not have std::from_range in C++23.
It is not difficult to guess that it can also get a closure like in C++23.
```c++
auto closure = ranges::to>(4);
auto vector = closure(values);
```
In the process of implementing std::ranges::to, some types are also introduced,
such as `phony_input_iterator`, `pipline_result` and `range_closure`,
which are respectively "fake input iterators" for delayed loading, the results of pipeline operations and closures for delayed loading.
You can try to use them to implement some delayed loading outside the standard library.
### Reflection
```c++
// definition
struct a {
int member1;
char member2;
};
BEGIN_TYPE(a)
FIELDS(FIELD(member1))
END_TYPE()
// usage
auto a = ::a{};
auto reflected = utils::reflected<::a>{};
auto& tuple = reflected.fields();
auto& traits1 = std::get(tuple)>(tuple);
int value1 = traits1.get(a);
auto& traits2 = std::get(tuple)>(tuple);
char value2 = traits1.get(a);
```
Also supports serialization and deserialization of `nlohmann-json`
```c++
// Serialization
nlohmann::json json = a;
std::cout << json.dump(4) << '\n';
// Change the value of member1, expect it to change back to the previous value after deserialization
a.member1 = 90;
// Deserialization
a = json;
std::cout << a.member1 << '\n';
```
### Memory
Provides allocators, memory pools, and storage
#### Memory pool
Provides two types of memory pools
```c++
synchronized_pool synchronized_pool{};
unsynchronized_pool unsynchronized_pool{};
```
#### Allocator
Provides two types of allocators: `standard_allocator` and `allocator`
Among them, `standard_allocator` just encapsulates `std::allocator`
And `allocator` needs to be created from the memory pool
```c++
synchronized_pool pool;
allocator allocator{pool};
std::vector vector{allocator};
```
#### Memory
Exclusive memory and shared memory are provided.
Shared memory supports copy-on-write, which is suitable for scenarios with high copy overhead.
It should be noted that this copy-on-write is only effective when `=` is used.
### Structure
#### `dense_map`&`dense_set`
### Signal
#### Delegate
#### Sink
#### Dispatcher