15template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
17 return try_find_edge_desc_by_id(edge_id).has_value();
20template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
22 std::vector<std::size_t> ids;
23 for (
auto [e, eend] = boost::edges(g); e != eend; ++e) {
24 ids.push_back(get_edge_id(*e));
29template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
31 auto it_u = id_to_bgl.find(u);
32 auto it_v = id_to_bgl.find(v);
33 if (it_u == id_to_bgl.end() || it_v == id_to_bgl.end()) {
36 return collect_edge_ids_between(it_u->second, it_v->second);
39template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
41 auto e = get_edge_desc_by_id(edge_id);
43 node_id_of(boost::source(e, g)),
44 node_id_of(boost::target(e, g))
48template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
52 invalidate_min_cost_flow_state();
53 VertexDesc bu = get_or_create_vertex(u);
54 VertexDesc bv = get_or_create_vertex(v);
56 if constexpr (!Multi) {
57 auto [e, exists] = boost::edge(bu, bv, g);
60 return get_edge_id(e);
64 auto [e, added] = boost::add_edge(bu, bv, g);
67 assign_next_edge_id(e);
68 return get_edge_id(e);
71template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
74std::size_t Graph<NodeID, EdgeWeight, Directed, Multi, Weighted, OutEdgeSelector, VertexSelector>::add_edge_with_id(
const NodeID& u,
const NodeID& v) {
75 invalidate_min_cost_flow_state();
76 VertexDesc bu = get_or_create_vertex(u);
77 VertexDesc bv = get_or_create_vertex(v);
79 if constexpr (!Multi) {
80 auto [e, exists] = boost::edge(bu, bv, g);
82 return get_edge_id(e);
86 auto [e, added] = boost::add_edge(bu, bv, g);
88 assign_next_edge_id(e);
89 return get_edge_id(e);
92template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
94 invalidate_min_cost_flow_state();
95 auto edge_desc = try_find_edge_desc_by_id(edge_id);
96 if (!edge_desc.has_value()) {
97 throw std::runtime_error(
"Edge lookup failed: edge not found.");
99 edge_properties.erase(edge_id);
100 erase_edge_id_index(edge_id);
101 boost::remove_edge(*edge_desc, g);
104template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
107 auto edge_it = edge_properties.find(edge_id);
108 if (edge_it == edge_properties.end()) {
109 throw std::runtime_error(
"Edge attribute lookup failed: edge has no attributes.");
111 auto attr_it = edge_it->second.find(key);
112 if (attr_it == edge_it->second.end()) {
113 throw std::runtime_error(
"Edge attribute lookup failed: key not found.");
116 return std::any_cast<T>(attr_it->second);
117 }
catch (
const std::bad_any_cast&) {
118 throw std::runtime_error(
"Edge attribute lookup failed: stored type does not match requested type.");
122template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
125 auto edge_it = edge_properties.find(edge_id);
126 if (edge_it == edge_properties.end()) {
129 auto attr_it = edge_it->second.find(key);
130 if (attr_it == edge_it->second.end()) {
133 if (
const auto* value = std::any_cast<T>(&(attr_it->second))) {
139template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
141 if (key ==
"weight") {
142 if constexpr (Weighted) {
143 return static_cast<double>(get_edge_weight(edge_id));
145 throw std::runtime_error(
"Edge attribute lookup failed: graph has no built-in edge weight.");
149 auto edge_it = edge_properties.find(edge_id);
150 if (edge_it == edge_properties.end()) {
151 throw std::runtime_error(
"Edge attribute lookup failed: edge has no attributes.");
153 auto attr_it = edge_it->second.find(key);
154 if (attr_it == edge_it->second.end()) {
155 throw std::runtime_error(
"Edge attribute lookup failed: key not found.");
158 if (
auto numeric_value = detail::try_numeric_any_cast(attr_it->second)) {
159 return *numeric_value;
162 throw std::runtime_error(
"Edge attribute lookup failed: stored value is not numeric.");
165template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
169 auto e = get_edge_desc_by_id(edge_id);
170 return weight_map[e];
173template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
176void Graph<NodeID, EdgeWeight, Directed, Multi, Weighted, OutEdgeSelector, VertexSelector>::set_edge_weight(std::size_t edge_id, EdgeWeight w) {
177 invalidate_min_cost_flow_state();
178 auto e = get_edge_desc_by_id(edge_id);
182template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
185 invalidate_min_cost_flow_state();
186 (void)get_edge_desc_by_id(edge_id);
187 edge_properties[edge_id][key] = make_attr_any(value);
Attribute-bearing edge insertion helpers and attribute-oriented graph method definitions.
Graph wrapper around Boost Graph Library with Python-inspired helpers.
Definition graph.hpp:288
double get_edge_numeric_attr(const NodeID &u, const NodeID &v, const std::string &key) const
Reads an endpoint-selected edge attribute as a numeric value.
Definition attributes.hpp:220
void set_edge_attr(std::size_t edge_id, const std::string &key, const T &value)
Stores a typed attribute on an edge identified by edge ID.
Definition multigraph.hpp:184
void remove_edge(const NodeID &u, const NodeID &v)
Removes all edges between two endpoints.
Definition graph.hpp:997
std::pair< NodeID, NodeID > get_edge_endpoints(std::size_t edge_id) const
Returns the endpoints of an edge identified by its wrapper-managed ID.
Definition multigraph.hpp:40
std::optional< T > try_get_edge_attr(const NodeID &u, const NodeID &v, const std::string &key) const
Attempts to read a typed edge attribute selected by endpoints.
Definition attributes.hpp:200
T get_edge_attr(const NodeID &u, const NodeID &v, const std::string &key) const
Reads a typed edge attribute selected by endpoints.
Definition attributes.hpp:164
std::vector< std::size_t > edge_ids() const
Returns all wrapper-managed edge IDs currently present in the graph.
Definition multigraph.hpp:21
bool has_edge_id(std::size_t edge_id) const
Returns whether an edge with the given wrapper-managed ID exists.
Definition multigraph.hpp:16