tin  1.5.9
reflection.h
Go to the documentation of this file.
1 // Copyright (c) 2026 Tinverse LLC. All rights reserved.
2 // SPDX-License-Identifier: LicenseRef-Tinverse-Commercial
3 
10 
11 #pragma once
12 
13 #if __has_include(<meta>)
14 #include <meta>
15 #else
16 #error \
17  "TSM_ENABLE_REFLECTION requires a compiler and standard library with <meta>"
18 #endif
19 
20 #include <array>
21 #include <cstddef>
22 #include <string_view>
23 #include <tuple>
24 #include <type_traits>
25 
26 #include "tsm.h"
27 
28 #if !defined(TSM_ENABLE_REFLECTION) || TSM_ENABLE_REFLECTION != 1
29 #error "This branch requires TSM_ENABLE_REFLECTION=1; no fallback reflection path is available"
30 #endif
31 
32 namespace tsm::reflection {
33 
35  std::string_view from;
36  std::string_view event;
37  std::string_view to;
38 };
39 
40 template<typename T>
41 constexpr std::string_view type_name();
42 
43 namespace detail {
44 
45 template<typename Transition>
47  return { type_name<typename Transition::from>(),
48  type_name<typename Transition::event>(),
49  type_name<typename Transition::to>() };
50 }
51 
52 template<typename TransitionList>
54 
55 template<typename... TransitionEntries>
56 struct transition_count<std::tuple<TransitionEntries...>>
57  : std::integral_constant<std::size_t, sizeof...(TransitionEntries)> {};
58 
59 template<typename... TransitionEntries>
60 struct transition_count<tsm::detail::type_list<TransitionEntries...>>
61  : std::integral_constant<std::size_t, sizeof...(TransitionEntries)> {};
62 
63 template<typename TransitionList>
64 inline constexpr std::size_t transition_count_v =
66 
67 template<typename TransitionList>
69 
70 template<typename... TransitionEntries>
71 struct transition_table_builder<std::tuple<TransitionEntries...>> {
72  static constexpr auto make() {
73  return std::array<transition_descriptor, sizeof...(TransitionEntries)>{
74  describe_transition<TransitionEntries>()...
75  };
76  }
77 };
78 
79 template<typename... TransitionEntries>
80 struct transition_table_builder<tsm::detail::type_list<TransitionEntries...>> {
81  static constexpr auto make() {
82  return std::array<transition_descriptor, sizeof...(TransitionEntries)>{
83  describe_transition<TransitionEntries>()...
84  };
85  }
86 };
87 
88 template<typename A, typename B>
90  : std::bool_constant<std::is_same_v<typename A::from, typename B::from> &&
91  std::is_same_v<typename A::event, typename B::event>> {
92 };
93 
94 template<typename Transition, typename... RemainingEntries>
96  : std::bool_constant<(same_trigger<Transition, RemainingEntries>::value || ...)> {};
97 
98 template<typename... TransitionEntries>
100 
101 template<>
102 struct has_duplicate_trigger_impl<> : std::false_type {};
103 
104 template<typename Transition, typename... RemainingEntries>
105 struct has_duplicate_trigger_impl<Transition, RemainingEntries...>
106  : std::bool_constant<transition_conflicts_with_any<
107  Transition,
108  RemainingEntries...>::value ||
109  has_duplicate_trigger_impl<RemainingEntries...>::value> {};
110 
111 template<typename TransitionList>
113 
114 template<typename... TransitionEntries>
115 struct has_duplicate_trigger<std::tuple<TransitionEntries...>>
116  : has_duplicate_trigger_impl<TransitionEntries...> {};
117 
118 template<typename... TransitionEntries>
119 struct has_duplicate_trigger<tsm::detail::type_list<TransitionEntries...>>
120  : has_duplicate_trigger_impl<TransitionEntries...> {};
121 
122 } // namespace detail
123 
124 template<typename T>
125 constexpr std::string_view type_name() {
126  return std::meta::display_string_of(^^T);
127 }
128 
129 template<typename Context>
130 constexpr auto transition_table() {
132 }
133 
134 template<typename Context>
135 consteval void validate_context() {
136  static_assert(tsm::detail::has_transitions_v<Context>,
137  "tsm: Context must define using transitions = ...");
138  static_assert(
139  detail::transition_count_v<typename Context::transitions> > 0,
140  "tsm: Context transition table must not be empty");
141  static_assert(
143  "tsm: duplicate transition trigger; a State + Event pair must resolve to one transition");
144 }
145 
146 template<typename Context>
147 struct graph {
148  static constexpr auto name = type_name<Context>();
149  static constexpr auto transitions = transition_table<Context>();
150 };
151 
152 } // namespace tsm::reflection
153 
154 namespace tsm {
155 
156 template<typename Context>
157 struct reflected_hsm : hsm<Context> {
158  using base = hsm<Context>;
160 
161  static consteval bool validate_reflection_context() {
162  reflection::validate_context<Context>();
163  return true;
164  }
165 
166  static_assert(validate_reflection_context());
167 
168  static constexpr auto graph = reflection_graph{};
169 
170  using base::base;
171 };
172 
173 } // namespace tsm
constexpr std::size_t transition_count_v
Definition: reflection.h:64
constexpr transition_descriptor describe_transition()
Definition: reflection.h:46
Definition: reflection.h:32
constexpr std::string_view type_name()
Definition: reflection.h:125
consteval void validate_context()
Definition: reflection.h:135
constexpr auto transition_table()
Definition: reflection.h:130
Definition: bare_metal.h:20
detail::type_list< TransitionEntries... > transition_table
Definition: tsm.h:2442
Definition: reflection.h:157
hsm< Context > base
Definition: reflection.h:158
static constexpr auto graph
Definition: reflection.h:168
static consteval bool validate_reflection_context()
Definition: reflection.h:161
Definition: reflection.h:91
Definition: reflection.h:147
static constexpr auto transitions
Definition: reflection.h:149
static constexpr auto name
Definition: reflection.h:148
Definition: reflection.h:34
std::string_view to
Definition: reflection.h:37
std::string_view event
Definition: reflection.h:36
std::string_view from
Definition: reflection.h:35