diff --git a/.agents/docs/plans/implementation-plan.md b/.agents/docs/plans/implementation-plan.md index 15fcded..19482d4 100644 --- a/.agents/docs/plans/implementation-plan.md +++ b/.agents/docs/plans/implementation-plan.md @@ -1,102 +1,125 @@ -# Primitives 下一步实现计划清单(2026-03-26) - -## 总体原则 - -- [ ] 先定义稳定 API 边界,再落地实现 -- [ ] 每个能力都配套 tests + examples + docs -- [ ] 高风险转换默认禁止隐式触发,只允许显式 API -- [ ] 明确分层职责:`algorithms` 负责值域/排序/边界元信息与值算法;`conversion` 负责显式类型变换 -- [ ] 明确依赖方向:`conversion` 可依赖 `algorithms`,`algorithms` 不反向依赖 `conversion` - -## M1. C API 互操作层(双向) - -### 工作清单 - -- [ ] 定义稳定 C ABI(命名规范、导出宏、版本策略) -- [ ] 设计双向能力:C 调用 primitives;primitives 适配并调用 C API -- [ ] 统一错误模型(error code + 可选 message buffer) -- [ ] 提供最小可用头文件:`include/mcpplibs/primitives/c_api.h` -- [ ] 增加 C/C++ 混合构建测试(C 编译器 + C++ 链接) -- [ ] 增加示例:`examples/c/basic.c`、`examples/cpp/use_c_api.cpp` - -### 验收标准 - -- [ ] 纯 C 工程可链接并完成基础能力调用 -- [ ] C++ 对外部 C API 的适配调用行为可控、无未定义行为 - -## M2. Concept/Traits 体系增强与元信息 API - -### 工作清单 - -- [ ] 扩展 concept 分层(category/representation/policy-capability) -- [ ] 明确 `underlying::traits` 与 `algorithms::traits` 的职责边界:前者描述表示层;后者描述值算法层 -- [ ] 完善 `traits` 元信息(`kind`、`rep_type`、policy tags) -- [ ] 设计 `algorithms::traits`,内容参考 `std::numeric_limits`,但只保留算法/比较所需子集: -- [ ] `min()` / `lowest()` / `max()` / `epsilon()` / `infinity()` / `quiet_nan()` -- [ ] `is_bounded` / `is_exact` / `is_signed` / `is_integer` / `is_iec559` -- [ ] `has_infinity` / `has_quiet_nan` / `digits` / `digits10` / `radix` -- [ ] 增加排序能力元信息:`comparison_category`、`totally_ordered`、`partially_ordered`、`unordered_possible` -- [ ] 提供双参聚合元信息:`algorithms::common_traits`,统一暴露 `common_rep`、可比较性、边界查询与策略兼容性 -- [ ] 提供检测类 API(可比较性/可裁剪性/可转换性/是否有损/错误模型能力) -- [ ] 统一 `constexpr` 查询入口,减少分散 traits 访问 -- [ ] 增加编译期测试矩阵(`static_assert` 覆盖) - -### 验收标准 - -- [ ] 上层模块仅依赖公开 concept/traits,不依赖 `details::*` -- [ ] `algorithms::traits` 可直接支撑算法层判定,并作为 conversion 的元信息依赖 -- [ ] `std::numeric_limits` 相关逻辑不再散落在 `conversion`/`operations` 内部 - -## M3. 显式转换层(任意策略组适用) - -### 工作清单 - -- [ ] 设计统一接口族(建议):`explicit_cast`、`try_cast`、`checked_cast` -- [ ] 将边界、NaN、无穷大、精度与排序相关判定统一改为依赖 `algorithms::traits` / `algorithms::common_traits` -- [ ] 支持任意策略组组合,不绑定特定策略实现 -- [ ] 风险可见化(截断/溢出/精度损失)并可程序化读取 -- [ ] 定义失败语义(错误码或 expected 风格,按策略可配置) -- [ ] 建立转换矩阵测试(同类/跨类/跨策略组) - -### 验收标准 - -- [ ] 所有跨类高风险转换必须走显式 API -- [ ] 风险信息可在编译期或运行期被确定性获取 -- [ ] `conversion` 模块仅消费 `algorithms` 提供的元信息,不反向定义算法层协议 - -## M4. 算法层(traits 先行,以 max/min 为起点) - -### 工作清单 - -- [ ] 确定模块结构:`mcpplibs.primitives.algorithms`、`mcpplibs.primitives.algorithms.traits`、`mcpplibs.primitives.algorithms.compare`、`mcpplibs.primitives.algorithms.minmax` -- [ ] 先实现 `algorithms::traits` 与 `algorithms::common_traits`,作为整个算法层与 conversion 的基础依赖 -- [ ] 约束算法职责只涉及值的比较、选择、裁剪与边界处理,不提供目标类型导向的 cast API -- [ ] `max`/`min` 内部仅允许做 `common_rep` 归一化或排序语义协商,不绕回 conversion 层 -- [ ] 实现 `max`/`min`,并预留 `clamp`/`compare` 扩展位 -- [ ] 支持同类输入与受约束的异类输入;异类场景必须满足 `common_rep`、排序能力与策略组约束 -- [ ] 明确 `partial_ordering` / `unordered` 语义,尤其是浮点 `NaN` 路径 -- [ ] 为 `clamp`/`compare` 抽出复用内核:公共比较、边界判定、值选择 -- [ ] 在可行范围保持 `constexpr`/`noexcept` 特性 -- [ ] 增加边界测试(极值、NaN、有符号/无符号混合、不同 `comparison_category`) - -### 验收标准 - -- [ ] 算法行为与策略约束一致 -- [ ] 风险路径始终显式、可审计 -- [ ] `algorithms` 可独立编译并被 `conversion` 依赖,不形成反向模块耦合 -- [ ] 算法层实现不通过“显式转换 API”间接完成值比较 - -## 建议推进顺序 - -1. M2(先夯实约束与元信息基础) -2. M4 前半:`algorithms::traits` / `common_traits` / 排序能力查询 -3. M3(让 conversion 改为依赖 algorithms 元信息) -4. M4 后半:`max` / `min` / `clamp` / `compare` -5. M1(建立跨语言边界,可按需求并行推进) - -## 总体完成跟踪 - -- [ ] M1 完成 -- [ ] M2 完成 -- [ ] M3 完成 -- [ ] M4 完成 +# Primitives 下一步实现计划清单(2026-03-27) + +## 当前状态 + +- [ ] M1 完成:C API 互操作层(双向) +- [x] M2 完成:Concept/Traits 体系增强与元信息 API +- [x] M3 完成:显式转换层(任意策略组适用) +- [x] M4 完成:算法层(traits 先行,以 max/min 为起点) + +## 持续约束 + +- 先定义稳定 API 边界,再落地实现。 +- 每个能力都配套 `tests + examples + docs`。 +- 高风险转换默认禁止隐式触发,只允许显式 API。 +- 明确分层职责:`algorithms` 负责值域/排序/边界元信息与值算法;`conversion` 负责显式类型变换。 +- 明确依赖方向:`conversion` 可依赖 `algorithms`,`algorithms` 不反向依赖 `conversion`。 +- C ABI 只暴露稳定、可版本化的边界;不直接泄露模板、模块实现细节或未稳定的策略矩阵。 + +## M1. C API 互操作层(最后剩余部分) + +### M1-0. 范围冻结与接口裁剪 + +- [ ] 冻结 `M1 v1` 范围:仅支持 `int32_t` / `uint32_t` / `double` 三类基础值。 +- [ ] 冻结 `M1 v1` 能力面:仅提供 `add` / `sub` / `mul` / `div`、基础比较、显式转换、版本查询。 +- [ ] 明确第一版不纳入 ABI 的内容:`char` 系列、`long double`、自定义 underlying、完整策略组合、完整 operator 集。 +- [ ] 统一第一版语义映射为“显式调用 + checked 路径 + 错误码返回”,不允许异常跨越 C ABI。 +- [ ] 输出一份最小公共命名规范:`mcpplibs_primitives_{type}_{op}`。 + +### M1-1. 稳定 C ABI 与头文件 + +- [ ] 新增最小公共头文件:`include/mcpplibs/primitives/c_api.h`。 +- [ ] 定义导出宏:`MCPPLIBS_PRIMITIVES_C_API`、`MCPPLIBS_PRIMITIVES_EXTERN_C`。 +- [ ] 定义 C API 版本宏:`MCPPLIBS_PRIMITIVES_C_API_VERSION_MAJOR` / `MINOR` / `PATCH`。 +- [ ] 定义统一错误码枚举,至少覆盖: +- [ ] `ok` +- [ ] `invalid_argument` +- [ ] `overflow` +- [ ] `underflow` +- [ ] `divide_by_zero` +- [ ] `domain_error` +- [ ] `unsupported` +- [ ] `internal_error` +- [ ] 定义统一消息缓冲区协议:`char* message` + `size_t message_size`,支持空指针与零长度缓冲区。 +- [ ] 定义统一返回约定:函数返回错误码,业务结果通过 `out` 参数返回。 +- [ ] 提供版本查询函数与能力探测函数,确保后续 ABI 演进可协商。 + +### M1-2. C -> primitives 调用桥 + +- [ ] 在 `src/c_api/` 下建立实现目录。 +- [ ] 拆分实现文件,建议至少包含: +- [ ] `src/c_api/abi.cpp` +- [ ] `src/c_api/arithmetic.cpp` +- [ ] `src/c_api/compare.cpp` +- [ ] `src/c_api/conversion.cpp` +- [ ] 以公开模块能力为唯一实现入口:只调用 `mcpplibs.primitives` 已导出的 `types`、`operations`、`conversion`。 +- [ ] 为每个 ABI 入口补齐参数校验:`out == nullptr`、非法 buffer、除零、溢出、域错误。 +- [ ] 建立统一错误翻译层:将 `policy::error::kind` 与转换风险映射到 C 错误码。 +- [ ] 在 ABI 边界统一拦截异常并映射为 `internal_error`,禁止任何 C++ 异常穿透到 C 侧。 +- [ ] 保证所有导出函数不暴露 `std::expected`、模板实例、模块内部类型或 STL 容器布局。 + +### M1-3. primitives -> 外部 C API 适配桥 + +- [ ] 新增 C++ 适配层,建议文件: +- [ ] `src/c_api/adapter.cppm` +- [ ] `src/c_api/adapter.cpp` +- [ ] 用“函数表 + `void* context`”建模外部 C API,而不是散落裸函数指针。 +- [ ] 第一版只适配与 `M1 v1` 对称的能力:四则、比较、显式 cast。 +- [ ] 明确适配协议: +- [ ] 适配层不拥有 `context` +- [ ] 回调必须是 `noexcept` 语义约束 +- [ ] 返回码必须可映射到 `policy::error::kind` +- [ ] 外部 C API 回传值必须再经过 primitives 的范围与错误检查,不能绕开现有风险路径。 +- [ ] 为适配层建立最小公共抽象,避免未来直接把外部 C API 绑定死到具体函数签名。 + +### M1-4. 构建系统与安装集成 + +- [ ] 更新 `CMakeLists.txt`:将 `project(... LANGUAGES CXX)` 扩展为 `project(... LANGUAGES C CXX)`。 +- [ ] 为 C API 头文件添加安装与导出规则,确保 `include/mcpplibs/primitives/c_api.h` 进入安装产物。 +- [ ] 决定 C ABI 的产物形态: +- [ ] 方案 A:并入现有 `mcpplibs-primitives` 静态库 +- [ ] 方案 B:新增单独目标 `mcpplibs-primitives-capi` +- [ ] 更新 `xmake.lua`,确保 C 示例与 C 测试能参与构建。 +- [ ] 更新 `examples/CMakeLists.txt` 与 `examples/xmake.lua`,纳入 C 示例和 C++ 适配示例。 +- [ ] 更新 `tests/CMakeLists.txt`、`tests/basic/CMakeLists.txt`、`tests/xmake.lua`,纳入 C/C++ 混合验证目标。 + +### M1-5. 测试、示例与文档 + +- [ ] 新增纯 C 示例:`examples/c/basic.c`。 +- [ ] 新增 C++ 调用 C API 示例:`examples/cpp/use_c_api.cpp`。 +- [ ] 新增纯 C smoke test,验证: +- [ ] 头文件可被 C 编译器独立包含 +- [ ] C 目标可链接库产物 +- [ ] `int32 add`、`double div` 成功路径可运行 +- [ ] 除零或溢出错误路径可观测 +- [ ] 新增 C++ 适配层测试,验证: +- [ ] 外部 C API 成功路径映射正确 +- [ ] 错误码映射正确 +- [ ] 空指针/非法参数会被拒绝 +- [ ] 回调异常或非法返回不会引入未定义行为 +- [ ] 新增 ABI 边界测试,覆盖消息 buffer 截断、空 buffer、空 `out` 参数、版本查询。 +- [ ] 更新 `README.md` / `README.zh.md`,补充 C API 简介、边界约束与示例入口。 +- [ ] 更新 `docs/api/en` / `docs/api/zh`,补充错误模型、版本策略和双向互操作说明。 + +### M1-6. 收口与验收 + +- [ ] 纯 C 工程可独立包含 `c_api.h`、成功链接并调用基础能力。 +- [ ] C API 成功路径、错误路径、异常隔离路径全部可回归测试。 +- [ ] C++ 对外部 C API 的适配调用行为可控、无未定义行为。 +- [ ] ABI 命名、导出宏、版本查询、错误码模型在文档中有明确承诺。 +- [ ] `M1 v1` 中未纳入 ABI 的能力在文档中明确标注为“未稳定/不承诺”。 + +## 建议推进顺序(按 PR / 工作包) + +1. `M1-0 + M1-1`:先冻结第一版范围,并提交 `c_api.h` 与 ABI 契约。 +2. `M1-2`:实现 C 调用 primitives 的最小闭环,先跑通 `int32_t` 和 `double`。 +3. `M1-4`:补齐 CMake/xmake/安装规则,让 C 目标进入正式构建链路。 +4. `M1-5`:补齐 `examples/c/basic.c`、`examples/cpp/use_c_api.cpp` 和混合测试。 +5. `M1-3`:实现 primitives 对外部 C API 的适配桥,并补齐适配测试。 +6. `M1-6`:统一收口文档、版本策略与验收项,准备关闭 M1。 + +## 已完成里程碑归档 + +- [x] M2 已完成,后续不再作为阻塞项跟踪。 +- [x] M3 已完成,后续仅在 M1 适配中复用已有显式转换能力。 +- [x] M4 已完成,后续仅在 M1 实现中复用已有算法层与 traits 元信息。 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3439b31..8991541 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -project(mcpplibs-primitives VERSION 0.3.0 LANGUAGES CXX) +project(mcpplibs-primitives VERSION 0.4.0 LANGUAGES CXX) find_package(Threads REQUIRED) diff --git a/README.md b/README.md index efedd65..f5fcab9 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ | [中文](README.zh.md) - [English](README.md) - [Forum](https://mcpp.d2learn.org/forum) | |---------------------------------------------------------------------------------| | [用户文档](docs/guide/zh/README.md) - [User Documentation](docs/guide/en/README.md) | -| [API文档](docs/guide/api/README.md) - [API Documentation](docs/api/en/README.md) | +| [API文档](docs/api/zh/README.md) - [API Documentation](docs/api/en/README.md) | This repository provides configurable `primitive` infrastructure (`underlying traits`, `policy`, and `operations/dispatcher`) to unify numeric behavior, error handling, and concurrency access semantics. @@ -98,14 +98,16 @@ Default policies are available under `policy::defaults`: ## Examples -- `ex01_default_arithmetic`: Basic arithmetic under default policies. +- `ex01_basic_usage`: Literals + primitive factory helpers with the built-in operator set. - `ex02_type_policy`: Type negotiation with `strict/compatible`, including how type policy affects construction from `underlying`. - `ex03_value_policy`: `checked/unchecked/saturating` behavior, including mixed binary operations with `underlying`. - `ex04_error_policy`: Error-handling behavior across different error policies. - `ex05_concurrency_policy`: Representative mixed read/write concurrency workload (writer `store` + reader `add/sub` + `CAS`). -- `ex06_custom_underlying`: Custom underlying traits, rep validation, and common-rep extension. -- `ex07_custom_policy`: Custom policy protocol implementation. -- `ex08_custom_operation`: Custom operation extension. +- `ex06_conversion`: Checked/saturating/truncating/exact conversion helpers across underlying values and primitives. +- `ex07_algorithms`: Limits metadata, special numeric values, and hashing helpers. +- `ex08_custom_underlying`: Custom underlying traits, rep validation, and common-rep extension. +- `ex09_custom_policy`: Custom policy protocol implementation. +- `ex10_custom_operation`: Custom operation extension. ## Project Layout @@ -117,7 +119,7 @@ mcpplibs-primitives/ │ ├── policy/ # policy tags and protocol implementations │ ├── operations/ # operation tags / dispatcher / operators │ └── underlying/ # underlying traits and common_rep -├── examples/ # ex01 ~ ex08 examples +├── examples/ # example programs ├── tests/ # test entry and basic test suite ├── xmake.lua # xmake build script ├── CMakeLists.txt # CMake build script @@ -151,17 +153,22 @@ xlings install ```bash xmake build mcpplibs-primitives -xmake run basic # equivalent to ex01_default_arithmetic +xmake run basic # compatibility alias for ex01_basic_usage +xmake run ex01_basic_usage +xmake run ex06_conversion +xmake run ex07_algorithms xmake run ex05_concurrency_policy xmake run primitives_test ``` -**Using CMake** +**Using CMake** (`CMake >= 3.31`) ```bash cmake -B build -G Ninja cmake --build build --target mcpplibs-primitives -cmake --build build --target ex01_default_arithmetic +cmake --build build --target ex01_basic_usage +cmake --build build --target ex06_conversion +cmake --build build --target ex07_algorithms cmake --build build --target basic_tests ctest --test-dir build --output-on-failure ``` diff --git a/README.zh.md b/README.zh.md index 1f10f6a..359af58 100644 --- a/README.zh.md +++ b/README.zh.md @@ -1,6 +1,6 @@ # mcpplibs primitives -> C++23 模块化原语库 - `import mcpplibs.primitives;` +> C++23 模块化 primitives 库 - `import mcpplibs.primitives;` [![d2x](https://img.shields.io/badge/d2x-ok-green.svg)](https://github.com/d2learn/d2x) [![Online-ebook](https://img.shields.io/badge/online-ebook-orange.svg)](https://github.com/d2learn/d2x) @@ -8,29 +8,29 @@ | [中文](README.zh.md) - [English](README.md) - [论坛](https://mcpp.d2learn.org/forum) | |----------------------------------------------------------------------------------| -| [用户文档](docs/guide/zh/README.md) - [User Documentation](docs/guide/en/README.md) | -| [API文档](docs/guide/api/README.md) - [API Documentation](docs/api/en/README.md) | +| [用户文档](docs/guide/zh/README.md) - [User Documentation](docs/guide/en/README.md) | +| [API文档](docs/api/zh/README.md) - [API Documentation](docs/api/en/README.md) | -本仓库提供可配置的 `primitive` 基础设施(`underlying traits`、`policy`、`operations/dispatcher`),用于统一约束数值计算、错误处理与并发访问语义。 +本仓库提供可配置的 `primitive` 基础设施(`underlying traits`、`policy`、`operations/dispatcher`),用于统一数值行为、错误处理与并发访问语义。 > [!WARNING] -> 当前项目仍在快速演进中,API 可能发生变更。 +> 项目仍在快速演进中,API 可能继续调整。 ## 特性 -- **C++23 模块** — `import mcpplibs.primitives;` -- **双构建系统** — 同时支持 xmake 和 CMake -- **策略驱动行为** — 值/类型/错误/并发策略可组合配置 -- **混合运算支持** — 支持 `primitive` 与 `underlying` 的混合二元运算 -- **并发访问接口** — `primitive::load/store/compare_exchange` +- **C++23 模块**: `import mcpplibs.primitives;` +- **双构建系统**: 同时支持 xmake 和 CMake +- **策略驱动行为**: value/type/error/concurrency 策略可组合配置 +- **混合运算支持**: 支持 `primitive` 与 `underlying` 的二元运算 +- **并发访问接口**: `primitive::load/store/compare_exchange` ## Operators -该库为 `primitive` 提供了常见的一元、算术、位运算与比较操作。 -算术结果通过统一分发链路返回 `std::expected<..., policy::error::kind>`。 +该库为 `primitive` 提供常见的一元、算术、位运算和比较操作。 +算术路径通过统一分发链路返回 `std::expected<..., policy::error::kind>`。 -- 值策略(`policy::value::checked` / `policy::value::saturating` / `policy::value::unchecked`)决定溢出行为; -- 错误策略(`policy::error::throwing` / `policy::error::expected` / `policy::error::terminate`)决定错误传播方式。 +- 值策略(`policy::value::checked` / `policy::value::saturating` / `policy::value::unchecked`)定义溢出行为。 +- 错误策略(`policy::error::throwing` / `policy::error::expected` / `policy::error::terminate`)定义错误传播方式。 示例: @@ -53,24 +53,24 @@ auto maybe_overflow = ## Policy 协议命名空间 -自定义 policy 时,协议入口按职责拆分到子命名空间: +实现自定义 policy 时,协议入口按职责拆分为以下命名空间: - `policy::type::handler` / `policy::type::handler_available` - `policy::concurrency::handler` / `policy::concurrency::injection` - `policy::value::handler` / `policy::value::decision` - `policy::error::handler` / `policy::error::request` / `policy::error::kind` -预设 policy 标签: +内置 policy 标签: - `policy::value::{checked, unchecked, saturating}` - `policy::type::{strict, compatible, transparent}` - `policy::error::{throwing, expected, terminate}` - `policy::concurrency::{none, fenced, fenced_relaxed, fenced_acq_rel, fenced_seq_cst}` -并发策略说明: +并发说明: -- `fenced*` 系列是操作级并发语义,通过策略注入内存序 fence; -- `primitive` 存储仍保持统一、零额外存储抽象; +- `fenced*` 系列提供操作级并发语义,并通过策略注入内存序 fence。 +- `primitive` 存储保持统一的零额外存储抽象。 - `primitive::load/store/compare_exchange` 由并发策略协议提供,若策略未实现会在编译期报错。 示例(并发访问 API): @@ -98,14 +98,16 @@ if (v.compare_exchange(expected, 3)) { ## 示例程序 -- `ex01_default_arithmetic`: 默认策略下的基础算术运算示例。 -- `ex02_type_policy`: 展示 `strict/compatible` 的类型协商差异,并包含 `underlying` 构造路径对 type 策略的影响。 -- `ex03_value_policy`: 展示 `checked/unchecked/saturating`,并包含与 `underlying` 的混合二元运算行为。 -- `ex04_error_policy`: 展示不同 error 策略的处理方式。 -- `ex05_concurrency_policy`: 读写组合并发场景(writer `store` + reader `add/sub` + `CAS`)示例。 -- `ex06_custom_underlying`: 自定义 underlying traits、rep 校验与 common rep 扩展。 -- `ex07_custom_policy`: 自定义策略协议实现示例。 -- `ex08_custom_operation`: 自定义 operation 扩展示例。 +- `ex01_basic_usage`: 展示 literal 与 primitive 工厂函数联合使用,并覆盖更多内置操作符。 +- `ex02_type_policy`: 展示 `strict/compatible` 的类型协商差异,以及 `underlying` 构造对 type 策略的影响。 +- `ex03_value_policy`: 展示 `checked/unchecked/saturating` 行为,以及与 `underlying` 的混合二元运算。 +- `ex04_error_policy`: 展示不同 error 策略下的错误处理方式。 +- `ex05_concurrency_policy`: 展示典型的读写混合并发场景(writer `store` + reader `add/sub` + `CAS`)。 +- `ex06_conversion`: 展示 underlying 与 primitive 之间的 `checked/saturating/truncating/exact` 转换辅助接口。 +- `ex07_algorithms`: 展示 limits 元信息、特殊数值和哈希辅助接口。 +- `ex08_custom_underlying`: 展示自定义 underlying traits、rep 校验和 common rep 扩展。 +- `ex09_custom_policy`: 展示自定义 policy 协议实现。 +- `ex10_custom_operation`: 展示自定义 operation 扩展。 ## 项目结构 @@ -117,8 +119,8 @@ mcpplibs-primitives/ │ ├── policy/ # policy 标签与协议实现 │ ├── operations/ # operation tags / dispatcher / operators │ └── underlying/ # underlying traits 与 common_rep -├── examples/ # ex01 ~ ex08 示例 -├── tests/ # 测试入口与 basic 测试集 +├── examples/ # 示例程序 +├── tests/ # 测试入口与基础测试集 ├── xmake.lua # xmake 构建脚本 ├── CMakeLists.txt # CMake 构建脚本 └── .xlings.json # xlings 包描述文件 @@ -151,17 +153,22 @@ xlings install ```bash xmake build mcpplibs-primitives -xmake run basic # 等价于 ex01_default_arithmetic +xmake run basic # ex01_basic_usage 的兼容别名 +xmake run ex01_basic_usage +xmake run ex06_conversion +xmake run ex07_algorithms xmake run ex05_concurrency_policy xmake run primitives_test ``` -**使用 CMake** +**使用 CMake**(`CMake >= 3.31`) ```bash cmake -B build -G Ninja cmake --build build --target mcpplibs-primitives -cmake --build build --target ex01_default_arithmetic +cmake --build build --target ex01_basic_usage +cmake --build build --target ex06_conversion +cmake --build build --target ex07_algorithms cmake --build build --target basic_tests ctest --test-dir build --output-on-failure ``` @@ -185,8 +192,8 @@ target("myapp") ## 相关链接 -- [mcpp-style-ref | 现代 C++ 编码/项目风格参考](https://github.com/mcpp-community/mcpp-style-ref) -- [d2mystl | 从零实现一个迷你STL库](https://github.com/mcpp-community/d2mystl) -- [mcpp 社区官网](https://mcpp.d2learn.org) -- [mcpp | 现代 C++ 爱好者论坛](https://mcpp.d2learn.org/forum) -- [入门教程: 动手学现代 C++](https://github.com/Sunrisepeak/mcpp-standard) +- [mcpp-style-ref | 现代 C++ 编码与项目风格参考](https://github.com/mcpp-community/mcpp-style-ref) +- [d2mystl | 从零实现一个迷你 STL](https://github.com/mcpp-community/d2mystl) +- [mcpp 社区网站](https://mcpp.d2learn.org) +- [mcpp 论坛](https://mcpp.d2learn.org/forum) +- [入门教程:动手学习现代 C++](https://github.com/Sunrisepeak/mcpp-standard) diff --git a/docs/api/en/README.md b/docs/api/en/README.md index 345e74b..9f51ca0 100644 --- a/docs/api/en/README.md +++ b/docs/api/en/README.md @@ -13,9 +13,12 @@ import mcpplibs.primitives; This module exports: - `mcpplibs.primitives.underlying` +- `mcpplibs.primitives.literals` - `mcpplibs.primitives.policy` - `mcpplibs.primitives.primitive` - `mcpplibs.primitives.operations` +- `mcpplibs.primitives.algorithms` +- `mcpplibs.primitives.conversion` ## Namespace Overview @@ -23,7 +26,10 @@ This module exports: - `mcpplibs::primitives::underlying`: underlying traits and categories. - `mcpplibs::primitives::policy`: policy tags, defaults, and protocols. - `mcpplibs::primitives::operations`: functional dispatch API. +- `mcpplibs::primitives::conversion`: numeric risk checks and cast helpers. +- `mcpplibs::primitives::algorithms`: limits and hash helpers. - `mcpplibs::primitives::operators`: operator overload entry. +- `mcpplibs::primitives::literals`: checked underlying literal suffixes. - `mcpplibs::primitives::meta`: primitive metadata traits. - `mcpplibs::primitives::types`: convenience aliases for common underlying types. @@ -96,7 +102,7 @@ Notes: ### Convenience aliases (`types`) -- Integers: `U8/U16/U32/U64`, `I8/I16/I32/I64` +- Integers: `U8/U16/U32/U64`, `Size`, `Diff`, `I8/I16/I32/I64` - Floating-point: `F32/F64/F80` - Bool/chars: `Bool/UChar/Char8/Char16/Char32/WChar` @@ -108,6 +114,28 @@ using value_t = mcpplibs::primitives::types::I32< mcpplibs::primitives::policy::error::expected>; ``` +### Factory helpers and literals + +- `with(value)` builds a `primitive` with default policies from an underlying value. +- `with(value)` applies an explicit policy set during construction. +- `with(policies_tuple, value)` reuses an existing policies tuple. +- `mcpplibs::primitives::literals` provides checked suffixes such as + `_u8/_u16/_u32/_u64/_size/_diff`, `_i8/_i16/_i32/_i64`, + `_f32/_f32e/_f64/_f64e/_f80/_f80e`, and character suffixes + `_uchar/_char8/_char16/_char32/_wchar`. + +Example: + +```cpp +import mcpplibs.primitives; +import mcpplibs.primitives.literals; + +using namespace mcpplibs::primitives; +using namespace mcpplibs::primitives::literals; + +auto value = with(42_i32); +``` + ## `operations` API The `operations` namespace provides function-style APIs with unified `std::expected` results. @@ -172,6 +200,58 @@ using namespace mcpplibs::primitives::operators; Operator results are still `std::expected<...>`, not raw values. +## `conversion` API + +The `conversion` namespace provides reusable casts for underlying values, +primitives, and mixed source/destination pairs. + +### Common result aliases and risk model + +- `cast_result = std::expected` +- `conversion::risk::kind`: + `none`, `overflow`, `underflow`, `domain_error`, `precision_loss`, + `sign_loss`, `invalid_type_combination` + +### Conversion helpers + +- `numeric_risk(value)` +- `unchecked_cast(value)` +- `checked_cast(value)` +- `saturating_cast(value)` +- `truncating_cast(value)` +- `exact_cast(value)` + +Notes: + +- `checked_cast` and `exact_cast` return `cast_result`. +- `saturating_cast` clamps overflow/underflow for numeric destinations. +- `truncating_cast` is useful for floating-to-integral conversions. +- Overloads exist for underlying -> underlying, primitive -> primitive, + primitive -> underlying, and underlying -> primitive paths. + +## `algorithms` API + +The `algorithms` namespace provides reusable limits metadata and hashing helpers +for built-in and supported custom underlyings. + +### Limits + +- `limits` +- `limited_type` +- `min_value()` +- `lowest_value()` +- `max_value()` +- `epsilon_value()` +- `infinity_value()` +- `quiet_nan_value()` + +### Hashing + +- `hash` +- `hash_result_t` +- `hashable` +- `hash_value(value)` + ## policy API ### Built-in policy tags diff --git a/docs/api/zh/README.md b/docs/api/zh/README.md index 515b625..8ea9fcf 100644 --- a/docs/api/zh/README.md +++ b/docs/api/zh/README.md @@ -1,35 +1,41 @@ # primitives API 文档 -> 适用模块:`import mcpplibs.primitives;` +> 模块入口:`import mcpplibs.primitives;` ## 模块入口 -顶层模块: +顶层导入: ```cpp import mcpplibs.primitives; ``` -该模块导出以下子模块: +该模块会导出以下子模块: - `mcpplibs.primitives.underlying` +- `mcpplibs.primitives.literals` - `mcpplibs.primitives.policy` - `mcpplibs.primitives.primitive` - `mcpplibs.primitives.operations` +- `mcpplibs.primitives.algorithms` +- `mcpplibs.primitives.conversion` ## 命名空间总览 -- `mcpplibs::primitives`: 核心类型、概念与 `primitive`。 -- `mcpplibs::primitives::underlying`: underlying traits 与类别。 -- `mcpplibs::primitives::policy`: policy 标签、默认值与协议。 -- `mcpplibs::primitives::operations`: 分发函数 API。 -- `mcpplibs::primitives::operators`: 运算符重载入口。 -- `mcpplibs::primitives::meta`: primitive 元信息 traits。 -- `mcpplibs::primitives::types`: 常用 underlying 的 primitive 别名。 +- `mcpplibs::primitives`:核心类型、概念与 `primitive`。 +- `mcpplibs::primitives::underlying`:underlying traits 与分类信息。 +- `mcpplibs::primitives::policy`:policy 标签、默认值与协议。 +- `mcpplibs::primitives::operations`:函数式分发 API。 +- `mcpplibs::primitives::conversion`:数值风险检查与转换辅助接口。 +- `mcpplibs::primitives::algorithms`:limits 与 hash 辅助接口。 +- `mcpplibs::primitives::operators`:运算符重载入口。 +- `mcpplibs::primitives::literals`:带校验的 underlying 字面量后缀。 +- `mcpplibs::primitives::meta`:primitive 元信息 traits。 +- `mcpplibs::primitives::types`:常用 underlying 对应的 primitive 别名。 ## 核心概念与元信息 -### underlying 相关概念 +### underlying 概念 - `underlying_type` - `boolean_underlying_type` @@ -40,7 +46,7 @@ import mcpplibs.primitives; - `has_common_rep` - `common_rep_t` -### policy 相关概念 +### policy 概念 - `policy::policy_type

