Patternia API Reference¶
Overview¶
Patternia exposes one public matching shape:
match(subject) | on(
case_1,
case_2,
_ >> fallback
)
The pipeline is immediate. There is no deferred builder stage.
match(subject)¶
match(subject) creates the evaluation context for one subject value.
int x = 7;
auto r = match(x) | on(
lit(7) >> 1,
_ >> 0
);
Rules:
subjectmust be an lvalue.- Cases are evaluated in source order.
- Matching uses first-match-wins semantics.
on(case1, case2, ...)¶
on(...) groups the case list consumed by match(subject).
match(x) | on(
lit(1) >> "one",
lit(2) >> "two",
_ >> "other"
);
Rules:
- The last case must be a wildcard fallback.
- Each entry must be a
pattern >> handlercase expression. - Unreachable wildcard/alt ordering errors are diagnosed at compile time.
pattern >> handler¶
This is the core case-expression form.
lit(1) >> 42
$(is<int>) >> [](int v) { return v * 2; }
$(has<&Point::x, &Point::y>) >> [](int x, int y) { return x + y; }
Handler forms:
pattern >> valuepattern >> callable
Bindings are determined entirely by the pattern.
Wildcard _¶
_ is the public wildcard and fallback pattern.
match(x) | on(
lit(1) >> "one",
_ >> "other"
);
The wildcard does not bind values by itself.
Literal Patterns¶
lit(value)¶
Runtime literal match.
match(x) | on(
lit(5) >> 42,
_ >> -1
);
val<value>¶
Compile-time literal match. Useful when the literal is known at compile time and the lowering engine can consider static dispatch.
match(x) | on(
val<1> >> 1,
val<2> >> 2,
_ >> 0
);
lit_ci(value)¶
Runtime ASCII case-insensitive string match.
match(s) | on(
lit_ci("hello") >> 1,
_ >> 0
);
Binding Patterns¶
$ and $(...)¶
Patternia keeps binding explicit.
$ // bind the whole subject
$(subpattern) // bind under a subpattern
Examples:
match(x) | on(
$ >> [](int v) { return v; },
_ >> 0
);
match(v) | on(
$(is<std::string>) >> [](const std::string &s) {
return s.size();
},
_ >> 0
);
Binding rules:
- No pattern binds implicitly.
- Handler parameters follow binding order.
- Patterns that do not bind produce zero-argument handlers.
Guard Attachment []¶
Attach a guard to a binding pattern with pattern[guard].
match(x) | on(
$[PTN_LET(value, value > 0 && value < 10)] >> "small",
_ >> "other"
);
Guard evaluation order:
- Match the pattern.
- Bind values.
- Evaluate the guard.
- Invoke the handler if the guard passes.
A guard failure only rejects the current case.
Guard Helpers¶
_0¶
Placeholder alias for a single bound value.
$[_0 > 5]
Use _0 when one binding is enough and the predicate reads clearly without an
explicit name.
arg<N>¶
Indexed placeholder for general multi-binding guards.
$(has<&Point::x, &Point::y>)[arg<0> * arg<0> + arg<1> * arg<1> == 25]
rng(lo, hi, mode)¶
Range helper for single-bound-value guards.
$[rng(0, 10)]
$[rng(0, 10, pat::mod::open)]
Use callables for domain logic that does not read naturally as _0,
arg<N>, or PTN_WHERE(...).
PTN_WHERE((names...), expr)¶
Use named guard parameters without writing the lambda yourself. The macro currently supports 1 to 5 names.
match(p) | on(
$(has<&Point::x, &Point::y>)[PTN_WHERE((x, y), x == y)] >> "diagonal",
_ >> "other"
);
PTN_WHERE(...) expands to a guard callable and composes with && / ||
like other guard predicates.
PTN_LET(name, expr)¶
Use the single-value form when a guard binds exactly one value and you want to name it explicitly.
match(x) | on(
$[PTN_LET(value, value > 0 && value < 10)] >> "small",
_ >> "other"
);
PTN_LET(name, expr) is equivalent to PTN_WHERE((name), expr).
Structural Matching has<&T::member...>¶
has<> describes structure.
Wrap it with $(...) to extract values.
struct Point {
int x;
int y;
};
match(p) | on(
$(has<&Point::x, &Point::y>) >> [](int x, int y) {
return x + y;
},
_ >> 0
);
Properties:
- Member order is explicit and stable.
- Unlisted members are ignored.
- Validation happens at compile time.
Variant Matching is<T> and alt<I>¶
is<T>¶
Type-based std::variant match.
match(v) | on(
is<int> >> "int",
$(is<std::string>) >> [](const std::string &s) {
return "str:" + s;
},
_ >> [] { return std::string("other"); }
);
alt<I>¶
Index-based std::variant match.
match(v) | on(
alt<0> >> "first",
alt<1> >> "second",
_ >> "other"
);
Rules:
is<T>requiresTto appear exactly once.alt<I>requiresIto be in range.- Use
$(...)when you want the alternative value bound into the handler.
Cached Case Packs¶
static_on(...)¶
Cache a stateless on(...) factory.
match(x) | static_on([] {
return on(
val<1> >> 1,
val<2> >> 2,
_ >> 0
);
});
PTN_ON(...)¶
Convenience macro over static_on(...).
match(x) | PTN_ON(
val<1> >> 1,
val<2> >> 2,
_ >> 0
);
The factory must be stateless.
Namespace Summary¶
The public surface is re-exported through namespace ptn:
matchonlit,val,lit_ci$__0,arg,rnghasis,alt
Minimal Example¶
#include <ptn/patternia.hpp>
int main() {
using namespace ptn;
int x = 2;
int r = match(x) | on(
lit(1) >> 10,
lit(2) >> 20,
_ >> 0
);
return r == 20 ? 0 : 1;
}