Skip to content

Refactor/cpp lab overhaul - #64

Merged
urbytes21 merged 20 commits into
masterfrom
refactor/cpp-lab-overhaul
Sep 15, 2026
Merged

urbytes21 merged 20 commits into
masterfrom
refactor/cpp-lab-overhaul

Conversation

@urbytes21

Copy link
Copy Markdown
Owner

No description provided.

urbytes21 and others added 20 commits July 27, 2026 09:18
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
Adding an example used to mean writing an IExample subclass, repeating the
group name, and remembering to add the file to a source list in CMake - a file
that was missing from the list simply never appeared in the menu. Menu entries
were also unordered, so the numbers changed between runs.

Framework (include/lab, src/lab):
- LAB_EXAMPLE("Name", "description" [, lab::kInteractive]) { ... } registers a
  file-local function before main() runs; the menu group is derived from the
  file's location, so ids like core/smart_pointer/Weak always match the tree.
- lab::Registry keeps examples sorted and rejects duplicate ids and invalid
  names instead of failing silently.
- Folder-style menu with search, plus a command line: --list, --run,
  --run-all, --list-ids, --plain, --mode, --version, --help.
- Logger gained LOG_FUNC/LOG_SECTION, colors only on a terminal, and a working
  Release build (the old release path could not compile LOG(string_view)).

Build:
- Example modules are globbed with CONFIGURE_DEPENDS, so no CMake edit is
  needed for a new example; OBJECT libraries keep the static registrations.
- Options: CPPLAB_BUILD_TESTS/DEMOS/GUI, CPPLAB_ENABLE_SANITIZERS,
  CPPLAB_WARNINGS_AS_ERRORS, ENABLE_COVERAGE. gtkmm-4.0 is now optional.
- Warnings, coverage and sanitizer flags moved to a cpplab::options target so
  they no longer apply to GoogleTest.
- One ctest smoke test per non-interactive example, discovered at test time.

Examples: all ~100 rewritten with a "what you will learn" header, sections,
fixed bugs (leaks in Command/Memento/Visitor, Builder's build() leaving a null
product, iterator vs nullptr comparison in UnorderedMap, wrong labels in
TemplateMethod, Dollars->Cents conversion, showpos demo, wcout/cout mixing,
a global set_terminate that stayed installed) and modern C++ (unique_ptr
ownership, ranges, concepts, std::format, jthread, variant). Examples no
longer execute undefined behavior or leave files behind, so the whole suite
passes under ASan/UBSan.

Sockets: TCPServer/TCPClient now report errno through std::system_error, close
their sockets exactly once, can stop a blocked accept(), and support port 0;
the new LoopbackEcho example runs a server thread and a client in one process.

Also: PID controller uses a unique_ptr pimpl and validates its parameters,
tests cover the framework, the PID and GoogleTest/GoogleMock usage, and the
GTK apps escape user text before building Pango markup.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
- README: quick start, menu and command line, how to add an example, build
  options, testing (including sanitizers and valgrind), static analysis,
  coverage, the standalone programs, VS Code debugging, Docker and
  troubleshooting.
- docs/adding-examples.md: the anatomy of an example, LAB_EXAMPLE, logging,
  conventions (anonymous namespaces, no undefined behavior, temp files) and
  how to add a new module.
- docs/README.md now indexes every topic; new READMEs for basics, datatype,
  function, linkage, smart_pointer, string, exception, concurrency and
  controller, and example tables in the existing ones.
- CLAUDE.md describes the framework, the house rules for examples and the
  traps found while working here (cppcheck needs -I include, .clang-format
  must stay on c++20 or it mangles digit separators).
- scripts/new_example.sh scaffolds an example from a template; run.sh also
  runs the tests; the coverage scripts use ENABLE_COVERAGE and their own
  build directory.
- CI runs cppcheck with the shared suppression list and adds a second job
  that builds with sanitizers and runs the whole suite again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
- ENABLE_COVERAGE now compiles with -fprofile-update=atomic. The RaceCondition
  example increments a counter from several threads on purpose, which also
  raced gcov's counters and made lcov abort with "unexpected negative count".
- The coverage scripts use their own build-coverage directory, build in
  parallel, and only open the HTML report when a desktop session is present
  (and never fail because of it). lcov now reports 90.8% line coverage.