` - `policy::value_policy

` @@ -51,7 +57,7 @@ import mcpplibs.primitives; ### primitive 元信息 -- `meta::traits>` +- `meta::traits>` 暴露 `value_type / policies / value_policy / type_policy / error_policy / concurrency_policy` - `meta::make_primitive_t` @@ -67,12 +73,12 @@ class primitive; - `value_type = T` - `policies = std::tuple` -### 主要构造与赋值 +### 构造与赋值 - `explicit primitive(T)`:同 underlying 构造。 -- `explicit primitive(U)`:跨 underlying 构造(是否允许由 type 策略决定)。 -- 支持同策略组下的拷贝/移动构造与赋值。 -- 支持同策略组、不同 underlying 的 primitive 互构造/赋值(受 type 策略约束)。 +- `explicit primitive(U)`:跨 underlying 构造,是否允许由 type policy 决定。 +- 支持同一 policy 集合下的拷贝/移动构造与赋值。 +- 当 type policy 允许时,支持跨 underlying primitive 的构造与赋值。 ### 值访问与并发访问 API @@ -84,23 +90,23 @@ class primitive; 说明: -- `store/compare_exchange` 支持同 underlying。 -- 在 type 策略允许时,`store/compare_exchange` 也支持跨 underlying 参数。 -- 并发访问能力由 `policy::concurrency::handler<..., void, ...>` 提供。 +- `store/compare_exchange` 始终支持同 underlying 类型。 +- 只有在 type policy 允许时,`store/compare_exchange` 才支持跨 underlying 参数。 +- 访问 API 由 `policy::concurrency::handler<..., void, ...>` 提供。 -### type 策略对跨 underlying 行为的影响 +### type policy 对跨 underlying 行为的影响 -- `policy::type::strict`:仅同类型允许,跨 underlying 构造/存储/CAS 不可用。 -- `policy::type::compatible`:要求同 underlying category 且可协商 `common_rep`。 -- `policy::type::transparent`:只要求可协商 `common_rep`。 +- `policy::type::strict`:只允许完全相同的类型。 +- `policy::type::compatible`:要求 underlying category 相同且存在有效的 `common_rep`。 +- `policy::type::transparent`:只要求存在有效的 `common_rep`。 -### 预定义别名(`types`) +### 便捷别名(`types`) -- 整型:`U8/U16/U32/U64`、`I8/I16/I32/I64` +- 整型:`U8/U16/U32/U64`、`Size`、`Diff`、`I8/I16/I32/I64` - 浮点:`F32/F64/F80` - 布尔/字符:`Bool/UChar/Char8/Char16/Char32/WChar` -用法示例: +示例: ```cpp using value_t = mcpplibs::primitives::types::I32< @@ -108,6 +114,28 @@ using value_t = mcpplibs::primitives::types::I32< mcpplibs::primitives::policy::error::expected>; ``` +### 工厂函数与 literals + +- `with(value)`:从 underlying 值按默认 policy 构造 `primitive`。 +- `with(value)`:构造时显式指定 policy 集合。 +- `with(policies_tuple, value)`:复用已有的 policy tuple。 +- `mcpplibs::primitives::literals` 提供带校验的后缀,例如 + `_u8/_u16/_u32/_u64/_size/_diff`、`_i8/_i16/_i32/_i64`、 + `_f32/_f32e/_f64/_f64e/_f80/_f80e`,以及字符后缀 + `_uchar/_char8/_char16/_char32/_wchar`。 + +示例: + +```cpp +import mcpplibs.primitives; +import mcpplibs.primitives.literals; + +using namespace mcpplibs::primitives; +using namespace mcpplibs::primitives::literals; + +auto value = with(42_i32); +``` + ## `operations` API `operations` 命名空间提供函数式调用接口,统一返回 `std::expected`。 @@ -156,39 +184,88 @@ using value_t = mcpplibs::primitives::types::I32< ### 混合操作支持 -对多数二元操作,支持以下三种形式: +大多数二元操作支持: - `primitive op primitive` - `primitive op underlying` - `underlying op primitive` -## `operators` 运算符重载 +## `operators` 重载 -若需要 `+ - * / % ...` 运算符语法,请引入: +如果要使用 `+ - * / % ...` 语法,请引入: ```cpp using namespace mcpplibs::primitives::operators; ``` -重载结果同样是 `std::expected<...>`,不是裸值。 +运算符结果依然是 `std::expected<...>`,不是裸值。 + +## `conversion` API + +`conversion` 命名空间提供 underlying、primitive 以及混合源/目标之间的统一转换接口。 + +### 常用结果类型与风险模型 + +- `cast_result = std::expected` +- `conversion::risk::kind`: + `none`、`overflow`、`underflow`、`domain_error`、`precision_loss`、 + `sign_loss`、`invalid_type_combination` + +### 转换函数 + +- `numeric_risk(value)` +- `unchecked_cast(value)` +- `checked_cast(value)` +- `saturating_cast(value)` +- `truncating_cast(value)` +- `exact_cast(value)` + +说明: + +- `checked_cast` 和 `exact_cast` 返回 `cast_result`。 +- `saturating_cast` 会在溢出/下溢时执行钳制。 +- `truncating_cast` 适合浮点到整数的截断场景。 +- 提供 underlying -> underlying、primitive -> primitive、primitive -> underlying、underlying -> primitive 四类重载。 + +## `algorithms` API + +`algorithms` 命名空间提供 limits 元信息和 hash 辅助接口,适用于内建类型和受支持的自定义 underlying。 + +### Limits + +- `limits` +- `limited_type` +- `min_value()` +- `lowest_value()` +- `max_value()` +- `epsilon_value()` +- `infinity_value()` +- `quiet_nan_value()` + +### Hash + +- `hash` +- `hash_result_t` +- `hashable` +- `hash_value(value)` ## policy API -### 内置策略标签 +### 内建 policy 标签 - 值策略:`policy::value::{checked, unchecked, saturating}` - 类型策略:`policy::type::{strict, compatible, transparent}` - 错误策略:`policy::error::{throwing, expected, terminate}` - 并发策略:`policy::concurrency::{none, fenced, fenced_relaxed, fenced_acq_rel, fenced_seq_cst}` -### 默认策略 +### 默认值 - `policy::defaults::value = policy::value::checked` - `policy::defaults::type = policy::type::strict` - `policy::defaults::error = policy::error::throwing` - `policy::defaults::concurrency = policy::concurrency::none` -### 错误码 +### 错误种类 `policy::error::kind`: @@ -204,7 +281,7 @@ using namespace mcpplibs::primitives::operators; ### 1) 注册 `underlying::traits` -需要提供: +必须提供: - `value_type` - `rep_type` @@ -214,15 +291,15 @@ using namespace mcpplibs::primitives::operators; - `from_rep(rep)` - `is_valid_rep(rep)` -### 2) 自定义 common rep 协商 +### 2) 自定义 common-rep 协商 -可特化 `underlying::common_rep_traits`,以覆盖默认 `std::common_type_t` 规则。 +可以特化 `underlying::common_rep_traits`,覆盖默认的 `std::common_type_t` 行为。 -## 返回模型与错误处理模型 +## 返回值与错误模型 -- 绝大多数 operations/operators API 返回 `std::expected<...>`。 -- 当错误策略为 `policy::error::expected` 时,错误通过 `unexpected(policy::error::kind)` 返回。 -- 当错误策略为 `policy::error::throwing` 时,运行期错误会抛出异常(签名仍保持 `std::expected`)。 +- 大多数 operations/operators API 返回 `std::expected<...>`。 +- 使用 `policy::error::expected` 时,失败通过 `unexpected(policy::error::kind)` 返回。 +- 使用 `policy::error::throwing` 时,运行期失败会抛出异常,而 API 签名仍保持 `std::expected`。 ## 最小示例 diff --git a/docs/guide/en/extension.md b/docs/guide/en/extension.md index 2706bac..15303cf 100644 --- a/docs/guide/en/extension.md +++ b/docs/guide/en/extension.md @@ -18,7 +18,7 @@ Required members: After registration, your type can be used as `primitive` if it satisfies `underlying_type`. -Reference example: `examples/ex06_custom_underlying.cpp`. +Reference example: `examples/ex08_custom_underlying.cpp`. ## 2) Custom Common Rep Negotiation @@ -47,7 +47,7 @@ Custom policies require: If your value policy needs operation runtime behavior, also provide `operations::runtime::op_binding` specializations. -Reference example: `examples/ex07_custom_policy.cpp`. +Reference example: `examples/ex09_custom_policy.cpp`. ## 4) Custom Operation Tags @@ -61,7 +61,7 @@ To add new operation tags: 3. Provide `operations::runtime::op_binding`. 4. Invoke via `operations::apply(lhs, rhs)`. -Reference example: `examples/ex08_custom_operation.cpp`. +Reference example: `examples/ex10_custom_operation.cpp`. ## Extension Checklist diff --git a/docs/guide/en/installation-and-build.md b/docs/guide/en/installation-and-build.md index a3090b9..88f0b66 100644 --- a/docs/guide/en/installation-and-build.md +++ b/docs/guide/en/installation-and-build.md @@ -8,7 +8,7 @@ - MSVC >= 19.34 (MSVC version >= 1934) - Build tools - xmake (recommended) - - or CMake + Ninja + - or CMake >= 3.31 + Ninja ## Build with xmake @@ -21,7 +21,7 @@ xmake build mcpplibs-primitives Run an example: ```bash -xmake run ex01_default_arithmetic +xmake run ex01_basic_usage ``` Run tests: @@ -36,7 +36,7 @@ Compatibility alias: xmake run basic ``` -`basic` runs `ex01_default_arithmetic`. +`basic` runs `ex01_basic_usage`. ## Build with CMake @@ -50,7 +50,9 @@ cmake --build build --target mcpplibs-primitives Build an example and tests: ```bash -cmake --build build --target ex01_default_arithmetic +cmake --build build --target ex01_basic_usage +cmake --build build --target ex06_conversion +cmake --build build --target ex07_algorithms cmake --build build --target basic_tests ctest --test-dir build --output-on-failure ``` @@ -59,14 +61,16 @@ ctest --test-dir build --output-on-failure Examples are available as independent targets: -- `ex01_default_arithmetic` +- `ex01_basic_usage` - `ex02_type_policy` - `ex03_value_policy` - `ex04_error_policy` - `ex05_concurrency_policy` -- `ex06_custom_underlying` -- `ex07_custom_policy` -- `ex08_custom_operation` +- `ex06_conversion` +- `ex07_algorithms` +- `ex08_custom_underlying` +- `ex09_custom_policy` +- `ex10_custom_operation` ## Common Build Issues diff --git a/docs/guide/en/quick-start.md b/docs/guide/en/quick-start.md index 15dff70..55a0c59 100644 --- a/docs/guide/en/quick-start.md +++ b/docs/guide/en/quick-start.md @@ -38,14 +38,16 @@ This gives safe arithmetic and explicit error handling without requiring excepti Run examples in this order: -1. `ex01_default_arithmetic` +1. `ex01_basic_usage` 2. `ex02_type_policy` 3. `ex03_value_policy` 4. `ex04_error_policy` 5. `ex05_concurrency_policy` -6. `ex06_custom_underlying` -7. `ex07_custom_policy` -8. `ex08_custom_operation` +6. `ex06_conversion` +7. `ex07_algorithms` +8. `ex08_custom_underlying` +9. `ex09_custom_policy` +10. `ex10_custom_operation` Command: diff --git a/docs/guide/zh/README.md b/docs/guide/zh/README.md index 27b3d81..c71159b 100644 --- a/docs/guide/zh/README.md +++ b/docs/guide/zh/README.md @@ -1,6 +1,6 @@ -# primitives 用户文档(中文) +# primitives 用户指南(中文) -本节按使用流程组织。建议先看安装构建,再看快速上手。 +本节按使用流程组织。建议先看安装与构建,再看快速上手。 ## 阅读顺序 @@ -11,5 +11,5 @@ ## 相关文档 -- API 参考: [../../api/zh/README.md](../../api/zh/README.md) -- 文档总入口: [../../README.md](../../README.md) +- API 参考: [../../api/zh/README.md](../../api/zh/README.md) +- 文档总入口: [../../README.md](../../README.md) diff --git a/docs/guide/zh/extension.md b/docs/guide/zh/extension.md index 3bbd723..634aaf7 100644 --- a/docs/guide/zh/extension.md +++ b/docs/guide/zh/extension.md @@ -18,7 +18,7 @@ 完成后,只要满足 `underlying_type`,即可用于 `primitive`。 -参考:`examples/ex06_custom_underlying.cpp` +参考:`examples/ex08_custom_underlying.cpp` ## 2) 自定义 common rep 协商 @@ -47,7 +47,7 @@ struct mcpplibs::primitives::underlying::common_rep_traits { 如果 value policy 需要参与运行期运算逻辑,还要补充 `operations::runtime::op_binding` 特化。 -参考:`examples/ex07_custom_policy.cpp` +参考:`examples/ex09_custom_policy.cpp` ## 4) 自定义 operation 标签 @@ -61,7 +61,7 @@ struct mcpplibs::primitives::underlying::common_rep_traits { 3. 提供 `operations::runtime::op_binding`。 4. 通过 `operations::apply(lhs, rhs)` 调用。 -参考:`examples/ex08_custom_operation.cpp` +参考:`examples/ex10_custom_operation.cpp` ## 扩展检查清单 diff --git a/docs/guide/zh/installation-and-build.md b/docs/guide/zh/installation-and-build.md index e660e4f..45f70b7 100644 --- a/docs/guide/zh/installation-and-build.md +++ b/docs/guide/zh/installation-and-build.md @@ -8,7 +8,7 @@ - MSVC >= 19.34(MSVC 版本号 >= 1934) - 构建工具 - 推荐:xmake - - 或:CMake + Ninja + - 或:CMake >= 3.31 + Ninja ## 使用 xmake 构建 @@ -21,7 +21,7 @@ xmake build mcpplibs-primitives 运行示例: ```bash -xmake run ex01_default_arithmetic +xmake run ex01_basic_usage ``` 运行测试: @@ -36,7 +36,7 @@ xmake run primitives_test xmake run basic ``` -`basic` 对应 `ex01_default_arithmetic`。 +`basic` 对应 `ex01_basic_usage`。 ## 使用 CMake 构建 @@ -50,7 +50,9 @@ cmake --build build --target mcpplibs-primitives 构建示例与测试: ```bash -cmake --build build --target ex01_default_arithmetic +cmake --build build --target ex01_basic_usage +cmake --build build --target ex06_conversion +cmake --build build --target ex07_algorithms cmake --build build --target basic_tests ctest --test-dir build --output-on-failure ``` @@ -59,14 +61,16 @@ ctest --test-dir build --output-on-failure 可独立构建/运行的示例目标: -- `ex01_default_arithmetic` +- `ex01_basic_usage` - `ex02_type_policy` - `ex03_value_policy` - `ex04_error_policy` - `ex05_concurrency_policy` -- `ex06_custom_underlying` -- `ex07_custom_policy` -- `ex08_custom_operation` +- `ex06_conversion` +- `ex07_algorithms` +- `ex08_custom_underlying` +- `ex09_custom_policy` +- `ex10_custom_operation` ## 常见构建问题 diff --git a/docs/guide/zh/quick-start.md b/docs/guide/zh/quick-start.md index 109e7ac..baace21 100644 --- a/docs/guide/zh/quick-start.md +++ b/docs/guide/zh/quick-start.md @@ -38,14 +38,16 @@ int main() { 建议按以下顺序运行示例: -1. `ex01_default_arithmetic` +1. `ex01_basic_usage` 2. `ex02_type_policy` 3. `ex03_value_policy` 4. `ex04_error_policy` 5. `ex05_concurrency_policy` -6. `ex06_custom_underlying` -7. `ex07_custom_policy` -8. `ex08_custom_operation` +6. `ex06_conversion` +7. `ex07_algorithms` +8. `ex08_custom_underlying` +9. `ex09_custom_policy` +10. `ex10_custom_operation` 运行示例: diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b5b0ea1..690524f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,12 +1,14 @@ set(PRIMITIVES_EXAMPLE_SOURCES - ex01_default_arithmetic.cpp + ex01_basic_usage.cpp ex02_type_policy.cpp ex03_value_policy.cpp ex04_error_policy.cpp ex05_concurrency_policy.cpp - ex06_custom_underlying.cpp - ex07_custom_policy.cpp - ex08_custom_operation.cpp + ex06_conversion.cpp + ex07_algorithms.cpp + ex08_custom_underlying.cpp + ex09_custom_policy.cpp + ex10_custom_operation.cpp ) foreach(example_source IN LISTS PRIMITIVES_EXAMPLE_SOURCES) diff --git a/examples/ex01_basic_usage.cpp b/examples/ex01_basic_usage.cpp new file mode 100644 index 0000000..457cfe5 --- /dev/null +++ b/examples/ex01_basic_usage.cpp @@ -0,0 +1,71 @@ +/* + * Example: ex01_basic_usage + * + * Purpose: + * Combine checked literals, primitive factory helpers, and built-in framework + * operators in one compact end-to-end example. + * + * Expected results: + * - `with(...)` builds primitives directly from checked underlying literals. + * - Arithmetic, unary, bitwise, comparison, mixed, and compound operators all + * dispatch successfully. + * - The printed values match: sum=42, neg=-2, mod=2, shl=40, band=8, final=43. + * - Program exits with code 0; otherwise prints an error and exits non-zero. + */ + +#include + +import mcpplibs.primitives; + +using namespace mcpplibs::primitives; + +int main() { + using namespace mcpplibs::primitives::literals; + using namespace mcpplibs::primitives::operators; + + constexpr auto base = + with(40_i32); + constexpr auto step = + with(2_i32); + constexpr auto mask = + with(10_i32); + + constexpr auto sum = 2_i32 + base; + if constexpr (!sum.has_value()) { + std::cerr << "basic usage dispatch failed\n"; + return 1; + } + + constexpr auto neg = -step; + constexpr auto mod = *sum % 5_i32; + constexpr auto shl = mask << step; + constexpr auto band = base & 12_i32; + constexpr auto const eq = *sum == 42_i32; + constexpr auto const cmp = *sum <=> 41_i32; + + auto counter = + with(1_i32); + auto const pre_inc = ++counter; + constexpr auto bonus = + with(41_i32); + auto const add_assign = (counter += bonus); + + if (!pre_inc.has_value() || !add_assign.has_value()) { + std::cerr << "basic usage dispatch failed\n"; + return 1; + } + + if (pre_inc->value() != 2 || + add_assign->value() != 43 || counter.load() != 43) { + std::cerr << "basic usage produced unexpected values\n"; + return 1; + } + + std::cout << "sum=" << sum->value() << ", neg=" << neg->value() + << ", mod=" << mod->value() << ", shl=" << shl->value() + << ", band=" << band->value() << ", final=" << counter.load() + << '\n'; + + std::cout << "basic_usage demo passed\n"; + return 0; +} diff --git a/examples/ex01_default_arithmetic.cpp b/examples/ex01_default_arithmetic.cpp deleted file mode 100644 index 717d98e..0000000 --- a/examples/ex01_default_arithmetic.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Example: ex01_default_arithmetic - * - * Purpose: - * Demonstrate the default primitive aliases and operator pipeline for - * arithmetic operations without custom policy overrides. - * - * Expected results: - * - All four operations (+, -, *, /) succeed through dispatcher. - * - The printed values match: sum=42, diff=38, prod=80, quot=20. - * - Program exits with code 0; otherwise prints an error and exits non-zero. - */ - -#include -#include - -import mcpplibs.primitives; - -using namespace mcpplibs::primitives; - -int main() { - // Point 1: Use built-in primitive type aliases and framework operators. - using namespace mcpplibs::primitives::types; - using namespace mcpplibs::primitives::operators; - - using value_t = I32<>; - - // Prepare operands. - auto const a = value_t{40}; - auto const b = value_t{2}; - - // Run the four arithmetic operators routed through dispatcher. - auto const sum = a + b; - auto const diff = a - b; - auto const prod = a * b; - auto const quot = a / b; - - // Validate all dispatches succeeded. - if (!sum.has_value() || !diff.has_value() || !prod.has_value() || - !quot.has_value()) { - std::cerr << "default arithmetic failed\n"; - return 1; - } - - std::cout << "sum=" << sum->value() << ", diff=" << diff->value() - << ", prod=" << prod->value() << ", quot=" << quot->value() << '\n'; - return 0; -} diff --git a/examples/ex02_type_policy.cpp b/examples/ex02_type_policy.cpp index 4217c67..6c2eebb 100644 --- a/examples/ex02_type_policy.cpp +++ b/examples/ex02_type_policy.cpp @@ -54,8 +54,7 @@ int main() { operations::Addition, primitive, - compatible_i64, - policy::error::kind>; + compatible_i64>; static_assert( std::is_same_v); diff --git a/examples/ex06_conversion.cpp b/examples/ex06_conversion.cpp new file mode 100644 index 0000000..6555e31 --- /dev/null +++ b/examples/ex06_conversion.cpp @@ -0,0 +1,65 @@ +/* + * Example: ex06_conversion + * + * Purpose: + * Demonstrate the conversion helpers for checked, saturating, truncating, and + * exact casts across both underlying values and primitives. + * + * Expected results: + * - checked_cast succeeds for in-range primitive-to-underlying conversion. + * - checked_cast reports underflow for negative-to-unsigned conversion. + * - saturating_cast clamps out-of-range input. + * - truncating_cast drops the fractional part when targeting an integral + * primitive. + * - exact_cast preserves exact values and reports precision loss otherwise. + * - Program prints a success message and exits with code 0. + */ + +#include +#include + +import mcpplibs.primitives; + +using namespace mcpplibs::primitives; + +int main() { + using namespace mcpplibs::primitives::literals; + + using expected_i32 = + types::I32; + using expected_f32 = + types::F32; + + constexpr auto source = + with(255_i32); + + constexpr auto checked_u16 = conversion::checked_cast(source); + constexpr auto checked_bad = conversion::checked_cast(-1_i32); + constexpr auto saturated_u16 = + conversion::saturating_cast(100000_i32); + auto const truncated_i32 = + conversion::truncating_cast(12.75_f64); + auto const exact_f32 = conversion::exact_cast(16777216_i32); + auto const exact_bad = conversion::exact_cast(16777217_i32); + constexpr auto risk = conversion::numeric_risk(-1_i32); + + if (!checked_u16.has_value() || checked_bad.has_value() || + !exact_f32.has_value() || exact_bad.has_value() || !risk.has_value()) { + std::cerr << "conversion demo expected success path missing\n"; + return 1; + } + + if (*checked_u16 != static_cast(255) || + checked_bad.error() != conversion::risk::kind::underflow || + saturated_u16 != static_cast(65535) || + truncated_i32.load() != 12 || + exact_f32->load() != 16777216.0F || + exact_bad.error() != conversion::risk::kind::precision_loss || + *risk != conversion::risk::kind::underflow) { + std::cerr << "conversion demo produced unexpected values\n"; + return 1; + } + + std::cout << "conversion demo passed\n"; + return 0; +} diff --git a/examples/ex07_algorithms.cpp b/examples/ex07_algorithms.cpp new file mode 100644 index 0000000..e464480 --- /dev/null +++ b/examples/ex07_algorithms.cpp @@ -0,0 +1,57 @@ +/* + * Example: ex07_algorithms + * + * Purpose: + * Demonstrate the built-in algorithms helpers for numeric limits metadata, + * special values, and hashing. + * + * Expected results: + * - limits<> mirrors std::numeric_limits for supported built-in underlying types. + * - helpers expose lowest/max/epsilon/infinity/quiet_nan values. + * - hash_value() matches std::hash for the same underlying literal value. + * - Program prints a success message and exits with code 0. + */ + +#include +#include +#include +#include + +import mcpplibs.primitives; + +using namespace mcpplibs::primitives; + +int main() { + using namespace mcpplibs::primitives::literals; + + using int_limits = algorithms::limits; + using float_limits = algorithms::limits; + + static_assert(int_limits::enabled); + static_assert(float_limits::has_infinity); + static_assert(algorithms::hashable); + + constexpr auto min_i32 = algorithms::min_value(); + constexpr auto max_i32 = algorithms::max_value(); + constexpr auto lowest_f64 = algorithms::lowest_value(); + constexpr auto epsilon_f64 = algorithms::epsilon_value(); + constexpr auto infinity_f64 = algorithms::infinity_value(); + constexpr auto nan_f64 = algorithms::quiet_nan_value(); + auto const hash_literal = algorithms::hash_value(42_i32); + auto const hash_builtin = algorithms::hash_value(std::int32_t{42}); + + if (min_i32 != std::numeric_limits::min() || + max_i32 != std::numeric_limits::max() || + lowest_f64 != std::numeric_limits::lowest() || + epsilon_f64 != std::numeric_limits::epsilon() || + !std::isinf(infinity_f64) || !std::isnan(nan_f64) || + hash_literal != hash_builtin || + int_limits::digits != std::numeric_limits::digits || + float_limits::kind != underlying::category::floating) { + std::cerr << "algorithms demo produced unexpected values\n"; + return 1; + } + + std::cout << "algorithms demo passed\n"; + return 0; +} diff --git a/examples/ex06_custom_underlying.cpp b/examples/ex08_custom_underlying.cpp similarity index 99% rename from examples/ex06_custom_underlying.cpp rename to examples/ex08_custom_underlying.cpp index fe27c5e..9feb64c 100644 --- a/examples/ex06_custom_underlying.cpp +++ b/examples/ex08_custom_underlying.cpp @@ -1,5 +1,5 @@ /* - * Example: ex06_custom_underlying + * Example: ex08_custom_underlying * * Purpose: * Demonstrate custom underlying integration, including rep bridge, @@ -20,7 +20,7 @@ import mcpplibs.primitives; using namespace mcpplibs::primitives; -// Point 6 / Step 1: Define custom domain value types. +// Point 8 / Step 1: Define custom domain value types. struct UserInteger { int value; }; diff --git a/examples/ex07_custom_policy.cpp b/examples/ex09_custom_policy.cpp similarity index 92% rename from examples/ex07_custom_policy.cpp rename to examples/ex09_custom_policy.cpp index f0bd159..db181ab 100644 --- a/examples/ex07_custom_policy.cpp +++ b/examples/ex09_custom_policy.cpp @@ -1,5 +1,5 @@ /* - * Example: ex07_custom_policy + * Example: ex09_custom_policy * * Purpose: * Show end-to-end customization of all policy dimensions (type, value, @@ -24,14 +24,14 @@ import mcpplibs.primitives.operations.invoker; using namespace mcpplibs::primitives; namespace demo { -// Point 7 / Step 1: Define one custom tag for each policy dimension. +// Point 9 / Step 1: Define one custom tag for each policy dimension. struct custom_value {}; struct custom_type {}; struct custom_error {}; struct custom_concurrency {}; } // namespace demo -// Point 7 / Step 2: Register tags into policy::traits. +// Point 9 / Step 2: Register tags into policy::traits. template <> struct mcpplibs::primitives::policy::traits { using policy_type = demo::custom_value; static constexpr bool enabled = true; @@ -57,7 +57,7 @@ struct mcpplibs::primitives::policy::traits { static constexpr auto kind = category::concurrency; }; -// Point 7 / Step 3A: Implement custom type handler. +// Point 9 / Step 3A: Implement custom type handler. // Always allow and negotiate through std::common_type_t. template struct mcpplibs::primitives::policy::type::handler; }; -// Point 7 / Step 3B: Implement custom concurrency handler. +// Point 9 / Step 3B: Implement custom concurrency handler. template struct mcpplibs::primitives::policy::concurrency::handler< @@ -115,7 +115,7 @@ struct mcpplibs::primitives::policy::concurrency::handler< } }; -// Point 7 / Step 3C: Implement custom value handler. +// Point 9 / Step 3C: Implement custom value handler. // Complex point: finalize() post-processes decision and adjusts output. template @@ -138,7 +138,7 @@ struct mcpplibs::primitives::policy::value::handler struct mcpplibs::primitives::operations::runtime::op_binding< @@ -154,7 +154,7 @@ struct mcpplibs::primitives::operations::runtime::op_binding< } }; -// Point 7 / Step 3E: Implement custom error handler. +// Point 9 / Step 3E: Implement custom error handler. template struct mcpplibs::primitives::policy::error::handler; diff --git a/examples/ex08_custom_operation.cpp b/examples/ex10_custom_operation.cpp similarity index 92% rename from examples/ex08_custom_operation.cpp rename to examples/ex10_custom_operation.cpp index ec6f850..4106648 100644 --- a/examples/ex08_custom_operation.cpp +++ b/examples/ex10_custom_operation.cpp @@ -1,5 +1,5 @@ /* - * Example: ex08_custom_operation + * Example: ex10_custom_operation * * Purpose: * Demonstrate how to register new operation tags, declare operation traits, @@ -19,13 +19,13 @@ import mcpplibs.primitives.operations.invoker; using namespace mcpplibs::primitives; namespace demo_ops { -// Point 8 / Step 1: Define custom operation tags. +// Point 10 / Step 1: Define custom operation tags. struct Average {}; struct GreaterThan {}; struct BitAnd {}; } // namespace demo_ops -// Point 8 / Step 2: Register operation traits for +// Point 10 / Step 2: Register operation traits for // arithmetic/comparison/bitwise. template <> struct mcpplibs::primitives::operations::traits { using op_tag = demo_ops::Average; @@ -49,7 +49,7 @@ template <> struct mcpplibs::primitives::operations::traits { static constexpr auto capability_mask = capability::bitwise; }; -// Point 8 / Step 3: Provide runtime op_binding for each new operation. +// Point 10 / Step 3: Provide runtime op_binding for each new operation. // Complex point: these specializations plug directly into run_value dispatch. template struct mcpplibs::primitives::operations::runtime::op_binding< @@ -94,7 +94,7 @@ struct mcpplibs::primitives::operations::runtime::op_binding< }; int main() { - // Point 8 / Step 4: Invoke each custom operation through operations::apply. + // Point 10 / Step 4: Invoke each custom operation through operations::apply. using value_t = primitive; diff --git a/examples/xmake.lua b/examples/xmake.lua index 4dd4589..b17f158 100644 --- a/examples/xmake.lua +++ b/examples/xmake.lua @@ -3,20 +3,22 @@ add_rules("mode.debug", "mode.release") set_languages("c++23") local examples = { - "ex01_default_arithmetic", + "ex01_basic_usage", "ex02_type_policy", "ex03_value_policy", "ex04_error_policy", "ex05_concurrency_policy", - "ex06_custom_underlying", - "ex07_custom_policy", - "ex08_custom_operation" + "ex06_conversion", + "ex07_algorithms", + "ex08_custom_underlying", + "ex09_custom_policy", + "ex10_custom_operation" } --- CI compatibility alias: keep `xmake run basic` working. +-- CI compatibility alias: keep `xmake run basic` working for ex01_basic_usage. target("basic") set_kind("binary") - add_files("ex01_default_arithmetic.cpp") + add_files("ex01_basic_usage.cpp") add_deps("mcpplibs-primitives") set_policy("build.c++.modules", true) diff --git a/src/algorithms/limits.cppm b/src/algorithms/limits.cppm index 9dc40dc..9fb3242 100644 --- a/src/algorithms/limits.cppm +++ b/src/algorithms/limits.cppm @@ -6,7 +6,7 @@ module; export module mcpplibs.primitives.algorithms.limits; -import mcpplibs.primitives.underlying; +import mcpplibs.primitives.underlying.traits; namespace mcpplibs::primitives::algorithms::details { diff --git a/src/underlying/literals.cppm b/src/literals/literals.cppm similarity index 80% rename from src/underlying/literals.cppm rename to src/literals/literals.cppm index b104166..1667abc 100644 --- a/src/underlying/literals.cppm +++ b/src/literals/literals.cppm @@ -7,13 +7,13 @@ module; #include #include -export module mcpplibs.primitives.underlying.literals; +export module mcpplibs.primitives.literals; import mcpplibs.primitives.algorithms.limits; import mcpplibs.primitives.conversion.traits; -import mcpplibs.primitives.underlying; +import mcpplibs.primitives.underlying.traits; -namespace mcpplibs::primitives::underlying::details { +namespace mcpplibs::primitives::literals::details { template consteval auto throw_literal_risk() -> void { @@ -161,7 +161,7 @@ consteval auto literal_integral() -> To { return checked_integral_literal(parse_unsigned_decimal_literal()); } -} // namespace mcpplibs::primitives::underlying::details +} // namespace mcpplibs::primitives::literals::details export namespace mcpplibs::primitives::literals { @@ -179,100 +179,100 @@ consteval auto operator""_wchar(const wchar_t value) -> wchar_t { return value; template consteval auto operator""_u8() -> std::uint8_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } template consteval auto operator""_u16() -> std::uint16_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } template consteval auto operator""_u32() -> std::uint32_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } template consteval auto operator""_u64() -> std::uint64_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } template consteval auto operator""_size() -> std::size_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } template consteval auto operator""_diff() -> std::ptrdiff_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } template consteval auto operator""_i8() -> std::int8_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } template consteval auto operator""_i16() -> std::int16_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } template consteval auto operator""_i32() -> std::int32_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } template consteval auto operator""_i64() -> std::int64_t { - return underlying::details::literal_integral(); + return details::literal_integral(); } consteval auto operator""_f32(const unsigned long long value) -> float { - return underlying::details::checked_floating_literal(value); + return details::checked_floating_literal(value); } consteval auto operator""_f32(const long double value) -> float { - return underlying::details::checked_floating_literal(value); + return details::checked_floating_literal(value); } consteval auto operator""_f32e(const unsigned long long value) -> float { - return underlying::details::exact_floating_literal(value); + return details::exact_floating_literal(value); } consteval auto operator""_f32e(const long double value) -> float { - return underlying::details::exact_floating_literal(value); + return details::exact_floating_literal(value); } consteval auto operator""_f64(const unsigned long long value) -> double { - return underlying::details::checked_floating_literal(value); + return details::checked_floating_literal(value); } consteval auto operator""_f64(const long double value) -> double { - return underlying::details::checked_floating_literal(value); + return details::checked_floating_literal(value); } consteval auto operator""_f64e(const unsigned long long value) -> double { - return underlying::details::exact_floating_literal(value); + return details::exact_floating_literal(value); } consteval auto operator""_f64e(const long double value) -> double { - return underlying::details::exact_floating_literal(value); + return details::exact_floating_literal(value); } consteval auto operator""_f80(const unsigned long long value) -> long double { - return underlying::details::checked_floating_literal(value); + return details::checked_floating_literal(value); } consteval auto operator""_f80(const long double value) -> long double { - return underlying::details::checked_floating_literal(value); + return details::checked_floating_literal(value); } consteval auto operator""_f80e(const unsigned long long value) -> long double { - return underlying::details::exact_floating_literal(value); + return details::exact_floating_literal(value); } consteval auto operator""_f80e(const long double value) -> long double { - return underlying::details::exact_floating_literal(value); + return details::exact_floating_literal(value); } } // namespace mcpplibs::primitives::literals diff --git a/src/operations/operators.cppm b/src/operations/operators.cppm index 012fc5e..8aa5976 100644 --- a/src/operations/operators.cppm +++ b/src/operations/operators.cppm @@ -17,7 +17,7 @@ import mcpplibs.primitives.conversion.traits; import mcpplibs.primitives.conversion.underlying; import mcpplibs.primitives.policy.handler; import mcpplibs.primitives.policy.impl; -import mcpplibs.primitives.underlying.traits; +import mcpplibs.primitives.underlying; namespace mcpplibs::primitives::operations::details { diff --git a/src/policy/impl.cppm b/src/policy/impl.cppm index 69a0426..98dc4f0 100644 --- a/src/policy/impl.cppm +++ b/src/policy/impl.cppm @@ -15,7 +15,7 @@ import mcpplibs.primitives.operations.traits; import mcpplibs.primitives.operations.impl; import mcpplibs.primitives.policy.traits; import mcpplibs.primitives.policy.handler; -import mcpplibs.primitives.underlying.traits; +import mcpplibs.primitives.underlying; namespace mcpplibs::primitives::policy::details { diff --git a/src/primitive/impl.cppm b/src/primitive/impl.cppm index 0f1ad91..e9f5ca6 100644 --- a/src/primitive/impl.cppm +++ b/src/primitive/impl.cppm @@ -7,7 +7,7 @@ module; export module mcpplibs.primitives.primitive.impl; import mcpplibs.primitives.conversion.underlying; -import mcpplibs.primitives.underlying.traits; +import mcpplibs.primitives.underlying; import mcpplibs.primitives.policy.traits; import mcpplibs.primitives.policy.handler; import mcpplibs.primitives.policy.impl; diff --git a/src/primitive/traits.cppm b/src/primitive/traits.cppm index 0168c7d..c571112 100644 --- a/src/primitive/traits.cppm +++ b/src/primitive/traits.cppm @@ -7,7 +7,7 @@ export module mcpplibs.primitives.primitive.traits; import mcpplibs.primitives.primitive.impl; import mcpplibs.primitives.policy.traits; import mcpplibs.primitives.policy.utility; -import mcpplibs.primitives.underlying.traits; +import mcpplibs.primitives.underlying; namespace mcpplibs::primitives::meta::details { diff --git a/src/primitives.cppm b/src/primitives.cppm index 86ee0e2..6c71b6e 100644 --- a/src/primitives.cppm +++ b/src/primitives.cppm @@ -8,4 +8,4 @@ export import mcpplibs.primitives.primitive; export import mcpplibs.primitives.operations; export import mcpplibs.primitives.algorithms; export import mcpplibs.primitives.conversion; -export import mcpplibs.primitives.underlying.literals; +export import mcpplibs.primitives.literals; diff --git a/src/underlying/impl.cppm b/src/underlying/impl.cppm index 6c39c3a..6aaa4d1 100644 --- a/src/underlying/impl.cppm +++ b/src/underlying/impl.cppm @@ -1,35 +1,5 @@ module; -#include export module mcpplibs.primitives.underlying.impl; -import mcpplibs.primitives.underlying.traits; - -export -template -struct mcpplibs::primitives::underlying::traits { - using value_type = std::remove_cv_t; - using rep_type = value_type; - - static constexpr bool enabled = true; - - static constexpr category kind = [] { - if constexpr (std_bool) { - return category::boolean; - } else if constexpr (std_char) { - return category::character; - } else if constexpr (std_integer) { - return category::integer; - } else { - return category::floating; - } - }(); - - static constexpr rep_type to_rep(value_type value) noexcept { return value; } - - static constexpr value_type from_rep(rep_type value) noexcept { - return value; - } - - static constexpr bool is_valid_rep(rep_type) noexcept { return true; } -}; +export import mcpplibs.primitives.underlying.traits; diff --git a/src/underlying/traits.cppm b/src/underlying/traits.cppm index 9c1b429..7bf4674 100644 --- a/src/underlying/traits.cppm +++ b/src/underlying/traits.cppm @@ -74,6 +74,34 @@ struct common_rep_traits< static constexpr bool enabled = true; }; +template +struct traits { + using value_type = std::remove_cv_t; + using rep_type = value_type; + + static constexpr bool enabled = true; + + static constexpr category kind = [] { + if constexpr (std_bool) { + return category::boolean; + } else if constexpr (std_char) { + return category::character; + } else if constexpr (std_integer) { + return category::integer; + } else { + return category::floating; + } + }(); + + static constexpr rep_type to_rep(value_type value) noexcept { return value; } + + static constexpr value_type from_rep(rep_type value) noexcept { + return value; + } + + static constexpr bool is_valid_rep(rep_type) noexcept { return true; } +}; + } // namespace underlying } // namespace mcpplibs::primitives diff --git a/tests/basic/CMakeLists.txt b/tests/basic/CMakeLists.txt index 2cfd3a7..3609ce1 100644 --- a/tests/basic/CMakeLists.txt +++ b/tests/basic/CMakeLists.txt @@ -29,6 +29,7 @@ endfunction() add_basic_suite(basic_conversion_tests "conversion/**/test_*.cpp") add_basic_suite(basic_algorithms_tests "algorithms/**/test_*.cpp") +add_basic_suite(basic_literals_tests "literals/test_*.cpp") add_basic_suite(basic_operations_tests "operations/**/test_*.cpp") add_basic_suite(basic_policy_tests "policy/**/test_*.cpp") add_basic_suite(basic_primitive_tests "primitive/**/test_*.cpp") @@ -38,6 +39,7 @@ add_custom_target(basic_tests) add_dependencies(basic_tests basic_conversion_tests basic_algorithms_tests + basic_literals_tests basic_operations_tests basic_policy_tests basic_primitive_tests diff --git a/tests/basic/underlying/literals/test_literals.cpp b/tests/basic/literals/test_literals.cpp similarity index 94% rename from tests/basic/underlying/literals/test_literals.cpp rename to tests/basic/literals/test_literals.cpp index 970f0da..a73c8ff 100644 --- a/tests/basic/underlying/literals/test_literals.cpp +++ b/tests/basic/literals/test_literals.cpp @@ -3,7 +3,7 @@ #include #include -import mcpplibs.primitives.underlying.literals; +import mcpplibs.primitives.literals; using namespace mcpplibs::primitives::literals; @@ -52,7 +52,7 @@ static_assert(!literal_available); } // namespace -TEST(UnderlyingLiteralsTest, IntegerLiteralsReturnExpectedUnderlyingTypes) { +TEST(LiteralsTest, IntegerLiteralsReturnExpectedUnderlyingTypes) { static_assert(std::same_as); static_assert(std::same_as); static_assert(std::same_as); @@ -76,7 +76,7 @@ TEST(UnderlyingLiteralsTest, IntegerLiteralsReturnExpectedUnderlyingTypes) { EXPECT_EQ(42_i64, static_cast(42)); } -TEST(UnderlyingLiteralsTest, FloatingLiteralsReturnExpectedUnderlyingTypes) { +TEST(LiteralsTest, FloatingLiteralsReturnExpectedUnderlyingTypes) { static_assert(std::same_as); static_assert(std::same_as); static_assert(std::same_as); @@ -114,7 +114,7 @@ TEST(UnderlyingLiteralsTest, FloatingLiteralsReturnExpectedUnderlyingTypes) { EXPECT_EQ(2_f80e, static_cast(2.0)); } -TEST(UnderlyingLiteralsTest, CharacterLiteralsReturnExpectedUnderlyingTypes) { +TEST(LiteralsTest, CharacterLiteralsReturnExpectedUnderlyingTypes) { static_assert(std::same_as); static_assert(std::same_as); static_assert(std::same_as); diff --git a/xmake.lua b/xmake.lua index f51dd6b..f8e95b1 100644 --- a/xmake.lua +++ b/xmake.lua @@ -1,5 +1,5 @@ set_project("mcpplibs-primitives") -set_version("0.3.0") +set_version("0.4.0") add_rules("mode.release", "mode.debug")