28namespace shamrock::solvergraph {
31 class INode :
public std::enable_shared_from_this<INode> {
34 std::vector<std::shared_ptr<IEdge>> ro_edges;
36 std::vector<std::shared_ptr<IEdge>> rw_edges;
45 INode(
const INode &) =
delete;
49 INode(INode &&) noexcept = default;
52 INode &operator=(INode &&) noexcept = default;
58 inline std::shared_ptr<INode>
getptr_shared() {
return shared_from_this(); }
60 inline std::weak_ptr<INode>
getptr_weak() {
return weak_from_this(); }
63 inline std::vector<std::shared_ptr<IEdge>> &
get_ro_edges() {
return ro_edges; }
65 inline std::vector<std::shared_ptr<IEdge>> &
get_rw_edges() {
return rw_edges; }
84 tracker.trace_destroy();
104 auto &edge = ro_edges.at(slot);
106 auto ptr = std::dynamic_pointer_cast<T>(edge);
108 return std::cref(*ptr);
111 if (is_null_opt_edge(edge)) {
116 sham::format(
"Edge is not from the requested type: {}", slot));
122 auto &edge = rw_edges.at(slot);
124 auto ptr = std::dynamic_pointer_cast<T>(edge);
126 return std::cref(*ptr);
129 if (is_null_opt_edge(edge)) {
134 sham::format(
"Edge is not from the requested type: {}", slot));
158 tracker.trace_event([]() {
159 return "evaluate_begin";
162 tracker.trace_event([]() {
163 return "evaluate_end";
187 std::string node_info = sham::format(
"Node info :\n");
188 node_info += sham::format(
" - Node type : {}\n",
typeid(*this).name());
189 node_info += sham::format(
" - Node UUID : {}\n",
get_uuid());
192 auto append_edges_info = [&](
const char *title,
const auto &edges) {
193 node_info += sham::format(
" - {}: {}\n", title, edges.size());
194 for (
const auto &edge : edges) {
195 const auto &e = *edge;
196 node_info += sham::format(
197 " - Edge ptr = {}, uuid = {}, label = {},\n type = {} \n",
198 static_cast<void *
>(edge.get()),
205 append_edges_info(
"Node Read Only edges", ro_edges);
206 append_edges_info(
"Node Read Write edges", rw_edges);
239 for (
auto e : ro_edges) {
242 this->ro_edges = new_ro_edges;
243 for (
auto e : ro_edges) {
246 tracker.trace_state_update(*
this);
250 for (
auto e : rw_edges) {
253 this->rw_edges = new_rw_edges;
254 for (
auto e : rw_edges) {
257 tracker.trace_state_update(*
this);
262 for (
auto &in : ro_edges) {
269 for (
auto &out : rw_edges) {
278 std::string edge_str =
"";
279 for (
auto &in : ro_edges) {
280 edge_str += sham::format(
281 "e_{} -> n_{} [style=\"dashed\", color=green];\n",
284 edge_str += sham::format(
285 "e_{} [label=\"{}\",shape=rect, style=filled];\n", in->get_uuid(), in->get_label());
287 for (
auto &out : rw_edges) {
288 edge_str += sham::format(
289 "n_{} -> e_{} [style=\"dashed\", color=red];\n", this->
get_uuid(), out->get_uuid());
290 edge_str += sham::format(
291 "e_{} [label=\"{}\",shape=rect, style=filled];\n",
296 return sham::format(
"{}{}", node_str, edge_str);
300 return sham::format(
"n_{}", this->
get_uuid());
303 return sham::format(
"n_{}", this->
get_uuid());
308#define INODE_DECL_RO(type, name) const type &name;
309#define INODE_DECL_RW(type, name) type & name;
310#define INODE_PARAM_RO(type, name) const std::shared_ptr<type> &name,
311#define INODE_PARAM_RW(type, name) const std::shared_ptr<type> &name,
312#define INODE_PUSH_RO1(type, name) name,
313#define INODE_PUSH_RW1(type, name)
314#define INODE_PUSH_RO2(type, name)
315#define INODE_PUSH_RW2(type, name) name,
316#define INODE_GET_RO(type, name) get_ro_edge<type>(ro++),
317#define INODE_GET_RW(type, name) get_rw_edge<type>(rw++),
319#define INODE_DECL_RO_OPTIONAL(type, name) \
320 const std::optional<std::reference_wrapper<const type>> name;
321#define INODE_DECL_RW_OPTIONAL(type, name) const std::optional<std::reference_wrapper<type>> name;
322#define INODE_PARAM_RO_OPTIONAL(type, name) const std::optional<std::shared_ptr<type>> &name,
323#define INODE_PARAM_RW_OPTIONAL(type, name) const std::optional<std::shared_ptr<type>> &name,
324#define INODE_PUSH_RO1_OPTIONAL(type, name) shamrock::solvergraph::obsfucate_null_opt_edge(name),
325#define INODE_PUSH_RW1_OPTIONAL(type, name)
326#define INODE_PUSH_RO2_OPTIONAL(type, name)
327#define INODE_PUSH_RW2_OPTIONAL(type, name) shamrock::solvergraph::obsfucate_null_opt_edge(name),
328#define INODE_GET_RO_OPTIONAL(type, name) get_ro_edge_optional<type>(ro++),
329#define INODE_GET_RW_OPTIONAL(type, name) get_rw_edge_optional<type>(rw++),
333#define INODE_TEX_DECL(type, name) std::string name;
334#define INODE_TEX_GET_RO(type, name) get_ro_edge_base(ro++).get_tex_symbol(),
335#define INODE_TEX_GET_RW(type, name) get_rw_edge_base(rw++).get_tex_symbol(),
336#define INODE_TEX_REPLACE(type, name) shambase::replace_all(tex, "{" #name "}", symbols.name);
347#define INODE_EXPAND_TEX_SYMBOLS(TEX_DECLS, TEX_GETS, TEX_REPLACES) \
349 struct EdgesTexSymbols { \
353 inline EdgesTexSymbols get_edges_tex_symbols() const { \
356 return EdgesTexSymbols{TEX_GETS}; \
359 inline void replace_edges_tex_symbols(std::string &tex) const { \
360 auto symbols = get_edges_tex_symbols(); \
364#define EXPAND_NODE_EDGES(EDGES) \
367 EDGES(INODE_DECL_RO, INODE_DECL_RW) \
370 inline void set_edges( \
371 EDGES(INODE_PARAM_RO, INODE_PARAM_RW) SourceLocation loc = SourceLocation{}) { \
372 __shamrock_log_callsite(loc); \
374 __internal_set_ro_edges({EDGES(INODE_PUSH_RO1, INODE_PUSH_RW1)}); \
375 __internal_set_rw_edges({EDGES(INODE_PUSH_RO2, INODE_PUSH_RW2)}); \
378 inline Edges get_edges() { \
381 return Edges{EDGES(INODE_GET_RO, INODE_GET_RW)}; \
384 INODE_EXPAND_TEX_SYMBOLS( \
385 EDGES(INODE_TEX_DECL, INODE_TEX_DECL), \
386 EDGES(INODE_TEX_GET_RO, INODE_TEX_GET_RW), \
387 EDGES(INODE_TEX_REPLACE, INODE_TEX_REPLACE))
389#define EXPAND_NODE_EDGES_OPTIONAL(EDGES) \
392 EDGES(INODE_DECL_RO, INODE_DECL_RW, INODE_DECL_RO_OPTIONAL, INODE_DECL_RW_OPTIONAL) \
395 inline void set_edges( \
396 EDGES(INODE_PARAM_RO, INODE_PARAM_RW, INODE_PARAM_RO_OPTIONAL, INODE_PARAM_RW_OPTIONAL) \
397 SourceLocation loc = SourceLocation{}) { \
398 __shamrock_log_callsite(loc); \
400 __internal_set_ro_edges({EDGES( \
401 INODE_PUSH_RO1, INODE_PUSH_RW1, INODE_PUSH_RO1_OPTIONAL, INODE_PUSH_RW1_OPTIONAL)}); \
402 __internal_set_rw_edges({EDGES( \
403 INODE_PUSH_RO2, INODE_PUSH_RW2, INODE_PUSH_RO2_OPTIONAL, INODE_PUSH_RW2_OPTIONAL)}); \
406 inline Edges get_edges() { \
410 EDGES(INODE_GET_RO, INODE_GET_RW, INODE_GET_RO_OPTIONAL, INODE_GET_RW_OPTIONAL)}; \
413 INODE_EXPAND_TEX_SYMBOLS( \
414 EDGES(INODE_TEX_DECL, INODE_TEX_DECL, INODE_TEX_DECL, INODE_TEX_DECL), \
415 EDGES(INODE_TEX_GET_RO, INODE_TEX_GET_RW, INODE_TEX_GET_RO, INODE_TEX_GET_RW), \
416 EDGES(INODE_TEX_REPLACE, INODE_TEX_REPLACE, INODE_TEX_REPLACE, INODE_TEX_REPLACE))
Callback API to track the lifetime, state updates and operations of solvergraph objects.
std::uint64_t u64
64 bit unsigned integer
void evaluate()
Evaluate the node.
INode & operator=(const INode &)=delete
would violate shared_from_this() & unique UUID
std::vector< std::shared_ptr< IEdge > > & get_ro_edges()
Get the read only edges.
virtual std::string _impl_get_dot_graph_node_start() const
get the dot graph of the node start
void on_edge_ro_edges(Func &&f)
Apply a function to the read only edges.
T & get_rw_edge(int slot)
Get a read write edge and cast it to the type T.
INode(INode &&) noexcept=default
would violate shared_from_this() & unique UUID
void __internal_set_rw_edges(std::vector< std::shared_ptr< IEdge > > new_rw_edges)
Set the read write edges.
std::string get_dot_graph_node_start()
Get the id of the node start in the dot graph.
std::string get_tex_partial()
Get the TeX of the node partial.
std::weak_ptr< INode > getptr_weak()
Get a weak pointer to this node.
std::optional< std::reference_wrapper< const T > > get_ro_edge_optional(int slot)
Get a read only edge and cast it to the type T, return an optional.
u64 get_uuid() const
Get the UUID of the node.
std::string get_tex()
Get the TeX of the node.
void notify_self_state_update()
virtual void _impl_evaluate_internal()=0
evaluate the node
IEdge & get_rw_edge_base(int slot)
Get a reference to a read write edge and cast it to the type IEdge.
void on_edge_rw_edges(Func &&f)
Apply a function to the read write edges.
std::string get_dot_graph()
Get the dot graph of the node (Currently only an alias to get_dot_graph_partial).
std::shared_ptr< INode > getptr_shared()
Get a shared pointer to this node.
std::string get_label() const
Get the label of the node.
virtual std::string print_node_info() const
print the node info
void __internal_set_ro_edges(std::vector< std::shared_ptr< IEdge > > new_ro_edges)
Set the read only edges.
std::string get_dot_graph_partial()
Get the dot graph of the subgraph corresponding to the node.
std::string get_dot_graph_node_end()
Get the id of the node end in the dot graph.
std::optional< std::reference_wrapper< T > > get_rw_edge_optional(int slot)
Get a read write edge and cast it to the type T, return an optional.
virtual std::string _impl_get_label() const =0
get the label of the node
const T & get_ro_edge(int slot)
Get a read only edge and cast it to the type T.
virtual std::string _impl_get_dot_graph_partial() const
get the dot graph of the node partial
std::vector< std::shared_ptr< IEdge > > & get_rw_edges()
Get the read write edges.
virtual std::string _impl_get_tex() const =0
get the tex of the node
virtual std::string _impl_get_dot_graph_node_end() const
get the dot graph of the node end
const IEdge & get_ro_edge_base(int slot)
Get a reference to a read only edge.
Tracks the lifetime of an object of type T and notifies observers through static callbacks.
T & get_check_ref(const std::unique_ptr< T > &ptr, SourceLocation loc=SourceLocation())
Takes a std::unique_ptr and returns a reference to the object it holds. It throws a std::runtime_erro...
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
This file contains the definition for the stacktrace related functionality.