|
| template<typename T , typename... Ts> |
| consteval std::size_t | index_in_pack () |
| |
| template<typename T , typename... Ts> |
| consteval bool | contains_type () |
| |
| template<typename From , typename Event , typename... TransitionEntries> |
| consteval std::size_t | trigger_count () |
| |
| template<typename From , typename Event , typename... TransitionEntries> |
| consteval bool | duplicate_group_is_guarded () |
| |
| template<typename From , typename Event , typename... TransitionEntries> |
| consteval std::size_t | duplicate_group_unguarded_count () |
| |
| template<typename From , typename Event , typename... TransitionEntries> |
| consteval bool | trigger_group_is_valid () |
| |
| template<typename... TransitionEntries> |
| consteval bool | transition_triggers_are_valid () |
| |
| template<typename Hierarchy > |
| constexpr auto | compute_transition_sequence (std::uint16_t source, std::uint16_t destination) |
| |
| template<typename Hierarchy > |
| constexpr auto | compute_local_transition_sequence (std::uint16_t active_leaf, std::uint16_t selected_source, std::uint16_t destination) |
| |
| template<typename Hierarchy > |
| constexpr auto | compute_reentering_transition_sequence (std::uint16_t active_leaf, std::uint16_t selected_source, std::uint16_t destination) |
| |
template<typename Hierarchy >
| constexpr auto tsm::core::compute_reentering_transition_sequence |
( |
std::uint16_t |
active_leaf, |
|
|
std::uint16_t |
selected_source, |
|
|
std::uint16_t |
destination |
|
) |
| |
|
constexpr |
Compute an explicit re-entering external transition sequence.
Normal verified-tsm transitions preserve the least common ancestor. This helper models the UML/SCXML external form selected from a composite state: the selected source is exited and can be entered again on the target path.
(define (reentering-external active source destination hierarchy) (let* ((boundary (parent source hierarchy)) (exits (states-from-leaf-up-to active boundary hierarchy)) (entries (states-from-lca-down-to boundary destination hierarchy))) (transition-sequence destination boundary exits entries ...)))
template<typename Hierarchy >
| constexpr auto tsm::core::compute_transition_sequence |
( |
std::uint16_t |
source, |
|
|
std::uint16_t |
destination |
|
) |
| |
|
constexpr |
Compute a transition execution sequence.
Given a source leaf and destination state, compute the LCA, exit path, entry path, initial-entry descent, and final active path. The result is numeric and fixed-capacity so a runtime backend can execute it deterministically.
(define (transition-sequence source destination hierarchy) (let* ((lca (least-common-ancestor source destination hierarchy)) (exits (states-from-leaf-up-to source lca hierarchy)) (direct-entries (states-from-lca-down-to lca destination hierarchy)) (initial-entries (enter-initial-children destination hierarchy)) (entries (append direct-entries initial-entries)) (final-path (append (path-from-root lca hierarchy) entries))) (transition-sequence destination lca exits entries final-path))
template<typename T , typename... Ts>
| consteval std::size_t tsm::core::index_in_pack |
( |
| ) |
|
Position of a type in a type list.
This answers: "where does this state/event/transition type appear in the
declaration order?" The result is the stable numeric ID used by runtime dispatch and trace records.
(define (index-of needle haystack) (match haystack (() npos) ((needle . _) 0) ((_ . rest) (+ 1 (index-of needle rest)))))
(define (first-index-where predicate haystack) (match haystack (() npos) ((item . rest) (if (predicate item) 0 (let ((rest-index (first-index-where predicate rest))) (if (= rest-index npos) npos (+ 1 rest-index)))))))
The C++ implementation computes the answer at compile time. Callers that require a valid ID turn the failure value into a static assertion.
template<typename... TransitionEntries>
| consteval bool tsm::core::transition_triggers_are_valid |
( |
| ) |
|
Validate duplicate triggers in an authored transition table.
Normal states may have at most one unguarded (from, event) edge. Multiple edges are allowed only when every candidate has a guard, because runtime dispatch evaluates them in declaration order and takes the first accepted transition.
Choice and junction pseudostates use the same mechanism for automatic transitions, with one extra allowance: a single unguarded fallback branch may appear after guarded branches.