Modern C++ Utility Library
一个基于现代 C++ 的通用基础库,提供容器、并发、文件、时间、字符串、静态反射(序列化 / 配置生成)等常用模块。
- 🧩 以 C++20 modules 组织,全部通过
import modforge;使用 - 🚀 现代 C++ / C++26,无第三方依赖
- 🧵 并发与无锁数据结构(SPSC / MPSC / SPMC / MPMC)
- 🔍 C++26 静态反射(可选模块,默认关闭):反射序列化 + 配置驱动生成类型化 Config
- 🧪 以单文件单测试函数方式维护模块测试
- 🛠️ 覆盖参数解析、文件系统、时间、线程池、定时器、树结构、信号、原子 id 生成器、配置生成、 终端/鼠标辅助模块
- 🌐 阻塞式网络(IPv4 端点、TCP 字节流与长度前缀分帧、UDP 数据报)
- 🧠 张量与深度学习(任意秩张量、激活 / 损失 / 优化器、BP 全连接网络、CNN)
| 模块 | 说明 | 状态 |
|---|---|---|
args_parser |
命令行参数解析 | ✅ |
directory |
目录操作 | ✅ |
file |
文件操作 | ✅ |
lock_free_queue |
SPSC / MPSC / SPMC / MPMC 无锁队列 | ✅ |
id_generator |
原子递增 id 生成器(线程安全) | ✅ |
thread_pool |
线程池 | ✅ |
time |
时间工具(UTC / 本地时间、解析与格式化) | ✅ |
timer |
定时器、协程定时器 | ✅ |
signal |
信号/回调机制 | ✅ |
terminal |
终端尺寸、光标显隐/定位/上下移动 | ✅ |
cursor |
鼠标光标控制与点击监听 | 🟡 |
table |
终端表格渲染 | ✅ |
string_utils |
字符串工具 | ✅ |
tree |
通用 N 叉树与索引树 | ✅ |
range |
区间封装(整数/指针/数组/容器/迭代器对/正则匹配 统一可迭代) | ✅ |
utils |
通用工具 | ✅ |
static_serialize |
C++26 静态反射序列化 | 🔌 |
config_generator |
配置→类型化 Config(编译期生成 + 运行时加载) | 🔌 |
event |
事件模块(当前为空壳,未接入总入口) | 🚧 |
net.address |
网络端点(IPv4 + 端口) | ✅ |
net.socket |
socket 底座:fd 生命周期与通用调用 | ✅ |
net.tcp |
阻塞式 TCP(字节流 + 长度前缀分帧) | ✅ |
net.udp |
阻塞式 UDP(数据报收发) | ✅ |
net.http |
HTTP(当前为空壳) | 🚧 |
net.websocket |
WebSocket(当前为空壳) | 🚧 |
tensor |
任意秩张量(基于 std::mdspan:批量矩阵乘、零拷贝转置、序列化) |
✅ |
deep_learning.tools |
激活函数 / 损失函数 / 优化器 / OneHot / 随机工具 | ✅ |
deep_learning.bp |
全连接 BP 网络(前向 / 反向 / 余弦退火) | ✅ |
deep_learning.cnn |
卷积神经网络(Conv / Pool / FC + MNIST 加载与模型序列化) | ✅ |
图例:✅ 默认构建 · 🔌 可选,需显式开启 · 🟡 平台受限 · 🚧 占位未实现
net.address/net.socket/net.tcp/net.udp通过modforge.net已接入总入口——import modforge;即可直接使用;http/websocket仍是空壳,未导出。
cursor目前只有 Windows 实现(WinAPI),Linux 侧为空实现——接口可链接、调用为空操作, 注入能力依赖 X11 / Wayland,方案未落地。
deep_learning.tools/.bp/.cn通过modforge.deep_learning已接入总入口——import modforge;即可直接使用;tensor也经总入口导出。 三者都跨模块依赖tensor,bp另依赖terminal(训练时隐藏光标)——tensor/terminal是独立模块,不属于deep_learning。 注:cnn目前还没有测试覆盖。🔌 反射可选模块中,
static_serialize与config_generator在开启MODFORGE_ENABLE_REFLECTION时 也经总入口导出(import modforge;即得);event仍未接入总入口,需单独import。
graph LR
modforge --> args_parser
modforge --> directory
modforge --> file
modforge --> lock_free_queue
modforge --> id_generator
modforge --> thread_pool
modforge --> time
modforge --> timer
modforge --> tree
modforge --> range
modforge --> utils
modforge --> string_utils
modforge --> signal
modforge --> terminal
modforge --> cursor
modforge --> table
modforge -.-> static_serialize
modforge -.-> config_generator
modforge --> net
modforge --> tensor
modforge --> deep_learning
args_parser --> string_utils
args_parser --> utils
config_generator --> string_utils
config_generator --> utils
directory --> string_utils
file --> utils
thread_pool --> lock_free_queue
signal --> id_generator
timer --> id_generator
timer --> time
table --> terminal
subgraph "net module"
net --> net.tcp
net --> net.udp
net --> net.socket
net --> net.address
net.tcp --> net.socket
net.tcp --> net.address
net.udp --> net.socket
net.udp --> net.address
net.socket --> net.address
end
subgraph "deep_learning module"
deep_learning --> deep_learning.tools
deep_learning --> deep_learning.bp
deep_learning --> deep_learning.cnn
deep_learning.bp --> deep_learning.tools
deep_learning.cnn --> deep_learning.tools
end
deep_learning.tools --> tensor
deep_learning.bp --> tensor
deep_learning.cnn --> tensor
deep_learning.bp --> terminal
虚线表示 static_serialize 与 config_generator 仅在开启 MODFORGE_ENABLE_REFLECTION 时存在。
net.address / net.socket / net.tcp / net.udp 通过 modforge.net 接入总入口(import modforge; 即得),
deep_learning.tools / .bp / .cn 通过 modforge.deep_learning 同理;
event 仍未接入总入口,http / websocket 仍是空壳且未导出——用它们需单独 import。
id_generator 被 signal 与 timer 依赖,且经总入口对外导出。
关闭反射时 GCC 16.2.1、GCC trunk(17.0.0 experimental)与 Clang 22 都可构建,测试全部通过;
需要反射模块时必须用 GCC trunk —— std::meta 等 C++26 反射设施在 16.2.1 的标准库中并不完整
(Clang 不支持 -freflection,反射开启时不在验证范围内)。
cmake -S . -B build -G Ninja -DCMAKE_CXX_COMPILER="/path/to/g++"
cmake --build build --target tests
ctest --test-dir build --output-on-failure
directory模块内置了一个轻量辅助模板path_string():用has_generic_display_stringconcept 探测标准库能力,有generic_display_string()(GCC 17)就走它,否则回退到generic_string()(GCC 16)。这样 GCC 16 不会有缺失符号、GCC 17 也不会触发generic_string()的弃用警告,关闭反射时两个版本都能干净构建。
| 选项 | 默认 | 影响的模块 |
|---|---|---|
MODFORGE_ENABLE_REFLECTION |
OFF | static_serialize、config_generator |
命令行开启:
cmake -S . -B build-check -G Ninja -DMODFORGE_ENABLE_REFLECTION=ON作为子项目引入时,在 add_subdirectory() 之前设置:
set(MODFORGE_ENABLE_REFLECTION ON CACHE BOOL "" FORCE)
add_subdirectory(modforge)关闭时 static_serialize、config_generator 不参与编译,对应的两个测试也不会注册到 CTest。
开启后 -freflection 会随 modforge 目标传递给下游,下游整体将切入反射方言——
不用反射的项目保持默认 OFF 即可,不受影响。
安装分发时反射能力在安装那一刻固化:通过 find_package 拿到的包是否带反射,
取决于安装时 MODFORGE_ENABLE_REFLECTION 的取值,消费方无需也无法在 find_package 之后切换。
import std 目前仍是实验特性,两项开关必须在 project() 之前设置,否则 configure 阶段就会报
Experimental import std support not enabled。推荐 include 库自带的 init 脚本
(自动按 CMake 版本选 UUID,源码树与安装包中都带):
cmake_minimum_required(VERSION 3.30.0)
include("/path/to/modforge/cmake/modforge-init.cmake") # 必须在 project() 之前
project(my_app LANGUAGES CXX)也可以手动设置(UUID 随 CMake 版本变化,见 cmake/modforge-init.cmake):
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "<UUID>")
set(CMAKE_CXX_MODULE_STD 1)
project(my_app LANGUAGES CXX)add_subdirectory(modforge)
target_link_libraries(my_app PRIVATE modforge)先构建并安装 modforge(默认安装到 /usr/local,可用 --prefix 指定前缀):
cmake --build <modforge构建目录>
cmake --install <modforge构建目录> # 安装到默认前缀
cmake --install <modforge构建目录> --prefix /your/prefix # 或指定前缀消费方工程(configure 时用 -DCMAKE_PREFIX_PATH=/your/prefix 指向安装前缀):
find_package(modforge CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE modforge::modforge)卸载(按构建目录里的 install_manifest.txt 删除安装产物):
cmake --build <modforge构建目录> --target uninstall反射能力在安装那一刻固化:只有安装时以 MODFORGE_ENABLE_REFLECTION=ON 构建并安装,
find_package 拿到的包才带 static_serialize 与 config_generator。消费方不需要(也无法)在自己的工程里开任何选项:
# 安装一个带反射的包
cmake -S . -B build -G Ninja -DMODFORGE_ENABLE_REFLECTION=ON
cmake --build build
cmake --install build --prefix /your/prefiximport modforge;
// 接口与 add_subdirectory 方式完全一致,直接用即可
modforge::ArchivePointer ar(buf);
modforge::serialize(s, ar);
modforge::deserialize(s2, ar2);两点注意:
- 包是否带反射,消费方代码可以用
#ifdef MODFORGE_ENABLE_REFLECTION判断 (该宏随modforge::modforge目标的接口自动传播到消费方编译)。 - 带反射的包会把
-freflection自动传给消费方编译(含消费方自己的代码), 因此消费方编译器也必须支持-freflection(如 gcc-trunk 17)。
之后即可 import modforge; 使用,各模块的接口见 src/*.cppm 与 tests/ 下对应的用例。
项目使用 CTest,关闭反射为 20 个用例,开启反射后为 22 个。
ctest --test-dir build-check --output-on-failure| 测试 | 模块 |
|---|---|
test_args_parser |
args_parser |
test_directory |
directory |
test_file |
file |
test_lock_free_queue |
lock_free_queue |
test_string_utils |
string_utils |
test_time |
time |
test_timer |
timer |
test_thread_pool |
thread_pool |
test_tree |
tree |
test_range |
range |
test_utils |
utils |
test_signal |
signal |
test_event |
event(空测试) |
test_table |
table |
test_terminal |
terminal |
test_socket |
net.socket |
test_tcp |
net.tcp |
test_udp |
net.udp |
test_id_generator |
id_generator |
test_deep_learning |
tensor、deep_learning.tools、deep_learning.bp(张量 / 工具函数 / BP 收敛) |
test_static_serialize |
static_serialize(🔌 可选) |
test_config_generator |
config_generator(🔌 可选) |
单个测试可直接运行:
./build-check/tests/tests test_timer
./build-check/tests/tests test_signal
./build-check/tests/tests test_tree- Copy-on-Write
- Event Bus
-
event模块实体化(当前为空壳,且未接入总入口)
- Configuration(
config_generator:编译期从配置生成类型化 Config + 运行时加载)
-
find_package安装分发(install / export 规则)