Skip to content

v0.9.0

Choose a tag to compare

@sentomk sentomk released this 13 Mar 13:25
· 88 commits to main since this release

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 for PTN_WHERE((name), expr).
  • Added is<T>, as<T>, alt<I> variable templates, replacing the type::is<T>() / type::as<T>() / type::alt<I>() function syntax.
  • Added $(pattern) callable syntax for $, replacing bind(pattern).
  • Added implicit lit wrapping so value >> handler works without explicit lit(value).
  • Removed bind() entry point; use $ instead.
  • Removed _1, _2, _3 guard aliases; use arg<N> or PTN_WHERE instead.
  • Removed type:: namespace, ds<>(), chained match syntax, and variadic match(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_WHERE argument 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, _3 with arg<N> or PTN_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>() with is<T> / as<T> variable templates.
  • Replace ds<&T::m...>() with has<&T::m...>().
  • Replace match(subject, cases...) with match(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 patternia
find_package(patternia CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE patternia::patternia)

Docs

  • Release note: docs/changelog/v0.9.0.md