Skip to content

Migrate to C++20#20

Open
gitosaurus wants to merge 7 commits into
feature/sitrepfrom
cxx20-update
Open

Migrate to C++20#20
gitosaurus wants to merge 7 commits into
feature/sitrepfrom
cxx20-update

Conversation

@gitosaurus

Copy link
Copy Markdown
Owner

Stacked on #19 (feature/sitrep). Bumps the project from C++11 straight to C++20 and applies the features that improve readability, folding in the C++17 backlog previously catalogued in cpp17_migration.md (now superseded).

Commits

  • Compile as C++20CMAKE_CXX_STANDARD 20; warning-free with zero source changes on both Apple clang 21 and Alpine GCC (Docker driver build).
  • C++20 library idiomscontains() for membership, starts_with/ends_with replacing find/rfind arithmetic, std::erase_if replacing hand-rolled erase loops in Wellspring::close and remove_fillers, std::ranges algorithms.
  • Language features — defaulted Token::operator== (synthesized !=), using enum collapsing 146 Keywords:: qualifications in Expression.cc, if-with-initializer for the find-then-test idiom, structured bindings for map iteration, std::views::keys for key-only loops.
  • API shapesstring_view on the four byte-scanning helpers, optional<string> for identifier_of, std::filesystem path assembly in Wellspring, [[nodiscard]] on parser predicates and storage status returns — which flushed out four silently discarded insistOn results in Universe.cc, now explicit early returns (behavior unchanged; stopLooking() already doomed those parses).
  • std::format for diagnostics and constexpr constants.
  • Token.cc impossible-case cleanupbreak instead of incidental fallthrough after assert(0).
  • -Wall -Wextra enabled permanently — zero warnings; a trial with -Wimplicit-fallthrough (which GCC folds into -Wextra) is also clean, so the Alpine Docker build stays warning-free.

Verification

  • ./build/archetype --test: 15/15 suites pass after every commit.
  • End-to-end: compile gorreven to .acx, --perform, --update --input=look --sitrep, --inspect --full, and a bare relative --source path (exercises the new fs::path search).

🤖 Generated with Claude Code

gitosaurus and others added 7 commits June 11, 2026 17:24
Apple clang 21 (local) and Alpine GCC (drivers/Dockerfile) both fully
support C++20; the build is warning-free without source changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Membership tests on maps and sets say contains() instead of
  count() > 0 or find() != end().
- String prefix/suffix checks use starts_with/ends_with in place of
  find/rfind arithmetic (option scanning, .acx extension, path slash).
- Wellspring::close and remove_fillers collapse hand-rolled
  find-and-erase / erase-remove loops into std::erase_if.
- Whole-container algorithm calls use std::ranges (find, copy).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Token gets a defaulted operator== (operator!= is synthesized);
  the hand-written non-member comparisons are gone.
- using enum collapses 146 Keywords:: qualifications in Expression.cc
  and the Token type names in Token.cc's inserter.
- The find-then-test idiom becomes if-with-initializer throughout,
  scoping each iterator to the test that uses it (Object, Universe,
  Wellspring, SystemObject, Expression, inspect_universe, main).
- Map iteration uses structured bindings instead of .first/.second;
  key-only loops view the map through std::views::keys.
- Boolean option flags use the count returned by map::erase directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The byte-scanning helpers escape_string, escape_literal, uri_encode,
  and sanitize_local_name take std::string_view; each only inspects
  characters and returns a fresh string. The polymorphic UserOutput
  hierarchy deliberately keeps std::string.
- identifier_of returns std::optional<std::string> instead of using
  the empty string as a not-found sentinel.
- Wellspring assembles candidate paths with std::filesystem::path
  instead of manual '/' splicing; the default .arch extension now
  hangs off fs::path::extension.
- TokenStream::fetch/insistOn, the make_expr/make_statement factories,
  and FileStorage::ok are [[nodiscard]]. The warning flushed out four
  silently discarded insistOn results in Universe.cc, which now stop
  object/type declaration explicitly (stopLooking() already doomed the
  parse, so behavior is unchanged but visible).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Error and status messages assemble with std::format instead of
  string concatenation chains.
- uri_encode drops the ostringstream/setw/setfill/hex dance for a
  single format("%{:02x}") per escaped byte.
- VersionString is a constexpr string_view; IdIndex::npos and
  DefaultMethod are constexpr.
- CLAUDE.md now says C++20.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The outer switch already printed RESERVED_WORD and PUNCTUATION, so the
inner switch keeps their labels only to stay exhaustive for -Wswitch.
Falling through to print "identifier" was never the intent; if the
impossible happens in a release build, exit the switch instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The only warnings these flags surfaced were -Wunused-parameter on
interface defaults and one-directional storage stubs, where ignoring
the argument is the point. Commenting out those parameter names keeps
the documentation and makes the build warning-free on Apple clang;
a trial with -Wimplicit-fallthrough (which GCC folds into -Wextra)
also comes back clean, so the Alpine Docker build will too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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