GraphDom
Loading...
Searching...
No Matches
full_labeled_multiset_digraph.h
1/*
2 * Copyright 2026 Michele Comparini
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#ifndef GRAPHDOM_FULL_LABELED_MULTISET_DIGRAPH_IMPL_H
8#define GRAPHDOM_FULL_LABELED_MULTISET_DIGRAPH_IMPL_H
9
10#include "../full_labeled_multiset_digraph.h"
11
12template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
15labeled_vertex_multiset_graph<VertexType,VertexLabelType,VertexLabellerType>(),
16labeled_edge_non_mixed_graph<VertexType,EdgeLabelType,EdgeLabellerType>(),
17number_of_vertices_inserted(0) {}
18
19template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
21full_labeled_multiset_digraph(const VertexLabellerType& v_lab, const EdgeLabellerType& e_lab) :
22labeled_vertex_multiset_graph<VertexType,VertexLabelType,VertexLabellerType>(v_lab),
23labeled_edge_non_mixed_graph<VertexType,EdgeLabelType,EdgeLabellerType>(e_lab),
24number_of_vertices_inserted(0) {}
25
26template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
28full_labeled_multiset_digraph(const VertexLabellerType& v_lab, EdgeLabellerType&& e_lab) :
29labeled_vertex_multiset_graph<VertexType,VertexLabelType,VertexLabellerType>(v_lab),
30labeled_edge_non_mixed_graph<VertexType,EdgeLabelType,EdgeLabellerType>(std::move(e_lab)),
31number_of_vertices_inserted(0) {}
32
33template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
35full_labeled_multiset_digraph(VertexLabellerType&& v_lab, const EdgeLabellerType& e_lab) :
36labeled_vertex_multiset_graph<VertexType,VertexLabelType,VertexLabellerType>(std::move(v_lab)),
37labeled_edge_non_mixed_graph<VertexType,EdgeLabelType,EdgeLabellerType>(e_lab),
38number_of_vertices_inserted(0) {}
39
40template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
42full_labeled_multiset_digraph(VertexLabellerType&& v_lab, EdgeLabellerType&& e_lab) :
43labeled_vertex_multiset_graph<VertexType,VertexLabelType,VertexLabellerType>(std::move(v_lab)),
44labeled_edge_non_mixed_graph<VertexType,EdgeLabelType,EdgeLabellerType>(std::move(e_lab)),
45number_of_vertices_inserted(0) {}
46
47template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
48graphdom::full_labeled_multiset_digraph<VertexType,VertexLabelType,EdgeLabelType,VertexLabellerType,EdgeLabellerType>::~full_labeled_multiset_digraph() {
49 while ( ! vertices.empty() ) {
50 auto& vertex_to_erase = vertices.front();
51 auto& vertex_to_erase_adj = vertex_to_erase.adj;
52 for (auto edge_endpoint_to_deallocate = vertex_to_erase_adj.begin();
53 edge_endpoint_to_deallocate != vertex_to_erase_adj.end();
54 ++edge_endpoint_to_deallocate) {
55 safe_edge_endpoint_deallocation(*edge_endpoint_to_deallocate); // This is to avoid memory leaks
56 }
57 vertices.pop_front();
58 }
59}
60
61template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
65
66template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
68 const typename graph<VertexType>::vertex_const_handle& vertex) const {
69 if ( graphdom::graph<VertexType>::get_owner_graph(vertex) != this ) {
70 throw std::runtime_error("Error"); //TODO: write a better message
71 }
72 const auto* const vertex_container_ptr = static_cast< const vertex_container* >( graphdom::graph< VertexType >::get_vertex_container( vertex ) );
73 return vertex_container_ptr->vertex_label;
74}
75
76template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
78 const typename graph<VertexType>::adj_list_const_iterator& edge) const {
79 if ( graphdom::graph<VertexType>::get_owner_graph( edge ) != this ) {
80 throw std::runtime_error("Error"); //TODO: write a better message
81 }
82 return (
83 *(
84 static_cast<edge_endpoint*>(
86 )
87 )
88 ).edge_label;
89}
90
91template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
94 if( graphdom::graph<VertexType>::get_owner_graph(vertex) == this ) {
95 const auto vertex_container_to_erase_ptr = graphdom::graph<VertexType>::get_vertex_container(vertex);
96 if ( vertex_container_to_erase_ptr != nullptr ) {
97 auto before_vertex_container_to_erase_found_vertices_itr = vertices.end();
98 for(auto vertices_itr = vertices.before_begin(); vertices_itr != vertices.end(); ++vertices_itr) {
99 auto vertices_itr_next = std::next(vertices_itr);
100 if( vertices_itr_next != vertices.end() ){
101 if( (&(*vertices_itr_next)) == vertex_container_to_erase_ptr ){
102 before_vertex_container_to_erase_found_vertices_itr = vertices_itr;
103 }
104 auto& vertices_itr_next_vertex_container = *vertices_itr_next;
105 auto& vertices_itr_next_vertex_container_adj = vertices_itr_next_vertex_container.adj;
106 auto vertices_itr_next_vertex_container_adj_found_result_itr = vertices_itr_next_vertex_container_adj.find(vertex_container_to_erase_ptr);
107 if ( vertices_itr_next_vertex_container_adj_found_result_itr != vertices_itr_next_vertex_container_adj.end() ) {
108 safe_edge_endpoint_deallocation(*vertices_itr_next_vertex_container_adj_found_result_itr); // This is to avoid memory leaks
109 vertices_itr_next_vertex_container_adj.erase(vertices_itr_next_vertex_container_adj_found_result_itr);
110 }
111 }
112 }
113 if ( before_vertex_container_to_erase_found_vertices_itr != vertices.end() ) {
114 const auto& vertex_container_to_erase_forward_list_iterator = std::next( before_vertex_container_to_erase_found_vertices_itr );
115 auto& adj_to_erase = (*vertex_container_to_erase_forward_list_iterator).adj;
116 for (auto adj_to_erase_itr = adj_to_erase.begin(); adj_to_erase_itr != adj_to_erase.end(); ++adj_to_erase_itr) {
117 safe_edge_endpoint_deallocation(*adj_to_erase_itr); // This is to avoid memory leaks
118 }
119 vertices.erase_after(before_vertex_container_to_erase_found_vertices_itr);
120 --number_of_vertices_inserted;
121 }
122 //TODO:: Evaluate a possible exception throw HERE
123 }
124 //TODO:: Evaluate a possible exception throw HERE
125 }
126 //TODO:: Evaluate a possible exception throw HERE
127}
128
129template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
130typename graphdom::graph<VertexType>::adj_list_iterator
132 const typename graph<VertexType>::adj_list_const_iterator& edge_itr) {
133 if ( graphdom::graph<VertexType>::get_owner_graph(edge_itr) != this ) {
134 throw std::runtime_error("Error"); //TODO: write a better message
135 }
136 auto const edge_itr_begin_point = const_cast<vertex_container*>( static_cast< const vertex_container* >( graphdom::graph<VertexType>::get_begin_point(edge_itr) ) );
137 auto edge_itr_inner_iterator = graphdom::multiset_graph<VertexType>::get_inner_iterator( edge_itr );
138 auto const edge_itr_endpoint = *edge_itr_inner_iterator;
139 safe_edge_endpoint_deallocation(edge_itr_endpoint);
141 this,
142 edge_itr_begin_point,
143 directed,
144 ( edge_itr_begin_point->adj ).erase( edge_itr_inner_iterator )
145 );
146}
147
148template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
150 const typename graph<VertexType>::vertex_const_handle& vertex) {
151 if ( graphdom::graph<VertexType>::get_owner_graph(vertex) != this ) {
152 throw std::runtime_error("Error"); //TODO: write a better message
153 }
154 const auto* const vertex_container_ptr = static_cast< const vertex_container* >( graphdom::graph< VertexType >::get_vertex_container( vertex ) );
155 return const_cast< VertexLabelType& >( (*vertex_container_ptr).vertex_label );
156}
157
158template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
161 const VertexType& v_core, const VertexLabelType& vertex_label) {
162 vertices.emplace_front(
163 v_core,
164 vertex_label
165 );
166 ++number_of_vertices_inserted;
168 this,
169 vertices.front(),
171 );
172}
173
174template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
177const VertexType& v_core, VertexLabelType&& vertex_label) {
178 vertices.emplace_front(
179 v_core,
180 std::move(vertex_label)
181 );
182 ++number_of_vertices_inserted;
184 this,
185 vertices.front(),
187 );
188}
189
190template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
193VertexType&& v_core, const VertexLabelType& vertex_label) {
194 vertices.emplace_front(
195 std::move(v_core),
196 vertex_label
197 );
198 ++number_of_vertices_inserted;
200 this,
201 vertices.front(),
203 );
204}
205
206template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
209VertexType&& v_core, VertexLabelType&& vertex_label) {
210 vertices.emplace_front(
211 std::move(v_core),
212 std::move(vertex_label)
213 );
214 ++number_of_vertices_inserted;
216 this,
217 vertices.front(),
219 );
220}
221
222template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
224 const typename graph<VertexType>::adj_list_const_iterator& edge ) {
225 if ( graphdom::graph<VertexType>::get_owner_graph( edge ) != this ) {
226 throw std::runtime_error("Error"); //TODO: write a better message
227 }
228 return (
229 *(
230 static_cast<edge_endpoint*>(
232 )
233 )
234 ).edge_label;
235}
236
237template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
239 const typename graph<VertexType>::vertex_const_handle& tail,
240 const typename graph<VertexType>::vertex_const_handle& head,
241 const EdgeLabelType& edge_label) {
242 if (
243 graphdom::graph<VertexType>::get_owner_graph( tail ) != this ||
244 graphdom::graph<VertexType>::get_owner_graph( head ) != this
245 ) {
246 throw std::runtime_error("Error"); //TODO: write a better message
247 }
248 auto const begin_point_vertex_container = static_cast< const vertex_container* >( graphdom::graph<VertexType>::get_vertex_container( tail ) );
249 auto const end_point_vertex_container = const_cast< typename graphdom::graph<VertexType>::vertex_container* >( graphdom::graph<VertexType>::get_vertex_container( head ) );
250 if ( begin_point_vertex_container == nullptr || end_point_vertex_container == nullptr ) {
251 throw std::runtime_error("Error"); //TODO: write a better message
252 }
253 std::unique_ptr< edge_endpoint > edge_endpoint_to_insert( new edge_endpoint( end_point_vertex_container , edge_label ) );
254 const auto inner_insertion_result = ( ( begin_point_vertex_container->adj ).insert( edge_endpoint_to_insert.get() ) ).second;
255 if ( inner_insertion_result ) {
256 edge_endpoint_to_insert.release();
257 }
258}
259
260template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
262 const typename graph<VertexType>::vertex_const_handle& tail,
263 const typename graph<VertexType>::vertex_const_handle& head,
264 EdgeLabelType&& edge_label) {
265 if (
266 graphdom::graph<VertexType>::get_owner_graph( tail ) != this ||
267 graphdom::graph<VertexType>::get_owner_graph( head ) != this
268 ) {
269 throw std::runtime_error("Error"); //TODO: write a better message
270 }
271 auto const begin_point_vertex_container = static_cast< const vertex_container* >( graphdom::graph<VertexType>::get_vertex_container( tail ) );
272 auto const end_point_vertex_container = const_cast< typename graphdom::graph<VertexType>::vertex_container* >( graphdom::graph<VertexType>::get_vertex_container( head ) );
273 if ( begin_point_vertex_container == nullptr || end_point_vertex_container == nullptr ) {
274 throw std::runtime_error("Error"); //TODO: write a better message
275 }
276 const auto lower_bound = ( begin_point_vertex_container->adj ).lower_bound( end_point_vertex_container );
277 if ( lower_bound == ( begin_point_vertex_container->adj ).cend() ) {
278 ( begin_point_vertex_container->adj ).emplace_hint( lower_bound, new edge_endpoint( end_point_vertex_container , std::move(edge_label) ) );
279 }
280 else {
281 if ( ( ( begin_point_vertex_container->adj ).key_comp() )( end_point_vertex_container, *lower_bound ) ) {
282 ( begin_point_vertex_container->adj ).emplace_hint( lower_bound, new edge_endpoint( end_point_vertex_container , std::move(edge_label) ) );
283 }
284 }
285 /*
286 std::unique_ptr< edge_endpoint > edge_endpoint_to_insert( new edge_endpoint( end_point_vertex_container , std::move(edge_label_to_insert) ) );
287 const auto inner_insertion_result = ( ( begin_point_vertex_container->adj ).insert( edge_endpoint_to_insert.get() ) ).second;
288 if ( inner_insertion_result ) {
289 edge_endpoint_to_insert.release();
290 }
291 */
292}
293
294template<typename VertexType, typename VertexLabelType, typename EdgeLabelType, typename VertexLabellerType, typename EdgeLabellerType>
297 typename graphdom::graph<VertexType>::template edge_endpoint<VertexContainerPointerType>* ee_ptr) {
298 delete static_cast< edge_endpoint* >( ee_ptr );
299}
300
301#endif //GRAPHDOM_FULL_LABELED_MULTISET_DIGRAPH_IMPL_H
Definition full_labeled_multiset_digraph.h:35
void insert_edge(const typename graph< VertexType >::vertex_const_handle &tail, const typename graph< VertexType >::vertex_const_handle &head, const EdgeLabelType &edge_label) override
Definition full_labeled_multiset_digraph.h:238
std::size_t order() const override
Returns the order of *this, i.e. the number of vertices inside the graph.
Definition full_labeled_multiset_digraph.h:62
graphdom::graph< VertexType >::adj_list_iterator erase_edge(const typename graph< VertexType >::adj_list_const_iterator &) override
Definition full_labeled_multiset_digraph.h:131
const VertexLabelType & get_vertex_label(const typename graph< VertexType >::vertex_const_handle &vertex) const override
Definition full_labeled_multiset_digraph.h:67
void erase_vertex(const typename graphdom::graph< VertexType >::vertex_const_handle &vertex) override
Removes the vertex identified by vertex.
Definition full_labeled_multiset_digraph.h:92
const EdgeLabelType & get_edge_label(const typename graph< VertexType >::adj_list_const_iterator &) const override
Definition full_labeled_multiset_digraph.h:77
multiset_graph< VertexType >::vertex_handle insert_vertex(const VertexType &v_core, const VertexLabelType &vertex_label) override
Definition full_labeled_multiset_digraph.h:160
Every valid instance of this class can be used to identify a specific vertex of a graph and to access...
Definition vertex_const_handle.h:35
Every graph created using this library is an instance of a concrete class publicly derived,...
Definition graph.h:43
Every valid instance of this class can be used to identify a specific vertex of a multiset graph and ...
Definition multiset_graph_vertex_handle.h:31
Every multiset graph created using this library is an instance of a concrete class publicly derived,...
Definition multiset_graph.h:19
@ directed
This enum value means directed edge.
Definition graph.h:23