Skip to content

v0.4.6

Choose a tag to compare

@sentomk sentomk released this 15 Nov 12:16
· 366 commits to main since this release

Type Layer Release Note

Overview

This release introduces the Type Pattern Layer, a major extension to the Patternia DSL that enables compile-time, zero-overhead type-driven dispatch.
It significantly enhances Patternia’s expressiveness, enabling a unified dispatch model across values, runtime objects, and C++ static types.

The Type Layer integrates seamlessly with the existing match / when / otherwise control DSL and forms the foundation for the upcoming Variant Pattern Layer.

This release focuses on:

  • expressiveness
  • compile-time analyzability
  • performance transparency
  • full interoperability with value patterns

Key Features

1. type::is<T>

Match when the subject’s type is exactly T.

match(x)
  .when(type::is<int> >> "int")
  .when(type::is<float> >> "float")
  .otherwise("other");

2. type::in<Ts...>

Match when the subject’s type belongs to a set of types.

match(x)
  .when(type::in<int, float, double> >> "numeric")
  .otherwise("other");

3. type::not_in<Ts...>

Negated type-set match.

match(x)
  .when(type::not_in<std::string, std::vector<int>> >> "plain type")
  .otherwise("container");

4. type::from<Tpl>

Match any specialization of a given template.

match(v)
  .when(type::from<std::vector> >> "vector")
  .when(type::from<std::optional> >> "optional")
  .otherwise("other");

This enables a genuinely expressive, structure-aware DSL.

5. Full DSL compatibility

Type patterns interoperate with:

  • lit()
  • predicate
  • relational operators (&&, ||, !)
  • operator>> case binding

Example:

match(x)
  .when((type::is<int> && gt(0)) >> "positive int")
  .otherwise("other");

6. Header-only, fully inlinable

All type patterns are implemented as lightweight structures with:

  • no runtime allocations
  • zero virtual dispatch
  • compile-time resolvable structure
  • type-based dispatch resolved by the optimizer

The generated machine code typically matches or exceeds manually written if constexpr and std::visit dispatch trees.

Example: Type-Based Router

std::variant<int, float, std::string> msg = 3.14f;

auto r = match(msg)
  .when(type::is<int> >> "int")
  .when(type::is<float> >> "float")
  .when(type::is<std::string> >> "string")
  .otherwise("unknown");

This is a precursor to the upcoming native variant::is<T> patterns.

Performance Notes

  • All type patterns are constexpr and trivially inlinable.
  • No RTTI is used unless the user explicitly relies on runtime polymorphism.
  • Dispatch is resolved using a compile-time discrimination model.
  • Expected branch prediction behavior matches manually optimized dispatch.
  • Benchmarks (included separately) show parity with hand-tuned variant visitors.

No ABI impact, no binary bloat.

Compatibility

  • C++20 or later
  • Fully portable across GCC, Clang, MSVC
  • API is stable and suitable for production use
  • Does not require exceptions or RTTI