88
99---
1010
11- ## 1. 布局
11+ ## 1. 布局(第二轮重排后:库入驻 d2x/、课程收进 src/)
1212
1313```
14- mcpp.toml workspace = [harness, intro, cpp11, cpp14, en/*, d2x/buildtools/mcpp]
15- harness/ 练习脚手架包(纯模块 d2x.harness,零宏)
16- intro/tests/hello-mcpp.cpp
17- cpp11/tests/<NN-topic>/<K>.cpp 49 题
18- cpp14/tests/00-generic-lambdas/{0,1}.cpp
19- en/{intro,cpp11,cpp14}/ en 镜像工程(lang=en 时启用,与 zh 互斥)
14+ mcpp.toml workspace = [d2x, src/*, src/en/*, d2x/buildtools/mcpp]
15+ d2x/ d2x 练习库(纯模块 `import d2x;`,零宏)
16+ d2x/buildtools/mcpp/ Provider(C++26)
17+ src/intro/tests/hello-mcpp.cpp
18+ src/cpp11/tests/<NN-topic>/<K>.cpp 49 题
19+ src/cpp14/tests/00-generic-lambdas/{0,1}.cpp
20+ src/en/{intro,cpp11,cpp14}/ en 镜像工程(lang=en 时启用,与 zh 互斥)
2021solutions/<std>/<NN-topic>/<K>.cpp 52 份(zh/en 共用,含 hello-mcpp)
21- d2x/buildtools/mcpp/ Provider(C++26)
2222```
2323
2424- ** 零生成物** :` .d2x/build/ ` 及三套清单生成已删除;` .d2x/ ` 下只剩学习进度
@@ -28,26 +28,38 @@ d2x/buildtools/mcpp/ Provider(C++26)
2828## 2. 双入口
2929
3030```
31- mcpp test -p cpp11 原生:进度表
32- mcpp test -p cpp11 00-auto 原生:单题(子串过滤)
33- d2x checker 闯关:文件监听、通过自动推进(已实测:改对
34- hello-mcpp 后自动进入 cpp11-00-auto-and-decltype-0)
31+ mcpp test -p src/cpp11 原生:进度表(-p cpp11 的 basename 简写同样可用)
32+ mcpp test -p src/cpp11 00-auto 原生:按子串过滤(匹配整章;更长的名字如
33+ 00-auto-and-decltype/3 即单题)
34+ d2x checker 闯关:文件监听、通过自动推进(已实测:改对
35+ hello-mcpp 后自动进入 cpp11-00-auto-and-decltype-0)
3536```
3637
3738同一条链路:` d2x checker → Provider → mcpp test --message-format json → 判定 ` ;
3839Provider 只是把 mcpp 的 JSON 记录 × 侧信道合并成协议 verdict。
3940
40- ## 3. harness (` import d2x.harness; ` )
41+ ## 3. d2x 库 (` import d2x; ` ,包与模块同名,住在 ` d2x/ ` )
4142
4243| 设施 | 说明 |
4344| ---| ---|
4445| ` d2x::check(cond, "原文") ` / ` check_eq(a, b, "a == b") ` | 第三参是给学习者看的表达式原文(迁移脚本自动从宏参数生成,教学输出零漂移);` std::formattable ` 探测转印值(SFINAE 安全,requires 里直接写 std::format 会踩未特化 formatter 的 static_assert) |
4546| ` D2X_YOUR_ANSWER ` | ** 纯约定,无定义** 。裸标识符的编译报错正好指着要填的位置 |
46- | ` d2x::wait() ` | 路障;记录后继续执行(后续断言照跑 ) |
47+ | ` d2x::wait() ` | 路障;记录后继续执行(后续检查点照跑 ) |
4748| ` d2x::dont_delete_this(expr) ` | 恒等透传(旧 D2X_DONT_DELETE_THIS) |
48- | 退出码 | 首次调用注册 atexit:有失败断言或未拆 wait → ` _Exit(1) ` 。裸 ` mcpp test ` 因此天然能判对错 |
49+ | 退出码 | 首次调用注册 atexit:有失败检查点或未拆 wait → ` _Exit(1) ` 。裸 ` mcpp test ` 因此天然能判对错 |
4950| 侧信道 v2 | ` {"v":2,"kind":"assert","ok":…,"what":…,"expected":…,"actual":…,"file":…,"line":…} ` / ` {"v":2,"kind":"wait",…} ` ;` D2X_RESULT_FILE ` 未设置时不写文件 |
5051
52+ ** 可见输出(去 HONLY 后的日志标识——emoji 即标识,无框架前缀)** :
53+
54+ ```
55+ ✅ | a == a1 (1 == 1) 绿
56+ ❌ | a == b (1 == 2) --> src/cpp11/tests/.../0.cpp:38 红
57+ 🚧 | Delete the d2x::wait() to continue --> <file>:<line> 黄
58+ ```
59+
60+ 失败/路障行带定位;路径经 cwd 剥离尽量以仓库相对形式展示(定位用的
61+ 绝对路径仍走侧信道,展示归展示、定位归定位)。
62+
5163** 判定顺序(注意与设计稿 §5 的一处刻意调整)** :失败断言 → fail;` wait ` → blocked;
5264退出码非 0 → fail;无侧信道 → 退出码 0 即 pass。` wait ` 判定** 先于** 退出码——
5365新 harness 里 wait 会把退出码顶成 1,按旧顺序 blocked 会全部误判成 fail。
0 commit comments