|
1 | | -## Plan: Policy 行为协议与分发规范 |
| 1 | +## Plan: 策略组一致性 + Primitive/Underlying 混合操作(增量) |
2 | 2 |
|
3 | | -基于现有 traits/concept 架构,采用“policy handler 协议 + 固定 dispatcher + primitive 路由层”的设计。type 协商前移到编译期静态决议,运行期 dispatcher 固定为三层并按外到内调用:concurrency -> value(已知 common type)-> error。第一阶段覆盖四则运算(加减乘除),错误通道统一为 expected 返回;跨底层类型运算由 type policy 在编译期决定“是否允许 + common type”;value 层负责溢出判定与值调整/错误下放且需要接收 concurrency 层注入;error 层按策略执行最终错误处理。用户扩展边界限定为仅可特化 policy handler,以保持上层接口可复用、低耦合且强约束。 |
| 3 | +本计划仅覆盖新增规则与新增重载,不重复已完成的分层协议与分发基建。 |
4 | 4 |
|
5 | | -**Steps** |
6 | | -1. 明确协议核心抽象(阻塞后续步骤) |
7 | | -2. 在 policy 层定义行为协议接口(依赖步骤 1) |
8 | | -3. 在 operations 层建立统一分发入口(依赖步骤 2) |
9 | | -4. 在 primitive 层实现运算路由与返回类型统一(依赖步骤 3) |
10 | | -5. 为跨类型运算定义 type policy 协商规则(依赖步骤 4,部分可与步骤 6 并行) |
11 | | -6. 建立编译期约束与诊断信息(依赖步骤 2,可并行于步骤 5) |
12 | | -7. 增加测试矩阵与示例验证(依赖步骤 4、5、6) |
13 | | -8. 文档化协议与扩展边界(依赖步骤 7) |
| 5 | +### A. 已确认规则(实现目标) |
| 6 | +1. 单个 `primitive` 的策略组规则保持不变 |
| 7 | + - 同类别策略标签重复时,编译期报错。 |
14 | 8 |
|
15 | | -**Phase 1: 协议基线(接口层)** |
16 | | -1. 在 [src/policy/traits.cppm](src/policy/traits.cppm) 复用 category 与 policy_type 概念,新增“行为协议概念”所需的基础类型约束(仅声明契约,不放具体行为)。 |
17 | | -2. 在 [src/policy/impl.cppm](src/policy/impl.cppm) 保留现有标签与 traits 特化,补充“策略能力声明位”对应的 traits 扩展位(用于编译期判定策略是否实现某 operation)。 |
18 | | -3. 新增 policy 协议模块(建议命名 mcpplibs.primitives.policy.handler),内容包含: |
19 | | -4. `policy_handler<Policy, OperationTag, Lhs, Rhs>` 主模板(默认禁用) |
20 | | -5. `policy_handler_available` 概念(用于约束上层调用) |
21 | | -6. 标准返回别名(统一为 expected 语义) |
22 | | -7. 明确用户扩展点:只允许特化 handler,不开放分发规则特化。 |
| 9 | +2. 两个 `primitive` 的策略组合并规则 |
| 10 | + - 先按默认策略补全四类策略(`value/type/error/concurrency`)。 |
| 11 | + - 补全后两边策略组必须完全一致(忽略声明顺序),否则编译期报错。 |
23 | 12 |
|
24 | | -**Phase 2: Operation 分发层(固定三层运行期链路)** |
25 | | -1. 在 [src/operations/impl.cppm](src/operations/impl.cppm) 维持 operation tag + arity 元数据,增加“可分发 operation”约束入口(例如合法 operation 概念)。 |
26 | | -2. 在 [src/operations/operators.cppm](src/operations/operators.cppm) 将 type 协商前移为编译期预处理,并实现运行期固定 dispatcher: |
27 | | -3. concurrency handler:负责并发包装(如加锁/解锁、内存屏障注入;具体机制可后续细化),并向 value 层注入并发执行上下文。 |
28 | | -4. value handler:接收已决议的 common type + concurrency 注入上下文,在 common type 上执行值域与溢出判定,决定“本层修正结果值”或“下放错误处理请求”。 |
29 | | -5. error handler:接收上层错误请求并按策略完成最终处理,统一映射到 expected 错误值。 |
30 | | -6. dispatcher 对外统一返回 expected,且不依赖具体 primitive 别名,仅依赖 traits 协议。 |
| 13 | +3. 两个 `primitive` 底层类型不同时的二元操作规则 |
| 14 | + - 先满足规则 2。 |
| 15 | + - `type::strict`:编译期拒绝。 |
| 16 | + - `type::compatible`:两侧 `underlying category` 必须一致,且 `common_rep_traits` 可用且推导结果非 `void`。 |
| 17 | + - `type::transparent`:忽略 `category`,但 `common_rep_traits` 必须可用且推导结果非 `void`。 |
31 | 18 |
|
32 | | -**Phase 3: Primitive 路由层(上层调用面)** |
33 | | -1. 在 [src/primitive/traits.cppm](src/primitive/traits.cppm) 复用 primitive_traits 与 resolve_policy_t,新增: |
34 | | -2. 跨类型运算协商 trait(由 type policy 决定是否允许、结果 common type) |
35 | | -3. 结果 primitive 重建工具(保持策略传播一致) |
36 | | -4. 在 primitive 对外运算入口中接入 operations dispatcher,覆盖加减乘除四个操作。 |
37 | | -5. 返回类型统一为 expected(成功值为 primitive,失败值为错误域类型)。 |
| 19 | +4. 不新增策略标签 |
| 20 | + - 维持 `compatible` / `transparent` 现有策略集合,不引入新 policy。 |
38 | 21 |
|
39 | | -**Phase 4: 聚合导出与契约稳定** |
40 | | -1. 在 [src/primitives.cppm](src/primitives.cppm) 增加新协议模块与分发层导出,保持聚合入口一致。 |
41 | | -2. 在 [src/policy/utility.cppm](src/policy/utility.cppm) 保持 common policy 选择逻辑不变,仅补充与 handler 可用性相关的辅助别名(若需要)。 |
| 22 | +### B. 新增范围:Primitive 与 Underlying 混合作为二元操作数 |
| 23 | +1. 在 `apply/operation` 层新增 `underlying` 参与重载 |
| 24 | + - 支持 `(primitive, underlying)`。 |
| 25 | + - 若是自由函数,必须同时支持 `(underlying, primitive)`(左右位置都可用)。 |
42 | 26 |
|
43 | | -**Phase 5: 验证与回归** |
44 | | -1. 在 [tests](tests) 新增 policy 行为协议测试: |
45 | | -2. handler 未实现时应在编译期失败(约束强) |
46 | | -3. 四则运算均返回 expected |
47 | | -4. 相同 type policy 下跨类型协商正确/错误路径正确 |
48 | | -5. 在 [examples/basic.cpp](examples/basic.cpp) 增加最小示例: |
49 | | -6. 默认策略下四则运算 |
50 | | -7. 自定义 policy handler 的单点扩展示例(仅特化 handler) |
| 27 | +2. 返回类型约束 |
| 28 | + - 算术类型操作结果始终返回 `primitive`(不返回裸 `underlying`)。 |
51 | 29 |
|
| 30 | +3. 策略选择约束 |
| 31 | + - 混合操作中仅有一个 `primitive` 时,`type` 策略取该 `primitive` 的策略。 |
| 32 | + - 其余策略(`value/error/concurrency`)同样取该 `primitive`,保持策略来源单一。 |
52 | 33 |
|
53 | | -**Interface Contracts(最小签名清单)** |
54 | | -1. Dispatcher 总入口(放在 [src/operations/operators.cppm](src/operations/operators.cppm)): |
55 | | -2. 输入:OperationTag、Lhs Primitive、Rhs Primitive、四类 policy(由 primitive_traits 解析)。 |
56 | | -3. 输出:expected<ResultPrimitive, ErrorPayload>。 |
57 | | -4. 约束:type 协商在编译期完成;运行期调用顺序固定为 concurrency -> value -> error。 |
58 | | -5. 编译期 type 协商合约(静态层,不进入运行期链路): |
59 | | -6. 输入:操作标签、Lhs/Rhs 静态类型信息、type policy。 |
60 | | -7. 输出:type_decision(is_allowed、common_type、diagnostic_id)。 |
61 | | -8. 责任:拒绝非法运算并确定 common_type;其结果作为运行期 value 层输入前提。 |
62 | | -9. concurrency handler 合约(放在 policy handler 模块): |
63 | | -10. 输入:operation_context、下一层 continuation、type_decision。 |
64 | | -11. 输出:concurrency_injection + 下一层 expected 透传能力。 |
65 | | -12. 责任:加锁/解锁、内存屏障、线程可见性包装;向 value 层注入并发执行上下文,不做值域判定。 |
66 | | -13. value handler 合约: |
67 | | -14. 输入:common_type 下的 lhs/rhs、operation_context、concurrency_injection。 |
68 | | -15. 输出:二选一路径: |
69 | | -16. 路径 A:直接给出成功值(已修正或原值)。 |
70 | | -17. 路径 B:下发 error_request(包含错误类别、上下文、候选回退值)。 |
71 | | -18. 责任:执行溢出/下溢/除零等值域检查,并决定是否本层修正。 |
72 | | -19. error handler 合约: |
73 | | -20. 输入:error_request + operation_context。 |
74 | | -21. 输出:expected<ResultPrimitive, ErrorPayload> 的最终错误分支或恢复成功值分支。 |
75 | | -22. 责任:按 error policy 落地处理(例如映射错误域、终止、抛错转译为 expected 错误值)。 |
76 | | -23. 跨层数据结构建议: |
77 | | -24. operation_context:封装 op tag、源 primitive traits、policy 句柄、调试标签。 |
78 | | -25. type_decision:封装 is_allowed、common_type、diagnostic_id。 |
79 | | -26. concurrency_injection:封装 guard_handle、memory_order/屏障策略、可选调度标签。 |
80 | | -27. value_decision:封装 has_value、value、error_request。 |
81 | | -28. error_request:封装 error_kind、reason、operation_context、可选 fallback。 |
82 | | -29. 扩展边界: |
83 | | -30. 用户只可特化三类运行期 handler(concurrency/value/error)与静态 type 协商策略实现,不可替换 dispatcher 顺序、不可改动跨层数据结构主骨架。 |
| 34 | +4. 底层类型推导约束 |
| 35 | + - 混合操作的 `underlying` 推导与“两侧都是 primitive”的规则一致: |
| 36 | + - 走相同的 `type` 协商路径,使用同一套 `common_rep_traits` 可用性与非 `void` 判定。 |
84 | 37 |
|
85 | | -**Relevant files** |
86 | | -- [src/policy/traits.cppm](src/policy/traits.cppm) — 复用并扩展 policy 概念边界,承载行为协议约束基础。 |
87 | | -- [src/policy/impl.cppm](src/policy/impl.cppm) — 保持标签定义,补充策略能力元信息挂点。 |
88 | | -- [src/policy/utility.cppm](src/policy/utility.cppm) — 与 common_policies 选择逻辑对齐,必要时提供 handler 检查辅助。 |
89 | | -- [src/operations/impl.cppm](src/operations/impl.cppm) — operation 元数据与分发前置约束。 |
90 | | -- [src/operations/operators.cppm](src/operations/operators.cppm) — dispatcher 核心实现位置。 |
91 | | -- [src/primitive/traits.cppm](src/primitive/traits.cppm) — policy 解析与跨类型协商 trait 的主落点。 |
92 | | -- [src/primitives.cppm](src/primitives.cppm) — 对外聚合导出。 |
93 | | -- [tests](tests) — 编译期约束与行为结果验证。 |
94 | | -- [examples/basic.cpp](examples/basic.cpp) — API 用法与扩展示例。 |
| 38 | +### C. 代码改动计划 |
| 39 | +1. `src/operations/dispatcher.cppm` |
| 40 | + - 增加“跨 primitive 策略组补全后一致”的编译期断言。 |
| 41 | + - 增加 `compatible` 下 `category` 一致性判定(与 `common_rep` 可用性判定协同)。 |
| 42 | + - 补齐 `common_rep` 非 `void` 的显式断言。 |
95 | 43 |
|
96 | | -**Verification** |
97 | | -1. 编译期契约验证: |
98 | | -2. 未提供对应 policy_handler 的 operation 调用必须报清晰静态断言。 |
99 | | -3. type policy 禁止的跨类型运算必须在编译期拒绝。 |
100 | | -4. 固定链路验证: |
101 | | -5. type 协商必须在编译期完成,运行期 dispatcher 必须按 concurrency -> value -> error 顺序调用,禁止跳层与重排。 |
102 | | -6. value 层必须验证“接收 concurrency 注入”这一前提生效。 |
103 | | -7. value 层“值修正”与“错误下放”两条路径都需覆盖测试。 |
104 | | -8. 行为一致性验证: |
105 | | -9. 四则运算对默认策略与自定义策略均返回 expected。 |
106 | | -10. 失败路径(溢出/除零/不兼容类型)按 error policy 语义编码到 expected 错误值。 |
107 | | -11. unchecked_value 路径验证: |
108 | | -12. 不触发 error policy,保持原生算术语义(含 UB 风险)并通过测试明确边界。 |
109 | | -13. 导出稳定性验证: |
110 | | -14. 通过聚合模块导入可直接访问 policy 协议、operation 分发、primitive 运算。 |
111 | | -15. 运行 tests 与示例构建,确认无回归。 |
| 44 | +2. `src/operations/operators.cppm` |
| 45 | + - 为自由函数 `apply/add/sub/mul/div/equal/not_equal/three_way_compare` 增加混合重载: |
| 46 | + - `(primitive, underlying)` 与 `(underlying, primitive)`。 |
| 47 | + - 保证非交换操作(如 `sub/div/<=>`)保留正确操作数顺序语义。 |
112 | 48 |
|
113 | | -**Decisions** |
114 | | -- 错误通道:默认路径统一返回 expected。 |
115 | | -- dispatcher 形态:type 协商前移到编译期,运行期固定三层链路 concurrency -> value -> error,不开放顺序重排。 |
116 | | -- 跨底层类型运算:由 type policy 在编译期决定可行性与 common type。 |
117 | | -- value 层职责:判定溢出并决定“本层值修正”或“下放 error 层处理”。 |
118 | | -- unchecked_value 语义:不做错误处理,不调用 error policy,行为尽量贴近原生 C/C++(包含 UB 风险)。 |
119 | | -- 扩展边界:仅开放 policy handler 特化,不开放分发规则。 |
120 | | -- 第一阶段覆盖范围:Addition/Subtraction/Multiplication/Division 全部纳入。 |
121 | | -- In scope:policy 行为协议、operation 分发、primitive 路由、测试与文档。 |
122 | | -- Out of scope:并发策略的运行时同步原语实现细节(atomic/lock-free/锁策略具体执行体)。 |
| 49 | +3. `src/primitive/impl.cppm`(如需) |
| 50 | + - 若存在 primitive access 的自由函数入口,同步补齐混合重载的左右位置版本。 |
| 51 | + - 成员函数形式的 access API 不做左右重载扩展。 |
123 | 52 |
|
124 | | -## Underlying Bridge Execution Contract (Runtime) |
| 53 | +4. `tests/basic/test_operations.cpp` |
| 54 | + - 新增混合重载测试: |
| 55 | + - `(primitive, underlying)` 与 `(underlying, primitive)` 都可编译并语义正确。 |
| 56 | + - 算术结果类型恒为 `primitive`。 |
| 57 | + - 策略组不一致时编译期失败。 |
| 58 | + - `strict/compatible/transparent` 下的跨底层类型判定符合规则 A-3。 |
125 | 59 |
|
126 | | -1. `dispatch` 在 value 阶段前统一执行 `to_rep`,将原始 value 映射到可协商的 `rep_type`。 |
127 | | -2. `type_handler` 的协商对象是 `lhs_rep/rhs_rep`,而非原始 value type。 |
128 | | -3. 若任一输入 `is_valid_rep(...) == false`,立即构造 `runtime_error_kind::domain_error` 并进入 error policy。 |
129 | | -4. 通过校验后执行 `from_rep -> to_rep` 规范化,再进入 value handler 与 op binding。 |
130 | | -5. 当前结果值仍按 `common_rep` 回传;comparison 最小闭环采用 `0/1` 表示(`static_cast<common_rep>(bool)`)。 |
131 | | -6. 本契约不改变 dispatcher 链路顺序,也不改变错误枚举体系。 |
| 60 | +### D. 验收标准 |
| 61 | +1. 所有新增约束均在编译期可判定,不引入运行期兜底分支。 |
| 62 | +2. 混合操作重载完整覆盖左右操作数位置(自由函数)。 |
| 63 | +3. 算术混合操作返回类型恒为 `primitive`。 |
| 64 | +4. 混合操作的 `type` 策略来源唯一且可预测(取 primitive 操作数)。 |
| 65 | +5. 与现有行为无回归,新增正反测试通过。 |
132 | 66 |
|
133 | | -**Further Considerations** |
134 | | -1. expected 的错误载体类型建议先统一为轻量错误枚举,再逐步演进到可扩展错误域,以减少首版模板复杂度。 |
135 | | -2. type policy 的 common type 规则建议先采用“显式白名单 + static_assert 诊断”,避免首版引入过宽的隐式提升。 |
136 | | -3. 后续可新增“native 快速路径”作为可选 API:当组合为 primitive<unchecked_value, transparent_type, single_thread> 时,提供非 expected 返回通道以最大化贴近原生 C/C++ 性能与行为。 |
137 | | -4. 后续可新增 C API 适配层(extern "C" 薄封装,POD 入参与返回值),内部复用 unchecked/native 路径,优先保障与现有 C 调用约定兼容。 |
0 commit comments