- --run-all with a filter that matches nothing says so instead of printing
  "Ran 0 example(s)".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
clang-tidy found real issues and a lot of noise that comes from the teaching
style of the examples.

Fixed:
- Adapter rounded money with (x + 0.5) instead of std::lround.
- Builder used rfind(..., 0) != 0 instead of starts_with, and built its
  description with temporary strings.
- Unique used reset(new T) where make_unique is the point of the example.
- Stack had a nested conditional operator; Internal.cpp and ThrowNoexcept used
  names that do not follow the project's own naming rules.
- LAB_EXAMPLE now parenthesizes its macro arguments.
- CString's strncat truncation demo silences -Wstringop-truncation locally: it
  only fires in optimized builds, and truncating is exactly what it shows.

Configured:
- .clang-tidy disables the checks that contradict the didactic style (copies
  that show a constructor call, moved-from objects that are inspected, explicit
  types, recursion, std::bind, ...) and explains each one. The explanation sits
  above the list, because a YAML folded scalar cannot contain comments - inside
  it the "comments" silently became part of the check names.
- abseil-* checks removed: this project does not use abseil.

CI gained a Release job with -Werror; optimized builds report diagnostics that
a Debug build never shows (that is how the strncat warning surfaced).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
Eight stages from initialization to sockets and firmware, with the take away
for each example, so the lab can be worked through in a sensible order instead
of alphabetically.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
Replace rfind(x, 0) == 0 with starts_with, std::string_view::npos for
option.npos, rename the command line lambdas and the local error message to
lower_case, pass the MVC widget colour by value, reserve in the registry test
helper, give FakeTurtle's switch a default case, and rename the Logger's
source_location parameter to loc so the declarations fit in 80 columns.

tests/dummy keeps scratch code exactly as it is written upstream, so a local
.clang-tidy disables every check there instead of reformatting it.

Also run clang-format over the tree: nine files had drifted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
cmake/Docs.cmake adds an optional "docs" target that fills docs/Doxyfile.in
into build/Doxyfile and runs Doxygen: the README is the front page, the guides
and module READMEs become related pages, and every source file is browsable and
cross-linked. The target only exists when doxygen is installed, and it is not
part of "all".

.github/workflows/docs.yml builds the site on every push and pull request with
CPPLAB_DOCS_WARNINGS_AS_ERRORS=ON and deploys it to GitHub Pages from master.
docs/doxygen.md explains the local workflow, the one-time Pages setup and how
to point the GitHub wiki at the result; scripts/publish_wiki.sh generates that
wiki Home page.

The Markdown needed small fixes to parse cleanly: Doxygen wants a blank line
before a fenced code block, reads a bare <random> in prose as an HTML tag and
rejects a fence that hangs off a list item.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
Audit of every module against the feature lists of C++11 to C++23, written up
in docs/cpp-standards-coverage.md: 48 topics had no example. Each one now has a
file that states what it should teach, prints that outline when it runs, and is
registered with the new lab::kDraft flag, so the menu and --list mark it
[draft] and the ctest smoke tests still cover it.

The gaps were, by module: a whole templates module (function and class
templates, specialization, NTTPs, concepts, SFINAE, CRTP, variable templates,
two-phase lookup), move semantics and perfect forwarding, inheritance,
abstract interfaces, static members, deducing this, attributes, literals,
std::byte and <bit>, list/forward_list/map/multimap/unordered_set/flat_map,
tuple, any, bitset, random, expected, numeric, ranges, source_location, span,
mdspan, the <utility> helpers, atomic, shared_mutex, latches and barriers,
coroutines, parallel algorithms, error codes, the ODR, modules, std::print,
the Interpreter pattern and the pImpl and type-erasure idioms.

scripts/new_example.sh --draft scaffolds the same shape for a new topic.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsQ7AcLHafb1tAgosoJFz
@urbytes21
urbytes21 deployed to github-pages September 12, 2026 02:19 — with GitHub Actions Active
@urbytes21
urbytes21 merged commit 2ae8b98 into master Sep 15, 2026
4 checks passed

This branch was successfully deployed

1 active deployment
github-pages — 5dedfa88 Deployed Sep 12, 2026 by urbytes21 via docs #1
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