Skip to content

Repository files navigation

Patternia logo

C++17+BuildLicenseVersionCoverageDocs


Patternia is a header-only pattern matching library for modern C++. It keeps matching expression-oriented, explicit, and zero-overhead.

Compile-time literal matching uses val<V>. Runtime literal matching remains lit(value) and lit_ci(value).

Syntax

#include<ptn/patternia.hpp>intclassify(int x) {
usingnamespaceptn;returnmatch(x) | on(
lit(0) >> 0,
lit(1) >> 1,
_ >> -1
);
}

match(subject) creates the evaluation context. on(...) provides the ordered case list. pattern >> handler defines one case. _ is the required fallback case.

Highlights

  • Literal, structural, and std::variant matching in one DSL.
  • Explicit binding through $ and $(...).
  • Declarative guards via _, PTN_BIND, rng(...), and callables.
  • No RTTI, no virtual dispatch, no heap allocation.
  • Static literal and variant dispatch lowering for hot paths.

Quick Examples

Guarded value match

usingnamespaceptn;constchar *bucket(int x) {
returnmatch(x) | on(
$[_ < 0] >> "negative",
$[_ < 10] >> "small",
_ >> "large"
);
}

Structural match

usingnamespaceptn;structPoint { int x; int y; };
intmagnitude2(const Point &p) {
returnmatch(p) | on(
$(has<&Point::x, &Point::y>) >> [](int x, int y) {
return x * x + y * y;
},
_ >> 0
);
}

Structural match with named placeholders

Declare readable names once with PTN_BIND (one to ten names), then use them directly in guard expressions:

usingnamespaceptn;structPoint { int x; int y; };
PTN_BIND(Point, x, y);
boolon_circle_radius5(const Point &p) {
returnmatch(p) | on(
$(has<&Point::x, &Point::y>)[x * x + y * y == 25] >> true,
_ >> false
);
}

Variant match

usingnamespaceptn;using Value = std::variant<int, std::string>;
std::string describe(const Value &v) {
returnmatch(v) | on(
is<int> >> "int",
$(is<std::string>) >> [](const std::string &s) {
return"str:" + s;
},
_ >> [] { returnstd::string("other"); }
);
}

Negation match

// Negation: match values NOT equal to specific literalsint status = 404;
auto msg = match(status) | on(
!val<200> >> []{ returnstd::string("error"); },
_ >> []{ returnstd::string("ok"); }
);
// msg == "error" — status isn't 200// `!p` is sugar for neg(p); likewise (a || b) for any and// (a && b) for all.

Installation

Patternia is header-only with no external dependencies.

vcpkg (recommended):

vcpkg install patternia
find_package(patterniaCONFIGREQUIRED)
target_link_libraries(your_targetPRIVATEpatternia::patternia)

FetchContent:

include(FetchContent)
FetchContent_Declare(patternia
GIT_REPOSITORY https://github.com/sentomk/patternia.git
GIT_TAG v0.9.4
)
FetchContent_MakeAvailable(patternia)
target_link_libraries(your_targetPRIVATEpatternia::patternia)

Direct clone:

git clone https://github.com/SentoMK/patternia.git
cd patternia
cmake -S . -B build
cmake --build build

See Installation Guide for find_package, submodule, and header-copy options.

Tests

cmake -S . -B build -DPTN_BUILD_TESTS=ON
cmake --build build --target ptn_tests
ctest --test-dir build --output-on-failure

Benchmarks

Patternia benchmark comparison

Patternia gap map across key scenarios. Each row is normalized to the fastest implementation in that scenario.

See Performance Notes for full reports and methodology.

Performance-Oriented Usage

Cache the case pack for repeated hot paths:

usingnamespaceptn;intfast_classify(int x) {
returnmatch(x) | PTN_ON(
val<1> >> 1,
val<2> >> 2,
_ >> 0
);
}

PTN_ON(...) is a convenience wrapper over static_on(...). It avoids rebuilding the matcher object on every call.

Documentation

Contributing

Please read CONTRIBUTING.md before sending changes. This project is governed by CODE_OF_CONDUCT.md.

About

Providing pattern matching for modern C++.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

201 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages