\doxysection{src/include/serif/utils/dependencies/observers.hpp File Reference} \hypertarget{utils_2dependencies_2observers_8hpp}{}\label{utils_2dependencies_2observers_8hpp}\index{src/include/serif/utils/dependencies/observers.hpp@{src/include/serif/utils/dependencies/observers.hpp}} {\ttfamily \#include $<$array$>$}\newline {\ttfamily \#include $<$concepts$>$}\newline {\ttfamily \#include $<$cstddef$>$}\newline {\ttfamily \#include $<$exception$>$}\newline {\ttfamily \#include $<$functional$>$}\newline {\ttfamily \#include $<$tuple$>$}\newline {\ttfamily \#include $<$type\+\_\+traits$>$}\newline {\ttfamily \#include $<$utility$>$}\newline {\ttfamily \#include $<$format$>$}\newline {\ttfamily \#include $<$string\+\_\+view$>$}\newline {\ttfamily \#include "{}serif/utils/dependencies/detail/schema.\+hpp"{}}\newline Include dependency graph for observers.\+hpp\+: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=350pt]{utils_2dependencies_2observers_8hpp__incl} \end{center} \end{figure} This graph shows which files directly or indirectly include this file\+: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=350pt]{utils_2dependencies_2observers_8hpp__dep__incl} \end{center} \end{figure} \doxysubsubsection*{Classes} \begin{DoxyCompactItemize} \item struct \mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_node_observer}{serif\+::utils\+::dependencies\+::\+Node\+Observer$<$ Key\+T, Before\+T, After\+T $>$}} \item struct \mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_all_nodes_observer}{serif\+::utils\+::dependencies\+::\+All\+Nodes\+Observer$<$ Before\+T, After\+T $>$}} \begin{DoxyCompactList}\small\item\em One registration can inspect every result without building a graph-\/sized observer tuple. \end{DoxyCompactList}\item struct \mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_edge_observer}{serif\+::utils\+::dependencies\+::\+Edge\+Observer$<$ Input\+T, Consumer\+T, Function\+T $>$}} \item class \mbox{\hyperlink{classserif_1_1utils_1_1dependencies_1_1detail_1_1_node_observation}{serif\+::utils\+::dependencies\+::detail\+::\+Node\+Observation$<$ Before\+T, After\+T $>$}} \begin{DoxyCompactList}\small\item\em Each started hook owns one invocation state and finishes once, including on exceptional exit. \end{DoxyCompactList}\item class \mbox{\hyperlink{classserif_1_1utils_1_1dependencies_1_1_observers}{serif\+::utils\+::dependencies\+::\+Observers$<$ Registrations $>$}} \begin{DoxyCompactList}\small\item\em Own registrations; execution state lasts for one invocation and is never part of the numerical cache. \end{DoxyCompactList}\item struct \mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_no_graph_observers}{serif\+::utils\+::dependencies\+::\+No\+Graph\+Observers}} \begin{DoxyCompactList}\small\item\em Default high-\/level binding adds no observation storage, timers, or callback work. \end{DoxyCompactList}\item struct \mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1detail_1_1_valid_observers}{serif\+::utils\+::dependencies\+::detail\+::\+Valid\+Observers$<$ Observers\+T, Graph\+T, Context\+T, Valid $>$}} \item struct \mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1detail_1_1_valid_observers_3_01_observers_3_01_registratabaa0417bbf6f785373b4d94e684892b}{serif\+::utils\+::dependencies\+::detail\+::\+Valid\+Observers$<$ Observers$<$ Registrations... $>$, Graph\+T, Context\+T, true $>$}} \item struct \mbox{\hyperlink{structstd_1_1formatter_3_01serif_1_1utils_1_1dependencies_1_1_node_outcome_01_4}{std\+::formatter$<$ serif\+::utils\+::dependencies\+::\+Node\+Outcome $>$}} \end{DoxyCompactItemize} \doxysubsubsection*{Namespaces} \begin{DoxyCompactItemize} \item namespace \mbox{\hyperlink{namespaceserif}{serif}} \item namespace \mbox{\hyperlink{namespaceserif_1_1utils}{serif\+::utils}} \item namespace \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies}{serif\+::utils\+::dependencies}} \item namespace \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail}{serif\+::utils\+::dependencies\+::detail}} \end{DoxyCompactItemize} \doxysubsubsection*{Concepts} \begin{DoxyCompactItemize} \item concept \mbox{\hyperlink{conceptserif_1_1utils_1_1dependencies_1_1_node_observer_callbacks}{serif\+::utils\+::dependencies\+::\+Node\+Observer\+Callbacks}} \begin{DoxyCompactList}\small\item\em Completion must be safe during stack unwinding and receives the state created by the before hook. \end{DoxyCompactList}\item concept \mbox{\hyperlink{conceptserif_1_1utils_1_1dependencies_1_1_keyed_node_observer_callbacks}{serif\+::utils\+::dependencies\+::\+Keyed\+Node\+Observer\+Callbacks}} \begin{DoxyCompactList}\small\item\em An all-\/node callback receives the compiled result identity before creating its invocation state. \end{DoxyCompactList}\item concept \mbox{\hyperlink{conceptserif_1_1utils_1_1dependencies_1_1_observers_for}{serif\+::utils\+::dependencies\+::\+Observers\+For}} \begin{DoxyCompactList}\small\item\em Reject unknown nodes, nonexistent edges, and callbacks that cannot observe the graph\textquotesingle{}s immutable values. \end{DoxyCompactList}\end{DoxyCompactItemize} \doxysubsubsection*{Enumerations} \begin{DoxyCompactItemize} \item enum class \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_af2f6dab3a0204175602c7fc2348344f7}{serif\+::utils\+::dependencies\+::\+Node\+Outcome}} \{ \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_af2f6dab3a0204175602c7fc2348344f7aaa8fb77e57d1ca18d593e909729871fe}{serif\+::utils\+::dependencies\+::completed}} , \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_af2f6dab3a0204175602c7fc2348344f7ac7537d6d48ecf261749c09a9f284bd45}{serif\+::utils\+::dependencies\+::rejected}} , \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_af2f6dab3a0204175602c7fc2348344f7a42552b1f133f9f8eb406d4f306ea9fd1}{serif\+::utils\+::dependencies\+::exception}} \} \begin{DoxyCompactList}\small\item\em Describe a node invocation, independently of whether the whole graph request is later accepted. \end{DoxyCompactList}\end{DoxyCompactItemize} \doxysubsubsection*{Functions} \begin{DoxyCompactItemize} \item {\footnotesize template$<$typename KeyT, typename BeforeT, typename AfterT$>$ }\\decltype(auto) \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a7ff94caf001bd5c7123966e6f92a8abb}{serif\+::utils\+::dependencies\+::detail\+::begin\+\_\+node}} (\mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_node_observer}{Node\+Observer}}$<$ KeyT, BeforeT, AfterT $>$ \&observer) \begin{DoxyCompactList}\small\item\em Preserve the existing nullary callback contract for individually selected nodes. \end{DoxyCompactList}\item {\footnotesize template$<$typename KeyT, typename BeforeT, typename AfterT$>$ }\\decltype(auto) \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_aee1fc72f63e9473f0ce45cd35dfafe7b}{serif\+::utils\+::dependencies\+::detail\+::begin\+\_\+node}} (\mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_all_nodes_observer}{All\+Nodes\+Observer}}$<$ BeforeT, AfterT $>$ \&observer) \begin{DoxyCompactList}\small\item\em Bind the identity once so generic registrations use the same exception-\/safe invocation scope. \end{DoxyCompactList}\item {\footnotesize template$<$typename InputT, typename ConsumerT, typename ObserverT, typename ValueT$>$ }\\void \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a2d1c9c4dc981bb4860436d10be716dc4}{serif\+::utils\+::dependencies\+::detail\+::observe\+\_\+input}} (ObserverT \&, const ValueT \&) \begin{DoxyCompactList}\small\item\em Unrelated registrations do not observe this edge. \end{DoxyCompactList}\item {\footnotesize template$<$typename InputT, typename ConsumerT, typename FunctionT, typename ValueT$>$ }\\void \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a5a86ca8b4c4a173da8ca5ee1ba6a1901}{serif\+::utils\+::dependencies\+::detail\+::observe\+\_\+input}} (\mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_edge_observer}{Edge\+Observer}}$<$ InputT, ConsumerT, FunctionT $>$ \&observer, const ValueT \&value) \begin{DoxyCompactList}\small\item\em Edge observers read the numerical value even when its consumer receives an owning handle. \end{DoxyCompactList}\item {\footnotesize template$<$typename KeyT, typename BeforeT, typename AfterT$>$ \newline requires Node\+Observer\+Callbacks$<$std\+::decay\+\_\+t$<$BeforeT$>$, std\+::decay\+\_\+t$<$AfterT$>$$>$ \&\& std\+::constructible\+\_\+from$<$std\+::decay\+\_\+t$<$BeforeT$>$, BeforeT$>$ \&\& std\+::constructible\+\_\+from$<$std\+::decay\+\_\+t$<$AfterT$>$, AfterT$>$}\\auto \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_a427c6ce690c7551cbdbbb5261bd8c125}{serif\+::utils\+::dependencies\+::observe\+\_\+node}} (BeforeT \&\&before, AfterT \&\&after) \begin{DoxyCompactList}\small\item\em Bind before/after callbacks to a result key; callback captures determine any external storage lifetime. \end{DoxyCompactList}\item {\footnotesize template$<$typename BeforeT, typename AfterT$>$ \newline requires std\+::constructible\+\_\+from$<$std\+::decay\+\_\+t$<$BeforeT$>$, BeforeT$>$ \&\& std\+::constructible\+\_\+from$<$std\+::decay\+\_\+t$<$AfterT$>$, AfterT$>$}\\auto \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_a1011c9c6c8b4e2ca4e87b9826743dde5}{serif\+::utils\+::dependencies\+::observe\+\_\+nodes}} (BeforeT \&\&before, AfterT \&\&after) \begin{DoxyCompactList}\small\item\em Observe all executed nodes; cache construction checks the callback contract for every result key. \end{DoxyCompactList}\item {\footnotesize template$<$typename InputT, typename ConsumerT, typename FunctionT$>$ \newline requires std\+::constructible\+\_\+from$<$std\+::decay\+\_\+t$<$FunctionT$>$, FunctionT$>$}\\auto \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_a1156ef3083e1e54eaabb23309b17fb57}{serif\+::utils\+::dependencies\+::observe\+\_\+edge}} (FunctionT \&\&function) \begin{DoxyCompactList}\small\item\em Bind a read-\/only callback to one input of one consumer; graph construction validates the edge and value type. \end{DoxyCompactList}\item {\footnotesize template$<$typename... Registrations$>$ \newline requires (\mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a54c9a0f2354c9edeef7db65bee38b1fe}{detail\+::is\+\_\+observer\+\_\+v}}$<$std\+::remove\+\_\+cvref\+\_\+t$<$Registrations$>$$>$ \&\& ...) \&\& (std\+::constructible\+\_\+from$<$std\+::remove\+\_\+cvref\+\_\+t$<$Registrations$>$, Registrations$>$ \&\& ...)}\\auto \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_af617b846949f46d528f63c89b218887b}{serif\+::utils\+::dependencies\+::make\+\_\+observers}} (Registrations \&\&... observers) \begin{DoxyCompactList}\small\item\em Collect any number of registrations, including several observers of the same node or edge. \end{DoxyCompactList}\item {\footnotesize template$<$typename GraphT, typename BindingsT, typename KeyT, typename BeforeT, typename AfterT$>$ }\\consteval bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a3cefb4aba3cf944c1cc738c523616fd8}{serif\+::utils\+::dependencies\+::detail\+::valid\+\_\+observer}} (\mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_node_observer}{Node\+Observer}}$<$ KeyT, BeforeT, AfterT $>$ \texorpdfstring{$\ast$}{*}) \begin{DoxyCompactList}\small\item\em Nodes are identified by result keys, including constant computations without inputs. \end{DoxyCompactList}\item {\footnotesize template$<$typename BeforeT, typename AfterT, typename... Keys$>$ }\\consteval bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a291daca460e39045e586084e8919d926}{serif\+::utils\+::dependencies\+::detail\+::valid\+\_\+all\+\_\+nodes}} (\mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_key_list}{Key\+List}}$<$ Keys... $>$) \begin{DoxyCompactList}\small\item\em Use a bounded array scan rather than a graph-\/sized fold expression at the compiler\textquotesingle{}s nesting limit. \end{DoxyCompactList}\item {\footnotesize template$<$typename GraphT, typename BindingsT, typename BeforeT, typename AfterT$>$ }\\consteval bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a09376ee40044c2a8bc7bdffd854cfaf6}{serif\+::utils\+::dependencies\+::detail\+::valid\+\_\+observer}} (\mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_all_nodes_observer}{All\+Nodes\+Observer}}$<$ BeforeT, AfterT $>$ \texorpdfstring{$\ast$}{*}) \begin{DoxyCompactList}\small\item\em A generic callback must accept every node, including constant computations without inputs. \end{DoxyCompactList}\item {\footnotesize template$<$typename GraphT, typename BindingsT, typename InputT, typename ConsumerT, typename FunctionT$>$ }\\consteval bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a038a5b2a212a350ff83d75745171a630}{serif\+::utils\+::dependencies\+::detail\+::valid\+\_\+observer}} (\mbox{\hyperlink{structserif_1_1utils_1_1dependencies_1_1_edge_observer}{Edge\+Observer}}$<$ InputT, ConsumerT, FunctionT $>$ \texorpdfstring{$\ast$}{*}) \begin{DoxyCompactList}\small\item\em Use declared inputs to include source edges as well as computed prerequisites. \end{DoxyCompactList}\end{DoxyCompactItemize} \doxysubsubsection*{Variables} \begin{DoxyCompactItemize} \item {\footnotesize template$<$typename T$>$ }\\constexpr bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a54c9a0f2354c9edeef7db65bee38b1fe}{serif\+::utils\+::dependencies\+::detail\+::is\+\_\+observer\+\_\+v}} = false \item {\footnotesize template$<$typename KeyT, typename BeforeT, typename AfterT$>$ }\\constexpr bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a846d8e6f747495893d968c26879f865e}{serif\+::utils\+::dependencies\+::detail\+::is\+\_\+observer\+\_\+v$<$ Node\+Observer$<$ Key\+T, Before\+T, After\+T $>$ $>$}} = true \item {\footnotesize template$<$typename BeforeT, typename AfterT$>$ }\\constexpr bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a375f43bdd5eeb52dbdc2a779131731ae}{serif\+::utils\+::dependencies\+::detail\+::is\+\_\+observer\+\_\+v$<$ All\+Nodes\+Observer$<$ Before\+T, After\+T $>$ $>$}} = true \item {\footnotesize template$<$typename InputT, typename ConsumerT, typename FunctionT$>$ }\\constexpr bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_a956c74525609c9d885b67bf18f1a63b7}{serif\+::utils\+::dependencies\+::detail\+::is\+\_\+observer\+\_\+v$<$ Edge\+Observer$<$ Input\+T, Consumer\+T, Function\+T $>$ $>$}} = true \item {\footnotesize template$<$typename ObserverT, typename KeyT$>$ }\\constexpr bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_af24e48ad85f3dcae7f944b475e13bed6}{serif\+::utils\+::dependencies\+::detail\+::observes\+\_\+node\+\_\+v}} = false \item {\footnotesize template$<$typename KeyT, typename BeforeT, typename AfterT$>$ }\\constexpr bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_aea6d20844348112dfd4d8f3d59278876}{serif\+::utils\+::dependencies\+::detail\+::observes\+\_\+node\+\_\+v$<$ Node\+Observer$<$ Key\+T, Before\+T, After\+T $>$, Key\+T $>$}} = true \item {\footnotesize template$<$typename BeforeT, typename AfterT, typename KeyT$>$ }\\constexpr bool \mbox{\hyperlink{namespaceserif_1_1utils_1_1dependencies_1_1detail_aa2711ef0eca99da243a90d5554e7c43c}{serif\+::utils\+::dependencies\+::detail\+::observes\+\_\+node\+\_\+v$<$ All\+Nodes\+Observer$<$ Before\+T, After\+T $>$, Key\+T $>$}} = true \end{DoxyCompactItemize}