Skip to content

Commit ba7e5ef

Browse files
committed
refactor: introduce full Type Layer (meta) and complete Type Pattern DSL (type::is/in/not_in/from)
1 parent c63c31e commit ba7e5ef

5 files changed

Lines changed: 395 additions & 20 deletions

File tree

‎CMakeLists.txt‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,12 @@ PTN_JOIN_HEADERS(PTN_HEADERS
8989
include/ptn/pattern/pattern_base.hpp
9090
include/ptn/pattern/pattern_traits.hpp
9191

92-
# Type Layer
92+
# Type Pattern Layer
9393
include/ptn/pattern/type/type_of.hpp
9494
include/ptn/pattern/type/type.hpp
95+
96+
# Type Meta Layer
97+
include/ptn/type/meta.hpp
9598
)
9699

97100
# ========== Public interface target ==========

‎include/ptn/pattern/type/type.hpp‎

Lines changed: 105 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,130 @@
11
#pragma once
22
/**
3-
* @file type_tag.hpp
4-
* @brief Defines `type_tag<T>` / `type_c<T>` as both a type tag and
5-
* a Patternia pattern (matches by static type).
3+
* @file type.hpp
4+
* @brief Static type-based patterns for Patternia.
65
*
7-
* Part of Pattern Layer (namespace ptn::pattern::value)
6+
* Provides the static Type Pattern DSL:
7+
* - type::is<T> : match when subject's type is exactly T
8+
* - type::in<Ts...> : match when subject's type is in Ts...
9+
* - type::not_in<Ts...>
10+
* - type::from<Tpl> : match any specialization of template Tpl<...>
11+
*
12+
* Legacy:
13+
* - type_is<T> alias kept as compatibility wrapper → type::is<T>
14+
*
15+
* This file forms the Pattern Layer entry for type patterns.
816
*/
917

1018
#include <type_traits>
19+
#include <utility>
20+
1121
#include "ptn/pattern/pattern_base.hpp"
1222

1323
namespace ptn::pattern::type {
1424

15-
/**
16-
* @brief Compile-time wrapper around a C++ type, and also a pattern
17-
* that matches when the subject's (decayed) type equals `T`.
18-
*/
25+
//====================================================================
26+
// Internal helper: is specialization of template?
27+
//====================================================================
28+
namespace detail {
29+
30+
template <template <typename...> typename Tpl, typename T>
31+
struct is_specialization_of : std::false_type {};
32+
33+
template <template <typename...> typename Tpl, typename... Args>
34+
struct is_specialization_of<Tpl, Tpl<Args...>> : std::true_type {};
35+
36+
} // namespace detail
37+
38+
//====================================================================
39+
// type::is<T> — static type equality
40+
//====================================================================
41+
1942
template <typename T>
20-
struct type_tag : ptn::pattern::pattern_base<type_tag<T>> {
43+
struct is_pattern : ptn::pattern::pattern_base<is_pattern<T>> {
2144

2245
template <typename X>
2346
constexpr bool match(X &&) const noexcept {
24-
return std::is_same_v<T, std::decay_t<X>>;
47+
return std::is_same_v<std::decay_t<X>, T>;
48+
}
49+
template <typename X>
50+
constexpr auto bind(X &&x) const noexcept {
51+
return std::forward<X>(x);
2552
}
53+
};
54+
55+
template <typename T>
56+
inline constexpr is_pattern<T> is{};
2657

58+
//====================================================================
59+
// type::in<Ts...> — membership
60+
//====================================================================
61+
62+
template <typename... Ts>
63+
struct in_pattern : ptn::pattern::pattern_base<in_pattern<Ts...>> {
64+
65+
template <typename X>
66+
constexpr bool match(X &&) const noexcept {
67+
using D = std::decay_t<X>;
68+
return (std::is_same_v<D, Ts> || ...);
69+
}
2770
template <typename X>
2871
constexpr auto bind(X &&x) const noexcept {
2972
return std::forward<X>(x);
3073
}
3174
};
3275

33-
/**
34-
* @brief Shorthand constant for `type_tag<T>`.
35-
*/
76+
template <typename... Ts>
77+
inline constexpr in_pattern<Ts...> in{};
78+
79+
//====================================================================
80+
// type::not_in<Ts...>
81+
//====================================================================
82+
83+
template <typename... Ts>
84+
struct not_in_pattern : ptn::pattern::pattern_base<not_in_pattern<Ts...>> {
85+
86+
template <typename X>
87+
constexpr bool match(X &&v) const noexcept {
88+
return !in_pattern<Ts...>{}.match(std::forward<X>(v));
89+
}
90+
template <typename X>
91+
constexpr auto bind(X &&x) const noexcept {
92+
return std::forward<X>(x);
93+
}
94+
};
95+
96+
template <typename... Ts>
97+
inline constexpr not_in_pattern<Ts...> not_in{};
98+
99+
//====================================================================
100+
// type::from<Tpl> — match template family
101+
//====================================================================
102+
103+
template <template <typename...> typename Tpl>
104+
struct from_pattern : ptn::pattern::pattern_base<from_pattern<Tpl>> {
105+
106+
template <typename X>
107+
constexpr bool match(X &&) const noexcept {
108+
using D = std::decay_t<X>;
109+
return detail::is_specialization_of<Tpl, D>::value;
110+
}
111+
template <typename X>
112+
constexpr auto bind(X &&x) const noexcept {
113+
return std::forward<X>(x);
114+
}
115+
};
116+
117+
template <template <typename...> typename Tpl>
118+
inline constexpr from_pattern<Tpl> from{};
119+
120+
//====================================================================
121+
// Legacy compatibility
122+
//====================================================================
123+
124+
template <typename T>
125+
using type_tag = is_pattern<T>;
126+
36127
template <typename T>
37-
inline constexpr type_tag<T> type_is{};
128+
inline constexpr auto type_is = is<T>;
38129

39130
} // namespace ptn::pattern::type

‎include/ptn/patternia.hpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ namespace ptn {
7474

7575
// ---- Export Type Layer (ONLY selected symbols) ----
7676
#if PTN_ENABLE_TYPE
77+
#include "ptn/pattern/type/type.hpp"
78+
namespace type = ptn::pattern::type;
7779
using pattern::type::type_is;
7880
using pattern::type::type_of;
7981
using pattern::type::type_tag;

0 commit comments

Comments
 (0)