Skip to content

feat(solutions+ci): add reference solutions and dslings build CI for cpp11#44

Merged
Sunrisepeak merged 1 commit intomainfrom
feat/solutions-and-dslings-ref-ci
Apr 25, 2026
Merged

feat(solutions+ci): add reference solutions and dslings build CI for cpp11#44
Sunrisepeak merged 1 commit intomainfrom
feat/solutions-and-dslings-ref-ci

Conversation

@Sunrisepeak
Copy link
Copy Markdown
Member

Summary

Adds a solutions/ mirror of dslings/ containing canonical, fully-compilable reference answers for every cpp11 exercise, and a CI workflow that builds + runs them through the same xmake d2x-buildtools plugin path that d2x checker uses internally.

Why

Practice files under dslings/ are intentionally broken (D2X_YOUR_ANSWER placeholders + deliberate compile/runtime bugs), so they can't be used directly for build CI. Reference solutions give CI a known-passing endpoint per exercise:

What's in this PR

  • solutions/cpp11/<NN>-<feat>-<K>.cpp — 47 reference answers, one per practice file. Each is the practice file with all D2X_YOUR_ANSWER filled in, all intentional bugs fixed, and D2X_WAIT removed. All D2X_DONT_DELETE_THIS(x) calls and d2x_assert* checks are preserved byte-for-byte from the practice (no expected-value tampering).

  • solutions/cpp11/xmake.lua — mirrors dslings/cpp11/xmake.lua. Each target carries a -ref suffix so it coexists with the practice target (e.g. cpp11-13-long-long-0 and cpp11-13-long-long-0-ref). Per-target flag overrides (-fno-elide-constructors, -Wpedantic -Werror, set_languages("c++17")) are mirrored.

  • solutions/xmake.lua — top-level loader. Only includes cpp11 today; cpp14/17/20/23 will follow as those chapters get written.

  • xmake.lua — one-line addition: includes("solutions/xmake.lua").

  • .github/workflows/dslings-ref-ci.yml — runs on push/PR/dispatch when dslings/, solutions/, d2x/, or xmake.lua change. Installs pinned xlings 0.4.3 + xmake, then:

    1. Lists every *-ref target via xmake d2x-buildtools --command=list
    2. Builds each via xmake d2x-buildtools --command=build
    3. Runs each and asserts no and no stray D2X_WAIT
    4. Lints that every dslings/*.cpp has a paired solutions/*.cpp (warning during bring-up; can tighten to error later)

    The workflow uses the same plugin entry point (d2x/buildtools/xmake/main.lua) that d2x checker uses internally, so a green CI here is exactly what a learner would see if they ran d2x checker cpp11-XX-feat-K-ref on every solution locally.

Test plan

Local clean-cache sweep through all 47 reference targets via the d2x-buildtools path:

  • xmake clean -a && xmake f -y succeeds
  • All 47 *-ref targets build successfully
  • All 47 produce only at runtime — 0 , 0 stray D2X_WAIT
  • Existing dslings/ practice files still produce their intentional teaching errors (didn't break the student experience)
  • Asserts preserved byte-identical: spot-checked 5 trap exercises (08, 10, 11, 17, 05), only differences are added explanatory comments
  • Negative tests pass: a deliberately-wrong solution produces and CI exits 1; a stray D2X_WAIT triggers the residue check and CI exits 1
  • YAML syntax of the new workflow is valid (yaml.safe_load)

Trap exercises — how each was solved

  • 08-literal-type-0: std::string is not a literal type in C++17. Removed constexpr from the std::string chain; kept it on the char/int/std::array chain and called to_array("123") directly so the constexpr arm still demonstrates compile-time computation.
  • 10-delegating-constructors-0: 1-arg → 2-arg → 3-arg delegation. Counter increments 0→3→5→6 to match the existing d2x_assert_eq values.
  • 11-inherited-constructors-2: deliberately did not declare move ops, so std::move(p3) falls back to copy — that's the teaching point.
  • 17-pod-type-0: ok = !std::is_trivial<C>::valueC has a virtual function so it's not trivial; the assert wants ok == true.
  • 15-variadic-templates-0/1: standard C++11 recursive base case + variadic recursion.
  • 05-move-semantics-0: copy ctor transfers via const_cast so all three == asserts on data_ptr() hold and there's exactly one alloc/free.
  • 06-scoped-enums-0: Color::ORANGE renamed to ORANGE_COLOR to dodge the unscoped/scoped collision.

Notes & follow-ups

  • cpp14/17/20/23 to follow when those chapters are added.
  • The solutions ↔ dslings filename-parity step is a soft warning during bring-up. After cpp11 stays at 100% coverage for a release cycle, flip it to an error so missing solutions block merges.
  • This is the second consumer of pinned xlings 0.4.3 (after ci: pin xlings to 0.4.3 and simplify install step #43's online-ebook update). If we end up with 3+ workflows installing xlings, worth extracting into a composite action.

…cpp11

Adds a `solutions/` mirror of `dslings/` containing canonical, fully-compilable
reference answers — one per cpp11 exercise — and wires up a CI workflow that
goes through the same `xmake d2x-buildtools` plugin path that `d2x checker`
uses internally to build and run every reference target.

## Why

Exercise files under `dslings/` are intentionally broken (D2X_YOUR_ANSWER
placeholders, deliberate compile/runtime bugs) so students can fix them. That
made it impossible to have a build CI that catches infrastructure drift —
e.g. issue #37 where `dslings/en/cpp11/xmake.lua` had silently lost
`set_languages("c++17")` for the literal-type-0 target. Reference solutions
solve this by giving CI a known-passing endpoint per exercise:

- Any drift in xmake target / include paths / language standard surfaces as a
  build failure
- Any teaching mistake (the canonical answer can't actually pass its own
  d2x_assert checks) surfaces as a runtime failure
- Future zh ↔ en drift gets flagged early

## What's in this PR

- `solutions/cpp11/<NN>-<feat>-<K>.cpp` — 47 reference answers (one per
  practice file). Each is the practice file with all D2X_YOUR_ANSWER
  replaced, all intentional bugs fixed, and `D2X_WAIT` removed. All
  `D2X_DONT_DELETE_THIS(x)` calls and `d2x_assert*` checks are preserved
  byte-for-byte from the practice version.
- `solutions/cpp11/xmake.lua` — mirrors `dslings/cpp11/xmake.lua` with each
  target carrying a `-ref` suffix to coexist with the practice targets
  (e.g. `cpp11-13-long-long-0` and `cpp11-13-long-long-0-ref`). Per-target
  flag overrides (`-fno-elide-constructors`, `-Wpedantic -Werror`,
  `set_languages("c++17")`) are mirrored.
- `solutions/xmake.lua` — top-level loader that pulls in cpp11 (other
  chapters can be added later).
- `xmake.lua` — one-line addition: `includes("solutions/xmake.lua")`.
- `.github/workflows/dslings-ref-ci.yml` — runs on push/PR/dispatch when
  any of `dslings/`, `solutions/`, `d2x/`, `xmake.lua` change. Installs
  pinned xlings 0.4.3 (matching the online-ebook workflow) + xmake, then:
    1. Lists every `*-ref` target via `xmake d2x-buildtools --command=list`
    2. Builds each via `xmake d2x-buildtools --command=build`
    3. Runs each and asserts no `❌` and no stray D2X_WAIT
    4. Lints that every dslings .cpp has a paired solutions/ counterpart
       (warning during bring-up; can tighten to error later)

  The workflow uses the same plugin entry point (`d2x/buildtools/xmake/main.lua`)
  that `d2x checker` uses internally, so a green CI run is what a student
  would see locally if they ran `d2x checker cpp11-XX-feat-K-ref` on
  every solution.

## Local verification

Clean rebuild + full sweep of all 47 reference targets via the d2x-buildtools
path, on a clean cache:

    PASS: 47 / 47
    FAIL: 0

Verified that:
- Existing dslings practice files still produce their intentional teaching
  errors (didn't accidentally break the student experience).
- Asserts in solutions are byte-identical to dslings (no expected-value
  fudging — checked with `diff` on assert/D2X_DONT_DELETE_THIS lines).
- Negative tests: a deliberately wrong solution produces ❌ and CI exits 1;
  a stray D2X_WAIT triggers the residue check and CI exits 1.

## Notes & follow-ups

- cpp14 / cpp17 / cpp20 / cpp23 will follow as those chapters get filled
  in. The `solutions/xmake.lua` only includes cpp11 right now.
- The new workflow file is the second consumer of pinned xlings 0.4.3
  (after PR #43's online-ebook update). If we end up with 3+ workflows
  using the same install snippet, worth extracting it into a composite
  action.
- The `solutions ↔ dslings filename parity` step is a soft warning during
  bring-up. Once cpp11 stays at 100% coverage for a release cycle, flip it
  to an error so missing solutions block merges.
@Sunrisepeak Sunrisepeak merged commit 0eddec0 into main Apr 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant