Skip to content

feat(guard): anchor PTN_BIND names to members - #47

Merged
sentomk merged 1 commit into
mainfrom
feat/member-anchored-placeholders
Aug 1, 2026
Merged

feat(guard): anchor PTN_BIND names to members#47
sentomk merged 1 commit into
mainfrom
feat/member-anchored-placeholders

Conversation

@sentomk

@sentomk sentomk commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Summary

Upgrade PTN_BIND placeholders from positional (arg_t<N>) to member-anchored (member_t<&Type::name>). Guards attached to has<...> rewrite each name to the position of its member in the pattern's member list at compile time, so names follow members — the order of member pointers in has<...> no longer matters. This also activates the previously documentary Type argument and resolves the deferred Type-validation roadmap item without static reflection.

Changes

  • PTN_BIND(Type, ...) now expands each name to constexpr member_t<&Type::name>; misspelled member names fail right at the macro line.
  • New compile-time machinery in guard.hpp: member_position (skips _ign slots) + resolve_expr/resolve_pred expression-tree rewriting; evaluation machinery untouched.
  • Resolution hooks: has_pattern::operator[] (non-binding path) and a new guard_resolver hook in binding_base.hpp, specialized for structural_bind_pattern (binding path).
  • _ keeps its positional meaning and mixes freely with member names.
  • Clear static_asserts when a name is missing from has<...> or used on a non-structural pattern.
  • Docs: docs/api.md PTN_BIND section rewritten (member semantics + PTN_ON capture caveat); roadmap WIP entry added and the deferred validation item marked resolved.

Testing

  • tests_named_placeholder.cpp rewritten for member semantics: type checks assert member_t<&T::m>; new cases cover order independence (has<&P::y, &P::x>), _ign slot skipping, mixed _ + member names, and the non-binding has<>[guard] path. Block-scope binds use ptn::on because PTN_ON's captureless caching lambda cannot capture block-scope names.
  • tests_destructure.cpp migrated from alias names to member names.
  • New compile-fail cases, each verified to fail with the intended diagnostic: member_placeholder_not_in_pattern, member_placeholder_non_structural, ptn_bind_unknown_member.
  • Full suite: 191/191 passing locally (GCC 13 + Clang 20, C++17).
  • clang-format clean on all touched files.

Notes

  • Breaking for alias-style PTN_BIND usage (placeholder names that were not real members): such declarations now fail at the macro line. Member-named usage is source-compatible with identical semantics when written in matching order.

Problem
- PTN_BIND names were positional (arg_t<N>), so their meaning
  depended on the order of member pointers in has<...>; the Type
  argument was documentary only and misspelled or mismatched names
  failed with indirect errors.

Implementation
- PTN_BIND now expands each name to member_t<&Type::name>, making
  Type meaningful: misspellings fail at the declaration line.
- Guards attached to has<...> rewrite member placeholders to the
  position of their member in the pattern's member list at compile
  time (resolve_pred over the expression tree), so names follow
  members regardless of has<...> order. Evaluation machinery is
  unchanged.
- _ign slots occupy no binding position; `_` keeps its positional
  meaning and mixes freely with member names.
- Clear static_asserts when a name is missing from has<...> or is
  used on a non-structural pattern.

Tests
- tests_named_placeholder rewritten for member semantics: type
  checks assert member_t<&T::m>; new cases cover order
  independence, _ign skipping, mixed `_` + names, and the
  non-binding has<>[guard] path.
- tests_destructure updated from alias names to member names.
- New compile_fail cases: name not in has<...>, member placeholder
  on a non-structural pattern, misspelled PTN_BIND member.
- Full suite: 191/191 (GCC 13 + Clang 20, C++17).

Notes
- Breaking for alias-style PTN_BIND usage (names that were not
  real members); such declarations now fail at the macro line.
- Block-scope PTN_BIND cannot be used inside PTN_ON (captureless
  caching lambda); documented in docs/api.md.
- docs/api.md + roadmap updated; the deferred Type-validation
  roadmap item is resolved without reflection.
@sentomk
sentomk force-pushed the feat/member-anchored-placeholders branch from 64d58b1 to 9210fd4 Compare August 1, 2026 07:58
@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.72093% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
include/ptn/pattern/modifiers/guard.hpp 70.83% 7 Missing ⚠️

📢 Thoughts on this report? Let us know!

@sentomk
sentomk merged commit cf12a25 into main Aug 1, 2026
22 checks 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