From 06acecca921da9ae7fe25224a73fcdee3f454ef3 Mon Sep 17 00:00:00 2001 From: FrozenlemonTee <1115306170@qq.com> Date: Mon, 23 Mar 2026 12:35:03 +0800 Subject: [PATCH 01/14] docs: Update current plan directory path in copilot instructions Signed-off-by: FrozenlemonTee <1115306170@qq.com> --- .github/copilot-instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 2b8024d..016ae56 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -14,7 +14,7 @@ ## 正在进行中的计划 -- 当前计划目录:`../.github/prompts/` +- 当前计划目录:`../.agents/docs/plans/` ## 说明 From ec9b072e0fded943228cb8b1a12963cc73272c2e Mon Sep 17 00:00:00 2001 From: FrozenlemonTee <1115306170@qq.com> Date: Mon, 23 Mar 2026 12:46:56 +0800 Subject: [PATCH 02/14] docs: Add implementation plan for primitives module with milestones and acceptance criteria Signed-off-by: FrozenlemonTee <1115306170@qq.com> --- .agents/docs/plans/implementation-plan.md | 82 +++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 .agents/docs/plans/implementation-plan.md diff --git a/.agents/docs/plans/implementation-plan.md b/.agents/docs/plans/implementation-plan.md new file mode 100644 index 0000000..55ea982 --- /dev/null +++ b/.agents/docs/plans/implementation-plan.md @@ -0,0 +1,82 @@ +# Primitives 下一步实现计划清单(2026-03-23) + +## 总体原则 + +- [ ] 先定义稳定 API 边界,再落地实现 +- [ ] 每个能力都配套 tests + examples + docs +- [ ] 高风险转换默认禁止隐式触发,只允许显式 API + +## 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) +- [ ] 完善 `traits` 元信息(`kind`、`rep_type`、limits、policy tags) +- [ ] 提供检测类 API(可转换性/是否有损/错误模型能力) +- [ ] 统一 `constexpr` 查询入口,减少分散 traits 访问 +- [ ] 增加编译期测试矩阵(`static_assert` 覆盖) + +### 验收标准 + +- [ ] 上层模块仅依赖公开 concept/traits,不依赖 `details::*` +- [ ] 元信息可支撑转换层与算法层的约束判定 + +## M3. 显式转换层(任意策略组适用) + +### 工作清单 + +- [ ] 设计统一接口族(建议):`explicit_cast`、`try_cast`、`checked_cast` +- [ ] 支持任意策略组组合,不绑定特定策略实现 +- [ ] 风险可见化(截断/溢出/精度损失)并可程序化读取 +- [ ] 定义失败语义(错误码或 expected 风格,按策略可配置) +- [ ] 建立转换矩阵测试(同类/跨类/跨策略组) + +### 验收标准 + +- [ ] 所有跨类高风险转换必须走显式 API +- [ ] 风险信息可在编译期或运行期被确定性获取 + +## M4. 算法层(以 max/min 为起点) + +### 工作清单 + +- [ ] 实现 `max`/`min`,并预留 `clamp`/`compare` 扩展位 +- [ ] 算法统一依赖 M2+M3 的公开接口,不绕过转换层 +- [ ] 支持同类与受约束的异类输入 +- [ ] 在可行范围保持 `constexpr`/`noexcept` 特性 +- [ ] 增加边界测试(极值、NaN、有符号/无符号混合) + +### 验收标准 + +- [ ] 算法行为与策略约束一致 +- [ ] 风险路径始终显式、可审计 + +## 建议推进顺序 + +1. M2(先夯实约束与元信息基础) +2. M1(建立跨语言边界) +3. M3(收敛转换风险) +4. M4(复用基础能力实现算法) + +## 总体完成跟踪 + +- [ ] M1 完成 +- [ ] M2 完成 +- [ ] M3 完成 +- [ ] M4 完成 From ab28749722094d6bbba6fee249e9a95945be30fc Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 19:21:07 +0800 Subject: [PATCH 03/14] docs: Update policy category references in traits implementation --- src/primitive/traits.cppm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/primitive/traits.cppm b/src/primitive/traits.cppm index e1fb5b4..aa77ac5 100644 --- a/src/primitive/traits.cppm +++ b/src/primitive/traits.cppm @@ -34,13 +34,13 @@ struct traits> { using value_type = T; using policies = std::tuple; using value_policy = - policy::resolve_policy_t; + policy::resolve_policy_t; using type_policy = - policy::resolve_policy_t; + policy::resolve_policy_t; using error_policy = - policy::resolve_policy_t; + policy::resolve_policy_t; using concurrency_policy = - policy::resolve_policy_t; + policy::resolve_policy_t; }; } // namespace mcpplibs::primitives::meta From c9f99aa53d5e3b7cd5d87d960bdc95eeead88ded Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 20:27:21 +0800 Subject: [PATCH 04/14] refactor: Simplify traits implementation by introducing primitive_traits_impl --- src/primitive/traits.cppm | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/primitive/traits.cppm b/src/primitive/traits.cppm index aa77ac5..b4ee72b 100644 --- a/src/primitive/traits.cppm +++ b/src/primitive/traits.cppm @@ -1,5 +1,6 @@ module; #include +#include export module mcpplibs.primitives.primitive.traits; @@ -9,6 +10,26 @@ import mcpplibs.primitives.policy.impl; import mcpplibs.primitives.policy.utility; import mcpplibs.primitives.underlying.traits; +namespace mcpplibs::primitives::meta::details { + +template struct primitive_traits_impl; + +template +struct primitive_traits_impl> { + using value_type = T; + using policies = std::tuple; + using value_policy = + policy::resolve_policy_t; + using type_policy = + policy::resolve_policy_t; + using error_policy = + policy::resolve_policy_t; + using concurrency_policy = + policy::resolve_policy_t; +}; + +} // namespace mcpplibs::primitives::meta::details + // Public API exported from this module. export namespace mcpplibs::primitives::meta { using policy_category = policy::category; @@ -27,21 +48,8 @@ using default_policies = std::tuple; -template struct traits; - -template -struct traits> { - using value_type = T; - using policies = std::tuple; - using value_policy = - policy::resolve_policy_t; - using type_policy = - policy::resolve_policy_t; - using error_policy = - policy::resolve_policy_t; - using concurrency_policy = - policy::resolve_policy_t; -}; +template +using traits = details::primitive_traits_impl>; } // namespace mcpplibs::primitives::meta From 35f52111b0058468629e3775ca5d7262d556a842 Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 20:56:01 +0800 Subject: [PATCH 05/14] refactor: Introduce concepts for primitive types in traits implementation --- src/primitive/traits.cppm | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/primitive/traits.cppm b/src/primitive/traits.cppm index b4ee72b..8ecb4fe 100644 --- a/src/primitive/traits.cppm +++ b/src/primitive/traits.cppm @@ -51,6 +51,43 @@ using default_policies = template using traits = details::primitive_traits_impl>; +template +concept primitive_type = requires { + typename traits::value_type; + typename traits::policies; + typename traits::value_policy; + typename traits::type_policy; + typename traits::error_policy; + typename traits::concurrency_policy; +}; + +template +concept boolean = + primitive_type && + (underlying::traits::value_type>::kind == + underlying::category::boolean); + +template +concept character = + primitive_type && + (underlying::traits::value_type>::kind == + underlying::category::character); + +template +concept integer = + primitive_type && + (underlying::traits::value_type>::kind == + underlying::category::integer); + +template +concept floating = + primitive_type && + (underlying::traits::value_type>::kind == + underlying::category::floating); + +template +concept numeric = integer || floating; + } // namespace mcpplibs::primitives::meta // Backward-compatible aliases for existing downstream users. From fb4c004e2612f86897eb6e2a550d10916e30abe9 Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 20:56:31 +0800 Subject: [PATCH 06/14] refactor: Add tests for meta traits and primitive concepts in primitives module --- tests/basic/test_underlying.cpp | 57 +++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/tests/basic/test_underlying.cpp b/tests/basic/test_underlying.cpp index 9a5c9d9..8ab7540 100644 --- a/tests/basic/test_underlying.cpp +++ b/tests/basic/test_underlying.cpp @@ -480,6 +480,63 @@ TEST(PrimitiveTraitsTest, LegacyPrimitiveTraitsNamespaceAliasesRemainAvailable) SUCCEED(); } +TEST(PrimitiveTraitsTest, MetaTraitsExposeValueTypeAndPrimitiveMetadata) { + using value_t = mcpplibs::primitives::primitive< + short, mcpplibs::primitives::policy::value::checked, + mcpplibs::primitives::policy::type::compatible, + mcpplibs::primitives::policy::error::expected, + mcpplibs::primitives::policy::concurrency::fenced>; + using traits_t = mcpplibs::primitives::meta::traits; + + static_assert( + std::same_as); + static_assert(std::same_as); + static_assert(std::same_as); + static_assert(std::same_as); + static_assert(std::same_as); + static_assert(std::same_as); + + SUCCEED(); +} + +TEST(PrimitiveTraitsTest, MetaPrimitiveConceptsMatchUnderlyingCategory) { + using boolean_t = mcpplibs::primitives::primitive; + using character_t = mcpplibs::primitives::primitive; + using integer_t = mcpplibs::primitives::primitive; + using floating_t = mcpplibs::primitives::primitive; + + static_assert(mcpplibs::primitives::meta::primitive_type); + static_assert(mcpplibs::primitives::meta::primitive_type); + static_assert(!mcpplibs::primitives::meta::primitive_type); + + static_assert(mcpplibs::primitives::meta::boolean); + static_assert(!mcpplibs::primitives::meta::boolean); + + static_assert(mcpplibs::primitives::meta::character); + static_assert(!mcpplibs::primitives::meta::character); + + static_assert(mcpplibs::primitives::meta::integer); + static_assert(!mcpplibs::primitives::meta::integer); + + static_assert(mcpplibs::primitives::meta::floating); + static_assert(!mcpplibs::primitives::meta::floating); + + static_assert(mcpplibs::primitives::meta::numeric); + static_assert(mcpplibs::primitives::meta::numeric); + static_assert(!mcpplibs::primitives::meta::numeric); + static_assert(!mcpplibs::primitives::meta::numeric); + static_assert(!mcpplibs::primitives::meta::numeric); + + EXPECT_TRUE((mcpplibs::primitives::meta::boolean)); + EXPECT_TRUE((mcpplibs::primitives::meta::character)); + EXPECT_TRUE((mcpplibs::primitives::meta::integer)); + EXPECT_TRUE((mcpplibs::primitives::meta::floating)); +} + TEST(PrimitiveTraitsTest, UnderlyingTypeRequiresValidRepTypeAndCategoryConsistency) { EXPECT_TRUE((mcpplibs::primitives::underlying::traits::enabled)); From 2d762fc5f40e4a310d9b6c09350876e7928ec0a1 Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 21:02:43 +0800 Subject: [PATCH 07/14] refactor: Replace primitive_instance concept with primitive_type in dispatcher and operators --- src/operations/dispatcher.cppm | 15 ++++++--------- src/operations/operators.cppm | 3 +++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/operations/dispatcher.cppm b/src/operations/dispatcher.cppm index 9fdaa33..4b17d41 100644 --- a/src/operations/dispatcher.cppm +++ b/src/operations/dispatcher.cppm @@ -15,13 +15,8 @@ import mcpplibs.primitives.underlying; export namespace mcpplibs::primitives::operations { -template -concept primitive_instance = requires { - typename primitives::meta::traits< - std::remove_cvref_t>::value_type; -}; - -template struct dispatcher_meta { using lhs_primitive = std::remove_cvref_t; @@ -85,7 +80,8 @@ struct dispatcher_meta { ErrorPayload>; }; -template using dispatch_result_t = std::expected< typename dispatcher_meta::common_rep, @@ -93,7 +89,8 @@ using dispatch_result_t = std::expected< // Dispatcher pipeline: compile-time negotiation plus runtime chain // (concurrency -> value -> error) through selected policy handlers. -template constexpr auto dispatch(Lhs const &lhs, Rhs const &rhs) -> dispatch_result_t { diff --git a/src/operations/operators.cppm b/src/operations/operators.cppm index 67f8b40..13e418d 100644 --- a/src/operations/operators.cppm +++ b/src/operations/operators.cppm @@ -61,6 +61,9 @@ constexpr auto decode_three_way_code(CommonRep const &code) -> Ordering { } // namespace details +template +concept primitive_instance = meta::primitive_type; + template using primitive_dispatch_result_t = std::expected Date: Mon, 23 Mar 2026 21:08:35 +0800 Subject: [PATCH 08/14] refactor: Remove redundant namespace qualifiers for primitive types in dispatcher --- src/operations/dispatcher.cppm | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/operations/dispatcher.cppm b/src/operations/dispatcher.cppm index 4b17d41..7947265 100644 --- a/src/operations/dispatcher.cppm +++ b/src/operations/dispatcher.cppm @@ -15,15 +15,15 @@ import mcpplibs.primitives.underlying; export namespace mcpplibs::primitives::operations { -template struct dispatcher_meta { using lhs_primitive = std::remove_cvref_t; using rhs_primitive = std::remove_cvref_t; - using lhs_traits = primitives::meta::traits; - using rhs_traits = primitives::meta::traits; + using lhs_traits = meta::traits; + using rhs_traits = meta::traits; using lhs_value_type = lhs_traits::value_type; using rhs_value_type = rhs_traits::value_type; @@ -31,15 +31,15 @@ struct dispatcher_meta { using lhs_rep = underlying::traits::rep_type; using rhs_rep = underlying::traits::rep_type; - using lhs_type_policy = typename lhs_traits::type_policy; - using lhs_value_policy = typename lhs_traits::value_policy; - using lhs_error_policy = typename lhs_traits::error_policy; - using lhs_concurrency_policy = typename lhs_traits::concurrency_policy; + using lhs_type_policy = lhs_traits::type_policy; + using lhs_value_policy = lhs_traits::value_policy; + using lhs_error_policy = lhs_traits::error_policy; + using lhs_concurrency_policy = lhs_traits::concurrency_policy; - using rhs_type_policy = typename rhs_traits::type_policy; - using rhs_value_policy = typename rhs_traits::value_policy; - using rhs_error_policy = typename rhs_traits::error_policy; - using rhs_concurrency_policy = typename rhs_traits::concurrency_policy; + using rhs_type_policy = rhs_traits::type_policy; + using rhs_value_policy = rhs_traits::value_policy; + using rhs_error_policy = rhs_traits::error_policy; + using rhs_concurrency_policy = rhs_traits::concurrency_policy; static constexpr bool policy_group_consistent = std::is_same_v && From 17d3984a28ce02cd6dd45356db3547529b5df3bc Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 21:08:46 +0800 Subject: [PATCH 09/14] refactor: Replace primitive_instance concept with meta::primitive_type in operators module --- src/operations/operators.cppm | 298 +++++++++++++++++----------------- 1 file changed, 148 insertions(+), 150 deletions(-) diff --git a/src/operations/operators.cppm b/src/operations/operators.cppm index 13e418d..6907db8 100644 --- a/src/operations/operators.cppm +++ b/src/operations/operators.cppm @@ -61,10 +61,7 @@ constexpr auto decode_three_way_code(CommonRep const &code) -> Ordering { } // namespace details -template -concept primitive_instance = meta::primitive_type; - -template using primitive_dispatch_result_t = std::expected::common_rep, @@ -74,11 +71,11 @@ using primitive_dispatch_result_t = std::expected concept underlying_operand = underlying_type>; -template +template using mixed_bridge_primitive_t = meta::make_primitive_t< std::remove_cvref_t, typename meta::traits::policies>; -template using mixed_primitive_dispatch_result_t = @@ -86,7 +83,7 @@ using mixed_primitive_dispatch_result_t = mixed_bridge_primitive_t, ErrorPayload>; -template using three_way_dispatch_result_t = std::expected< details::three_way_ordering_t< @@ -94,7 +91,7 @@ using three_way_dispatch_result_t = std::expected< ErrorPayload>::common_rep>, ErrorPayload>; -template using mixed_three_way_dispatch_result_t = three_way_dispatch_result_t; template using flipped_mixed_primitive_dispatch_result_t = primitive_dispatch_result_t< OpTag, mixed_bridge_primitive_t, Primitive, ErrorPayload>; -template using flipped_mixed_three_way_dispatch_result_t = three_way_dispatch_result_t< mixed_bridge_primitive_t, Primitive, ErrorPayload>; -template using unary_dispatch_result_t = primitive_dispatch_result_t; -template constexpr auto apply_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t; -template constexpr auto apply(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { @@ -139,14 +136,14 @@ constexpr auto apply(Lhs const &lhs, Rhs const &rhs) return result_primitive{*raw}; } -template constexpr auto apply(Operand const &operand) -> unary_dispatch_result_t { return apply(operand, operand); } -template constexpr auto apply(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { @@ -155,7 +152,7 @@ constexpr auto apply(Lhs const &lhs, Rhs const &rhs) return apply(lhs, bridge_rhs); } -template constexpr auto apply(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t +template constexpr auto increment(Operand &operand) -> unary_dispatch_result_t { return apply_assign(operand, operand); } -template +template constexpr auto decrement(Operand &operand) -> unary_dispatch_result_t { return apply_assign(operand, operand); } -template +template constexpr auto bit_not(Operand const &operand) -> unary_dispatch_result_t { return apply(operand); } -template +template constexpr auto unary_plus(Operand const &operand) -> unary_dispatch_result_t { return apply(operand); } -template +template constexpr auto unary_minus(Operand const &operand) -> unary_dispatch_result_t { return apply(operand); } // Binary arithmetic operations -template constexpr auto add(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto add(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto add(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto sub(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto sub(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto sub(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto mul(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto mul(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto mul(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto div(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto mod(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto mod(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto mod(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t constexpr auto shift_left(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto shift_left(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto shift_left(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto shift_right(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto shift_right(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto shift_right(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto bit_and(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto bit_and(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto bit_and(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto bit_or(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto bit_or(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto bit_or(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto bit_xor(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto bit_xor(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto bit_xor(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto div(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto div(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto equal(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto equal(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto equal(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto not_equal(Lhs const &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto not_equal(Lhs const &lhs, Rhs const &rhs) -> mixed_primitive_dispatch_result_t { return apply(lhs, rhs); } -template constexpr auto not_equal(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_primitive_dispatch_result_t(lhs, rhs); } -template constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs) -> three_way_dispatch_result_t { @@ -483,7 +480,7 @@ constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs) return details::decode_three_way_code(*raw); } -template constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs) -> mixed_three_way_dispatch_result_t { @@ -492,7 +489,7 @@ constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs) return three_way_compare(lhs, bridge_rhs); } -template constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs) -> flipped_mixed_three_way_dispatch_result_t { @@ -501,7 +498,7 @@ constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs) return three_way_compare(bridge_lhs, rhs); } -template constexpr auto apply_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { @@ -535,70 +532,70 @@ constexpr auto apply_assign(Lhs &lhs, Rhs const &rhs) return out; } -template constexpr auto add_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply_assign(lhs, rhs); } -template constexpr auto sub_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply_assign(lhs, rhs); } -template constexpr auto mul_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply_assign(lhs, rhs); } -template constexpr auto div_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply_assign(lhs, rhs); } -template constexpr auto mod_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply_assign(lhs, rhs); } -template constexpr auto shift_left_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply_assign(lhs, rhs); } -template constexpr auto shift_right_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply_assign(lhs, rhs); } -template constexpr auto bit_and_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply_assign(lhs, rhs); } -template constexpr auto bit_or_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { return apply_assign(lhs, rhs); } -template constexpr auto bit_xor_assign(Lhs &lhs, Rhs const &rhs) -> primitive_dispatch_result_t { @@ -610,13 +607,13 @@ constexpr auto bit_xor_assign(Lhs &lhs, Rhs const &rhs) export namespace mcpplibs::primitives::operators { // Unary operators -template +template constexpr auto operator++(Operand &operand) -> operations::unary_dispatch_result_t { return operations::increment(operand); } -template +template constexpr auto operator++(Operand &operand, int) -> operations::unary_dispatch_result_t { auto const before = operand; @@ -627,13 +624,13 @@ constexpr auto operator++(Operand &operand, int) return before; } -template +template constexpr auto operator--(Operand &operand) -> operations::unary_dispatch_result_t { return operations::decrement(operand); } -template +template constexpr auto operator--(Operand &operand, int) -> operations::unary_dispatch_result_t { auto const before = operand; @@ -644,33 +641,33 @@ constexpr auto operator--(Operand &operand, int) return before; } -template +template constexpr auto operator+(Operand const &operand) -> operations::unary_dispatch_result_t { return operations::unary_plus(operand); } -template +template constexpr auto operator-(Operand const &operand) -> operations::unary_dispatch_result_t { return operations::unary_minus(operand); } -template +template constexpr auto operator~(Operand const &operand) -> operations::unary_dispatch_result_t { return operations::bit_not(operand); } // Binary arithmetic operators -template +template constexpr auto operator+(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::add(lhs, rhs); } -template constexpr auto operator+(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator+(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::Addition, Lhs, Rhs> { return operations::add(lhs, rhs); } -template +template constexpr auto operator-(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::sub(lhs, rhs); } -template constexpr auto operator-(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator-(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::Subtraction, Lhs, Rhs> { return operations::sub(lhs, rhs); } -template +template constexpr auto operator*(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::mul(lhs, rhs); } -template constexpr auto operator*(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator*(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::Multiplication, Lhs, Rhs> { return operations::mul(lhs, rhs); } -template +template constexpr auto operator/(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::div(lhs, rhs); } -template constexpr auto operator/(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator/(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::Division, Lhs, Rhs> { return operations::div(lhs, rhs); } -template +template constexpr auto operator%(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::mod(lhs, rhs); } -template constexpr auto operator%(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator%(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::Modulus, Lhs, Rhs> { @@ -781,14 +778,14 @@ constexpr auto operator%(Lhs const &lhs, Rhs const &rhs) } // Binary bitwise operators -template +template constexpr auto operator<<(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::shift_left(lhs, rhs); } -template constexpr auto operator<<(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator<<(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::LeftShift, Lhs, Rhs> { return operations::shift_left(lhs, rhs); } -template +template constexpr auto operator>>(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::shift_right(lhs, rhs); } -template constexpr auto operator>>(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t>(Lhs const &lhs, Rhs const &rhs) } template + meta::primitive_type Rhs> constexpr auto operator>>(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::RightShift, Lhs, Rhs> { return operations::shift_right(lhs, rhs); } -template +template constexpr auto operator&(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::bit_and(lhs, rhs); } -template constexpr auto operator&(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator&(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::BitwiseAnd, Lhs, Rhs> { return operations::bit_and(lhs, rhs); } -template +template constexpr auto operator|(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::bit_or(lhs, rhs); } -template constexpr auto operator|(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator|(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::BitwiseOr, Lhs, Rhs> { return operations::bit_or(lhs, rhs); } -template +template constexpr auto operator^(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::bit_xor(lhs, rhs); } -template constexpr auto operator^(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator^(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::BitwiseXor, Lhs, Rhs> { @@ -898,14 +895,14 @@ constexpr auto operator^(Lhs const &lhs, Rhs const &rhs) // Binary comparison operators -template +template constexpr auto operator==(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::equal(lhs, rhs); } -template constexpr auto operator==(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator==(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t { return operations::equal(lhs, rhs); } -template +template constexpr auto operator!=(Lhs const &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::not_equal(lhs, rhs); } -template constexpr auto operator!=(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_primitive_dispatch_result_t + meta::primitive_type Rhs> constexpr auto operator!=(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_primitive_dispatch_result_t< operations::NotEqual, Lhs, Rhs> { return operations::not_equal(lhs, rhs); } -template +template constexpr auto operator<=>(Lhs const &lhs, Rhs const &rhs) -> operations::three_way_dispatch_result_t { return operations::three_way_compare(lhs, rhs); } -template constexpr auto operator<=>(Lhs const &lhs, Rhs const &rhs) -> operations::mixed_three_way_dispatch_result_t { @@ -959,82 +956,83 @@ constexpr auto operator<=>(Lhs const &lhs, Rhs const &rhs) } template + meta::primitive_type Rhs> constexpr auto operator<=>(Lhs const &lhs, Rhs const &rhs) -> operations::flipped_mixed_three_way_dispatch_result_t { return operations::three_way_compare(lhs, rhs); } -template +template constexpr auto operator+=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::add_assign(lhs, rhs); } -template +template constexpr auto operator-=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::sub_assign(lhs, rhs); } -template +template constexpr auto operator*=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::mul_assign(lhs, rhs); } -template +template constexpr auto operator/=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::div_assign(lhs, rhs); } -template +template constexpr auto operator%=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::mod_assign(lhs, rhs); } -template +template constexpr auto operator<<=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::shift_left_assign(lhs, rhs); } -template +template constexpr auto operator>>=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::shift_right_assign(lhs, rhs); } -template +template constexpr auto operator&=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::bit_and_assign(lhs, rhs); } -template +template constexpr auto operator|=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::bit_or_assign(lhs, rhs); } -template +template constexpr auto operator^=(Lhs &lhs, Rhs const &rhs) -> operations::primitive_dispatch_result_t { return operations::bit_xor_assign(lhs, rhs); } } // namespace mcpplibs::primitives::operators + From 570e309be2f32c7450fdfd6514f08d93f568ccd6 Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 21:13:18 +0800 Subject: [PATCH 10/14] refactor: Move underlying_operand concept into operations namespace --- src/operations/operators.cppm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/operations/operators.cppm b/src/operations/operators.cppm index 6907db8..ff2430c 100644 --- a/src/operations/operators.cppm +++ b/src/operations/operators.cppm @@ -17,6 +17,13 @@ import mcpplibs.primitives.policy.handler; import mcpplibs.primitives.policy.impl; import mcpplibs.primitives.underlying.traits; +namespace mcpplibs::primitives::operations { + +template +concept underlying_operand = underlying_type>; + +} // namespace mcpplibs::primitives::operations + export namespace mcpplibs::primitives::operations { namespace details { @@ -68,9 +75,6 @@ using primitive_dispatch_result_t = std::expected::policies>, ErrorPayload>; -template -concept underlying_operand = underlying_type>; - template using mixed_bridge_primitive_t = meta::make_primitive_t< std::remove_cvref_t, typename meta::traits::policies>; From facfac2414a600aeae53e5ba311f15d61697f486 Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 21:19:33 +0800 Subject: [PATCH 11/14] refactor: Improve apply_runtime_fence function parameter types and condition check --- src/operations/invoker.cppm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/operations/invoker.cppm b/src/operations/invoker.cppm index 7c84208..c203769 100644 --- a/src/operations/invoker.cppm +++ b/src/operations/invoker.cppm @@ -781,13 +781,13 @@ constexpr auto make_div_zero(char const *reason) return make_error(policy::error::kind::divide_by_zero, reason); } -constexpr auto apply_runtime_fence(bool enabled, - std::memory_order order) noexcept -> void { +constexpr auto apply_runtime_fence(const bool enabled, + const std::memory_order order) noexcept -> void { if (!enabled) { return; } - if (!std::is_constant_evaluated()) { + if !consteval { std::atomic_thread_fence(order); } } From c675829b95cd4851ab0241dace10280083d6ba48 Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 21:41:34 +0800 Subject: [PATCH 12/14] refactor: Make details not exported --- src/operations/invoker.cppm | 9 ++++++--- src/operations/operators.cppm | 8 ++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/operations/invoker.cppm b/src/operations/invoker.cppm index c203769..87c4258 100644 --- a/src/operations/invoker.cppm +++ b/src/operations/invoker.cppm @@ -17,9 +17,8 @@ import mcpplibs.primitives.policy.handler; import mcpplibs.primitives.policy.impl; import mcpplibs.primitives.policy.traits; -export namespace mcpplibs::primitives::operations::runtime { -namespace details { +namespace mcpplibs::primitives::operations::runtime::details { template constexpr auto make_error(policy::error::kind kind, char const *reason, @@ -792,7 +791,11 @@ constexpr auto apply_runtime_fence(const bool enabled, } } -} // namespace details +} // namespace mcpplibs::primitives::operations::runtime::details + + + +export namespace mcpplibs::primitives::operations::runtime { template struct op_binding { diff --git a/src/operations/operators.cppm b/src/operations/operators.cppm index ff2430c..3ec2bf9 100644 --- a/src/operations/operators.cppm +++ b/src/operations/operators.cppm @@ -22,10 +22,6 @@ namespace mcpplibs::primitives::operations { template concept underlying_operand = underlying_type>; -} // namespace mcpplibs::primitives::operations - -export namespace mcpplibs::primitives::operations { - namespace details { template struct three_way_ordering { using type = std::strong_ordering; @@ -68,6 +64,10 @@ constexpr auto decode_three_way_code(CommonRep const &code) -> Ordering { } // namespace details +} // namespace mcpplibs::primitives::operations + +export namespace mcpplibs::primitives::operations { + template using primitive_dispatch_result_t = std::expected Date: Mon, 23 Mar 2026 22:11:28 +0800 Subject: [PATCH 13/14] refactor: Move atomic reference utilities into details namespace --- src/policy/impl.cppm | 146 +++++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/src/policy/impl.cppm b/src/policy/impl.cppm index ecd090a..df1299e 100644 --- a/src/policy/impl.cppm +++ b/src/policy/impl.cppm @@ -19,6 +19,79 @@ import mcpplibs.primitives.policy.traits; import mcpplibs.primitives.policy.handler; import mcpplibs.primitives.underlying.traits; +namespace mcpplibs::primitives::policy::details { + +template > +struct atomic_ref_alignment_compatible : std::false_type {}; + +template +struct atomic_ref_alignment_compatible + : std::bool_constant<(alignof(T) >= + std::atomic_ref::required_alignment)> {}; + +template +inline constexpr bool atomic_ref_compatible_v = + atomic_ref_alignment_compatible::value; + +template constexpr void assert_atomic_ref_compatible() { + static_assert(std::is_trivially_copyable_v, + "concurrency::handler atomic access requires trivially " + "copyable CommonRep"); + static_assert( + atomic_ref_alignment_compatible::value, + "concurrency::handler atomic access requires alignof(CommonRep) to " + "satisfy std::atomic_ref::required_alignment"); +} + +template +concept has_underlying_rep_not_equal = + underlying_type && + requires(T const &lhs, T const &rhs) { + { + underlying::traits>::to_rep(lhs) != + underlying::traits>::to_rep(rhs) + } -> std::convertible_to; + }; + +template +inline constexpr bool none_compare_exchange_available_v = + has_underlying_rep_not_equal; + +template +inline constexpr bool is_arithmetic_operation_v = + operations::op_has_capability_v; + +template +inline constexpr bool is_boolean_or_character_v = std_bool || std_char; + +template +inline constexpr bool rejects_arithmetic_for_boolean_or_character_v = + is_arithmetic_operation_v && + (is_boolean_or_character_v || is_boolean_or_character_v); + +template +inline constexpr bool has_non_void_common_rep_v = + has_common_rep && + !std::same_as, void>; + +template +inline constexpr bool has_same_underlying_category_v = + underlying::traits>::enabled && + underlying::traits>::enabled && + (underlying::traits>::kind == + underlying::traits>::kind); + +template +auto atomic_ref_load(T const &value, std::memory_order order) noexcept -> T { + assert_atomic_ref_compatible(); + // libc++ rejects std::atomic_ref; load through a non-mutating view. + auto &mutable_value = const_cast(value); + std::atomic_ref ref(mutable_value); + return ref.load(order); +} + +} // namespace mcpplibs::primitives::policy::details + export namespace mcpplibs::primitives::policy { namespace value { @@ -138,79 +211,6 @@ using error = error::throwing; using concurrency = concurrency::none; } // namespace defaults -namespace details { - -template > -struct atomic_ref_alignment_compatible : std::false_type {}; - -template -struct atomic_ref_alignment_compatible - : std::bool_constant<(alignof(T) >= - std::atomic_ref::required_alignment)> {}; - -template -inline constexpr bool atomic_ref_compatible_v = - atomic_ref_alignment_compatible::value; - -template constexpr void assert_atomic_ref_compatible() { - static_assert(std::is_trivially_copyable_v, - "concurrency::handler atomic access requires trivially " - "copyable CommonRep"); - static_assert( - atomic_ref_alignment_compatible::value, - "concurrency::handler atomic access requires alignof(CommonRep) to " - "satisfy std::atomic_ref::required_alignment"); -} - -template -concept has_underlying_rep_not_equal = - underlying_type && - requires(T const &lhs, T const &rhs) { - { - underlying::traits>::to_rep(lhs) != - underlying::traits>::to_rep(rhs) - } -> std::convertible_to; - }; - -template -inline constexpr bool none_compare_exchange_available_v = - has_underlying_rep_not_equal; - -template -inline constexpr bool is_arithmetic_operation_v = - operations::op_has_capability_v; - -template -inline constexpr bool is_boolean_or_character_v = std_bool || std_char; - -template -inline constexpr bool rejects_arithmetic_for_boolean_or_character_v = - is_arithmetic_operation_v && - (is_boolean_or_character_v || is_boolean_or_character_v); - -template -inline constexpr bool has_non_void_common_rep_v = - has_common_rep && - !std::same_as, void>; - -template -inline constexpr bool has_same_underlying_category_v = - underlying::traits>::enabled && - underlying::traits>::enabled && - (underlying::traits>::kind == - underlying::traits>::kind); - -template -auto atomic_ref_load(T const &value, std::memory_order order) noexcept -> T { - assert_atomic_ref_compatible(); - // libc++ rejects std::atomic_ref; load through a non-mutating view. - auto &mutable_value = const_cast(value); - std::atomic_ref ref(mutable_value); - return ref.load(order); -} - -} // namespace details - // Default protocol specializations. template struct type::handler { From 33d9eb9a6bbe4ca11e7a7a71ee23ccf16a15b765 Mon Sep 17 00:00:00 2001 From: FrozenLemonTee Date: Mon, 23 Mar 2026 23:27:07 +0800 Subject: [PATCH 14/14] refactor: Remove unused type aliases in operators module --- src/operations/operators.cppm | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/operations/operators.cppm b/src/operations/operators.cppm index 3ec2bf9..86bc2a6 100644 --- a/src/operations/operators.cppm +++ b/src/operations/operators.cppm @@ -510,9 +510,6 @@ constexpr auto apply_assign(Lhs &lhs, Rhs const &rhs) using lhs_value_type = lhs_traits::value_type; using lhs_value_policy = lhs_traits::value_policy; using lhs_rep = underlying::traits::rep_type; - using out_primitive = primitive_dispatch_result_t::value_type; - using common_rep = meta::traits::value_type; auto out = apply(lhs, rhs); if (!out.has_value()) {