Releases: sentomk/patternia
v0.9.0
Patternia v0.9.0
Patternia v0.9.0 is an API modernization and compiler compatibility release. It introduces PTN_WHERE and PTN_LET as named guard macros, removes the legacy bind() entry point and positional guard aliases, fixes callable guard evaluation on MSVC, and adds vcpkg packaging support.
Highlights
- Added
PTN_WHERE((names...), expr)for naming guard arguments without writing a lambda (supports 1 to 5 bound values). - Added
PTN_LET(name, expr)as single-value shorthand forPTN_WHERE((name), expr). - Added
is<T>,as<T>,alt<I>variable templates, replacing thetype::is<T>()/type::as<T>()/type::alt<I>()function syntax. - Added
$(pattern)callable syntax for$, replacingbind(pattern). - Added implicit
litwrapping sovalue >> handlerworks without explicitlit(value). - Removed
bind()entry point; use$instead. - Removed
_1,_2,_3guard aliases; usearg<N>orPTN_WHEREinstead. - Removed
type::namespace,ds<>(), chained match syntax, and variadicmatch(subject, cases...)entry. - Fixed callable guards failing to dispatch bound values in composed guard expressions (
&&,||) on all compilers. - Fixed
std::apply-based tuple guard calls producing ICEs on MSVC conformance builds. - Fixed
PTN_WHEREargument counting under MSVC traditional preprocessor mode. - Added vcpkg support (
vcpkg install patternia).
API Notes
Named guard with PTN_WHERE:
using namespace ptn;
struct Point { int x; int y; };
bool on_diagonal(const Point &p) {
return match(p) | on(
$(has<&Point::x, &Point::y>())[PTN_WHERE((x, y), x == y)] >> true,
_ >> false
);
}Single-value guard with PTN_LET:
using namespace ptn;
const char *bucket(int x) {
return match(x) | on(
$[PTN_LET(value, value < 0)] >> "negative",
$[PTN_LET(value, value < 10)] >> "small",
_ >> "large"
);
}Migration
- Replace
bind()/bind(subpattern)with$/$(subpattern):// before bind()[_0 > 0] >> [](int v) { return v; } // after $[_0 > 0] >> [](int v) { return v; }
- Replace
_1,_2,_3witharg<N>orPTN_WHERE:// before $(has<&Point::x, &Point::y>())[_1 == _2] >> "diagonal" // after $(has<&Point::x, &Point::y>())[PTN_WHERE((x, y), x == y)] >> "diagonal"
- Replace
type::is<T>()/type::as<T>()withis<T>/as<T>variable templates. - Replace
ds<&T::m...>()withhas<&T::m...>(). - Replace
match(subject, cases...)withmatch(subject) | on(cases...).
Performance
No performance regressions. Guard dispatch rewrites replace std::apply and std::invoke with direct index-sequence expansion, which generates identical or better codegen on MSVC.
Compatibility
This is a breaking release. The following APIs have been removed:
| Removed | Replacement |
|---|---|
bind() |
$ |
bind(subpattern) |
$(subpattern) |
_1 / _2 / _3 |
arg<N> or PTN_WHERE |
type::is<T>() / type::as<T>() |
is<T> / as<T> |
ds<&T::m...>() |
has<&T::m...>() |
match(subject, cases...) |
match(subject) | on(...) |
Chained .when(...).otherwise(...) |
match(subject) | on(...) |
Install
vcpkg install patterniafind_package(patternia CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE patternia::patternia)Docs
- Release note:
docs/changelog/v0.9.0.md
v0.8.3
Patternia v0.8.3
Patternia v0.8.3 is an API ergonomics release that introduces shorter, more expressive syntax for common pattern matching operations. All additions are backward-compatible; existing code continues to compile without changes.
Highlights
- Added
match(subject, cases...)as a unified entry point, eliminating the need for builder chains or the pipe operator. - Added
_as a wildcard alias for__. - Added
$as a concise shorthand forbind(). - Added
_0,_1,_2,_3as guard placeholder aliases forarg<0>througharg<3>. - Deprecated the bare
_guard placeholder (placeholder_t) in favor of_0. - Fixed
pred_and/pred_orfailing to unwrap tuple when invoking raw callables in mixed guard expressions (e.g.,_0 > 1u && is_even).
API Notes
Recommended form in v0.8.3:
match(x,
lit(1) >> 100,
lit(2) >> 200,
_ >> 0
);Value capture with guard:
match(x,
$[_0 > 0 && _0 < 10] >> [](int v) { return v * 2; },
_ >> 0
);All existing forms remain available:
match(x) | on(lit(1) >> 100, __ >> 0);
match(x).when(lit(1) >> 100).otherwise(0);Migration
- Replace
_in guard expressions with_0:// before bind()[_ > 0 && _ < 10] // after $[_0 > 0 && _0 < 10]
- No other changes are required. The old
_guard placeholder still compiles but emits a deprecation warning.
Performance
No performance changes in this release. The new match(subject, cases...) entry constructs the same tuple<Cases...> and selects the same dispatch_plan as the existing match(x) | on(...) path. Lowering behavior is identical.
Compatibility
- No forced migration is required.
__,bind(),arg<N>,type::is<T>(),type::as<T>()all remain available.- Guard placeholder
_is deprecated; use_0instead.
Docs
- Release note:
docs/changelog/v0.8.3.md
v0.8.2
Patternia v0.8.2
Patternia v0.8.2 is a performance and API refinement release focused on one goal: making keyed pattern chains behave much closer to hand-written switch code while keeping the optimization model scalable.
Highlights
- Introduced a lowering engine with a shared legality model:
fullbucketednone
- Added a switch-oriented static literal dispatch path for
lit<value>(). - Added reusable hot-path matcher forms:
static_on(...)PTN_ON(...)
- Unified static literal dispatch and variant dispatch under the same
dispatch_planmodel. - Public examples now prefer
match(x) | on(...). - Kept runtime literal factories for general-purpose matching:
lit(value)lit_ci(value)
Performance
The main benchmark for this release is a 128-way literal match, chosen to separate dispatch quality from matcher construction overhead.
Representative local results:
| Benchmark | Meaning | CPU time |
|---|---|---|
BM_PatterniaPipe_LiteralMatch128StaticCases |
prebuilt matcher object | 1.74 ns |
BM_PatterniaPipe_LiteralMatch128On |
raw inline on(...) |
17.9 ns |
BM_PatterniaPipe_LiteralMatch128OnMacro |
cached pipeline matcher via PTN_ON(...) |
2.09 ns |
BM_Switch_LiteralMatch128 |
hand-written switch baseline |
1.52 ns |
Takeaway:
- the static literal lowering path is now close to the
switchbaseline - the main remaining cost in raw inline
on(...)is matcher construction PTN_ON(...)recovers most of that gap while keeping pipeline syntax
API Notes
Recommended public forms in v0.8.2:
match(x) | on(
lit(1) >> 1,
__ >> 0
);For hot paths:
match(x) | PTN_ON(
lit<1>() >> 1,
lit<2>() >> 2,
__ >> 0
);Literal API split:
lit(value)for general runtime matchinglit_ci(value)for runtime case-insensitive string matchinglit<value>()for compile-time literal lowering
Compatibility
- No forced migration is required.
- Existing
on{...}call sites remain source-compatible. - Public examples and docs now prefer
on(...).
Docs
- Release note:
docs/changelog/v0.8.2.md - Performance note:
docs/performance/v0.8.2.md
v0.8.0
Patternia v0.8.0
Release Date: February 27, 2026
Type: API + Performance Release
Highlights
- Removed legacy terminal API (breaking):
match(x, cases(...)).end()
- Standardized recommended syntax:
match(x) | on{ ... };
- Introduced tiered variant dispatch:
hot_inline(small branch sets)warm_segmented(medium branch sets)cold_compact(large branch sets)
- Added compact index mapping and cold-path separation for large branch counts.
- Documentation updates:
- Refreshed v0.8.0 performance snapshot in
README.md - Added/updated performance notes under
docs/performance - Synced changelog and release index for 0.8.0
- Refreshed v0.8.0 performance snapshot in
Breaking Changes
Removed:
match(x, cases(...)).end()
Migration
Before
auto r = match(x, cases(
lit(1) >> [] { return 1; },
__ >> [] { return 0; }
)).end();After
auto r = match(x) | on{
lit(1) >> [] { return 1; },
__ >> [] { return 0; }
};Performance Notes
v0.8.0 focuses on variant dispatch improvements:
- Inline-oriented fast path for small alternative counts
- Segmented dispatch for medium alternative counts
- Compact-map + cold-path strategy for large alternative counts
- Per-alt narrowing in typed-variant dispatch to reduce irrelevant case scanning
Bench & Tooling
- Use
ptn_bench_variantfor variant-focused profiling. - Generate single-JSON visualization with
scripts/bench_single_report.py. README.mdnow includes benchmark intent, code shape, and interpretation for each variant benchmark group.
Compatibility
match(x) | on{...}remains the primary supported path.- Chained
.when(...).end()and.otherwise(...)are still available but marked as deprecating.
Full Changelog
docs/changelog/v0.8.0.mddocs/changelog/releases.md
v0.7.6
Patternia v0.7.6
Release date: 2026-02-21
Patternia v0.7.6 is a performance + benchmarking release focused on variant dispatch and practical benchmark workflows.
Highlights
-
Variant dispatch fast paths
- Added single-dispatch fast path for simple variant cases.
- Specialized simple dispatch by active variant index.
- Added prefilter path for mixed simple + guarded variant patterns.
- Simplified typed variant index-resolution internals.
-
Real-world variant benchmarks
- Added Protocol Router and Command Parser scenarios.
- Each scenario includes side-by-side implementations:
- Patternia
- if-else
- switch-case
- std::visit
-
Benchmark tooling
- Added
scripts/bench_single_report.pyfor single-JSON visualization. - Outputs chart + markdown + csv for easier local comparison.
- Added
-
Docs updates
- Moved latest benchmark snapshot to the top of README.
- Updated benchmark workflow docs and release index.
Compatibility
- API: unchanged for 0.7.x users.
- Source compatibility: unchanged.
- Runtime behavior: external semantics unchanged; optimizations are internal.
Full Changelog
- perf(variant): prefilter mixed guarded dispatch by active alt
- refactor(eval): simplify variant simple-dispatch index resolution
- feat(bench): add protocol router and command parser scenarios
- feat(scripts): add single-json benchmark visualization tool
- docs(readme): surface latest benchmark snapshot at top
Compare: v0.7.5...v0.7.6
v0.7.5-Hotfix
Patternia v0.7.5 (Hotfix)
Release date: February 18, 2026
Patternia v0.7.5 is a hotfix release for v0.7.4 focused on benchmark build compatibility.
Hotfix Summary
- Fixed variant benchmark registration that could fail to compile on MinGW toolchains.
- Replaced macro-as-argument benchmark registration with direct
BENCHMARK(...)->...chained configuration. - Preserved the same stable variant benchmark profile:
- nanosecond unit
- minimum run time
- repetitions
- aggregate-only reporting
- Adjusted alternating-hot microbench setup to avoid deprecated const-ref
DoNotOptimizeusage.
Impact
- API: no changes
- Runtime semantics: no changes
- Build/tooling: benchmark target now builds correctly on MinGW in scenarios where v0.7.4 could fail
Full Changelog
- Compare: v0.7.4...v0.7.5
v0.7.4
Patternia v0.7.4
Release date: February 18, 2026
Patternia v0.7.4 is a focused performance and engineering patch release for the 0.7.x line.
Highlights
- Reduced redundant binding work in guarded match evaluation paths.
- Reduced typed-eval overhead for zero-bind variant cases.
- Added guarded-path bind-count regression tests to ensure one-bind behavior on match.
- Added variant-focused microbench coverage and a more stable benchmark run profile.
- Improved CI with benchmark gate workflow and tighter default pipeline checks.
Compatibility
- No breaking API changes for 0.7.x users.
- Source compatibility remains unchanged.
- Runtime semantics remain consistent; internal evaluation paths are optimized.
Documentation
- Added dedicated release note:
docs/changelog/v0.7.4.md - Updated release index and README versioned benchmark/update sections.
Full Changelog
- Compare: v0.7.3...v0.7.4
v0.7.3
Patternia v0.7.3 Release Note
Date: February 16, 2026
🎆Happy Chinese NewYear!🎆
What's Changed
Performance: Reference-Oriented Binding
- Optimized
bind()/bind(subpattern)binding paths to avoid unnecessary value copies. - Structural member binding now prefers reference-oriented binding, improving heavy payload scenarios.
Heavy-Bind Benchmarking
- Added
BM_Patternia_PacketMixedHeavyBindandBM_Switch_PacketMixedHeavyBindfor copy-sensitive performance comparison. - Added benchmark result staging and comparison scripts:
scripts/bench_stage_results.pyscripts/bench_compare.py
Docs and Release Updates
README.mdnow includes v0.7.3 performance notes and heavy-benchmark workflow.- Added changelog page:
docs/changelog/v0.7.3.md - Updated release index and bumped project version to
0.7.3.
Full release notes: v0.7.3.md
v0.7.1
Patternia v0.7.1 Release Note
Date: February 7, 2026
What's Changed
Diagnostics Quality Improvements
This patch release focuses on clearer compile-time diagnostics and better developer guidance.
Highlights:
- Replaced generic
static_assertrequirement names (likeok) with semantic names - Added concise
Tip:hints to common match-builder diagnostics - Improved
type::is<T>()diagnostics for:- alternative type not found in
std::variant - duplicate alternative types (with guidance to use
type::alt<I>)
- alternative type not found in
No API or Runtime Behavior Changes
- API surface is unchanged
- Matching behavior is unchanged
- This is a developer-experience (
DX) patch release
Full release notes: v0.7.1.md
v0.7.0
Patternia v0.7.0 Release Note
Date: February 5, 2026
What's Changed
Variant Matching
Patternia now supports std::variant matching with a unified type-pattern system.
New/Updated APIs:
type::is<T>— type matchtype::as<T>— type match + bindingtype::alt<I>— index-based match (supports duplicated types)
Example:
auto r = match(v)
.when(type::is<int>() >> "int")
.when(type::as<std::string>() >> [](const std::string &s) { return s; })
.when(__ >> "other")
.end();Guards on Binding Type Patterns
Type patterns that bind can now participate in guards:
.when(type::as<std::string>()[ _ != "" ] >> [](const std::string &s) { ... })Diagnostics Improvements
- Shorter, clearer
static_assertmessages - Consistent diagnostic prefixes
- Structural
has<>members validated at match-time
Documentation Updates
- Variant matching docs expanded
- Binding/guard semantics clarified
- Navigation link fixes
Full release notes: v0.7.0.md