GraphDom
Loading...
Searching...
No Matches
adj_list_base_iterator.h
1/*
2 * Copyright 2026 Michele Comparini
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#ifndef GRAPHDOM_ADJ_LIST_BASE_ITERATOR_IMPL_H
8#define GRAPHDOM_ADJ_LIST_BASE_ITERATOR_IMPL_H
9
10#include <stdexcept>
11#include <variant>
12
13#include "../adj_list_base_iterator.h"
14
15template<typename VertexType>
16template<typename VertexContainerPointerType>
17graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::adj_list_base_iterator() :
18iterator_owner_graph(nullptr),
19iterator_owner_graph_edges_type(mixed),
20edge_begin_point_vertex_container(nullptr),
21edges_type_restriction(none),
22inner_iterator_edge_current_type(undirected),
23inner_iterator( special_begin_end_indicator() )
24{}
25
26template<typename VertexType>
27template<typename VertexContainerPointerType>
28graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::adj_list_base_iterator(
29 const graphdom::graph<VertexType>* const iterator_owner_pointer,
30 const typename graphdom::graph<VertexType>::graph_edges_type iterator_owner_graph_edges_type,
31 const VertexContainerPointerType edge_begin_point_vertex_container,
32 const typename graphdom::graph<VertexType>::edges_type_selection_type edges_type_restriction,
33 const graphdom::edge_type inner_iterator_edge_current_type) :
34iterator_owner_graph(iterator_owner_pointer),
35iterator_owner_graph_edges_type(iterator_owner_graph_edges_type),
36edge_begin_point_vertex_container(edge_begin_point_vertex_container),
37edges_type_restriction(edges_type_restriction),
38inner_iterator_edge_current_type(inner_iterator_edge_current_type),
39inner_iterator( special_begin_end_indicator() ){}
40
41template<typename VertexType>
42template<typename VertexContainerPointerType>
43graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::adj_list_base_iterator(
44 const graphdom::graph<VertexType>* const iterator_owner_pointer,
45 const typename graph<VertexType>::graph_edges_type iterator_owner_graph_edges_type,
46 const VertexContainerPointerType edge_begin_point_vertex_container,
47 const typename graph<VertexType>::edges_type_selection_type edges_type_restriction,
48 const graphdom::edge_type inner_iterator_edge_current_type,
49 const typename graph<VertexType>::adj_set<graphdom::graph<VertexType>::vertex_container*>::iterator& inner_iterator) :
50iterator_owner_graph(iterator_owner_pointer),
51iterator_owner_graph_edges_type(iterator_owner_graph_edges_type),
52edge_begin_point_vertex_container(edge_begin_point_vertex_container),
53edges_type_restriction(edges_type_restriction),
54inner_iterator_edge_current_type(inner_iterator_edge_current_type),
55inner_iterator( inner_iterator ){}
56
57template<typename VertexType>
58template<typename VertexContainerPointerType>
59graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::adj_list_base_iterator(
60 const graphdom::graph<VertexType>* const iterator_owner_pointer,
61 const typename graph<VertexType>::graph_edges_type iterator_owner_graph_edges_type,
62 const VertexContainerPointerType edge_begin_point_vertex_container,
63 const typename graph<VertexType>::edges_type_selection_type edges_type_restriction,
64 const graphdom::edge_type inner_iterator_edge_current_type,
65 const typename graph<VertexType>::adj_set<const graphdom::graph<VertexType>::vertex_container*>::iterator& inner_iterator) :
66iterator_owner_graph(iterator_owner_pointer),
67iterator_owner_graph_edges_type(iterator_owner_graph_edges_type),
68edge_begin_point_vertex_container(edge_begin_point_vertex_container),
69edges_type_restriction(edges_type_restriction),
70inner_iterator_edge_current_type(inner_iterator_edge_current_type),
71inner_iterator( inner_iterator ){}
72
73template<typename VertexType>
74template<typename VertexContainerPointerType>
75template<typename K>
76constexpr bool graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::operator==(
77 const adj_list_base_iterator<K>& other_iterator) const {
78 if ( inner_iterator_edge_current_type != other_iterator.inner_iterator_edge_current_type ) {
79 return false;
80 }
81 if ( std::holds_alternative< special_begin_end_indicator >( inner_iterator ) ) {
82 if ( std::holds_alternative< special_begin_end_indicator >( other_iterator.inner_iterator ) ) {
83 return true;
84 }
85 return false;
86 }
87 else if ( std::holds_alternative< typename graph<VertexType>::adj_set<graph<VertexType>::vertex_container*>::iterator >( inner_iterator ) ) {
88 if ( ! std::holds_alternative< typename graph<VertexType>::adj_set<graph<VertexType>::vertex_container*>::iterator >( other_iterator.inner_iterator ) ) {
89 return false;
90 }
91 return std::get< typename graph<VertexType>::adj_set<graph<VertexType>::vertex_container*>::iterator >( inner_iterator ) ==
92 std::get< typename graph<VertexType>::adj_set<graph<VertexType>::vertex_container*>::iterator >( other_iterator.inner_iterator );
93 }
94 else {
95 if ( ! std::holds_alternative< typename graph<VertexType>::adj_set<const graph<VertexType>::vertex_container*>::iterator >( other_iterator.inner_iterator ) ) {
96 return false;
97 }
98 return std::get< typename graph<VertexType>::adj_set<const graph<VertexType>::vertex_container*>::iterator >( inner_iterator ) ==
99 std::get< typename graph<VertexType>::adj_set<const graph<VertexType>::vertex_container*>::iterator >( other_iterator.inner_iterator );
100 }
101}
102
103template<typename VertexType>
104template<typename VertexContainerPointerType>
105template<typename K>
106constexpr bool graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::operator!=(
107 const adj_list_base_iterator<K>& other_iterator) const {
108 return !( (*this) == other_iterator );
109}
110
111template<typename VertexType>
112template<typename VertexContainerPointerType>
113constexpr graphdom::edge_type graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::edge_type() const {
114 return inner_iterator_edge_current_type;
115}
116
117template<typename VertexType>
118template<typename VertexContainerPointerType>
119constexpr typename graphdom::graph<VertexType>::template adj_list_base_iterator<VertexContainerPointerType>&
120graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::internal_single_increment() {
121 if ( std::holds_alternative< typename graphdom::graph<VertexType>::adj_set<graphdom::graph<VertexType>::vertex_container*>::iterator >( inner_iterator ) ) {
122 return specialized_internal_single_increment< graphdom::graph<VertexType>::vertex_container* >();
123 }
124 if ( std::holds_alternative< typename graphdom::graph<VertexType>::adj_set<const graphdom::graph<VertexType>::vertex_container*>::iterator >( inner_iterator ) ) {
125 return specialized_internal_single_increment< const graphdom::graph<VertexType>::vertex_container* >();
126 }
127 throw std::runtime_error("adj_list overflow"); //TODO: write a better message
128}
129
130template<typename VertexType>
131template<typename VertexContainerPointerType>
132template<typename K>
133constexpr typename graphdom::graph<VertexType>::template adj_list_base_iterator<VertexContainerPointerType>&
134graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::specialized_internal_single_increment() {
135 static_assert(
136 std::is_same< K , graphdom::graph<VertexType>::vertex_container* >::value ||
137 std::is_same< K , const graphdom::graph<VertexType>::vertex_container* >::value
138 ,
139 "The typename 'K' of 'graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::specialized_internal_next<K>()' method must be a pointer to graphdom::graph<VertexType>::vertex_container"
140 );
141 auto& specialized_inner_iterator = std::get< typename graphdom::graph<VertexType>::adj_set<K>::iterator >( inner_iterator );
142 if ( inner_iterator_edge_current_type == graphdom::edge_type::undirected ) {
143 if ( std::next( specialized_inner_iterator ) == ( ( get_adj_set_if_accessible<K>(graphdom::edge_type::undirected) )->end() ) ) {
144 auto* const adj_set_directed = get_adj_set_if_accessible<K>(graphdom::edge_type::directed);
145 if ( adj_set_directed != nullptr ) {
146 if ( ! adj_set_directed->empty() ) {
147 inner_iterator = adj_set_directed->begin();
148 inner_iterator_edge_current_type = graphdom::edge_type::directed;
149 return *this;
150 }
151 }
152 }
153 ++specialized_inner_iterator;
154 return *this;
155 }
156 ++specialized_inner_iterator;
157 return *this;
158}
159
160template<typename VertexType>
161template<typename VertexContainerPointerType>
162template<typename K>
163constexpr typename graphdom::graph<VertexType>::template adj_set<K>*
164graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::get_adj_set_if_accessible(const graphdom::edge_type edge_type) const {
165 static_assert(
166 std::is_same< K , graphdom::graph<VertexType>::vertex_container* >::value ||
167 std::is_same< K , const graphdom::graph<VertexType>::vertex_container* >::value
168 ,
169 "The typename 'K' of 'graphdom::graph<VertexType>::adj_list_base_iterator<VertexContainerPointerType>::get_adj_list<K>(graphdom::edge_type edge_type)' method must be a pointer to graphdom::graph<VertexType>::vertex_container"
170 );
171 auto* const undirected_adj =
172 ( iterator_owner_graph_edges_type == mixed ) ?
173 &( ( static_cast< const typename graphdom::graph<VertexType>::mixed_graph_vertex_container<K>* >( edge_begin_point_vertex_container ) )->undirected_adj )
174 :
175 (
176 ( iterator_owner_graph_edges_type == undirected ) ?
177 &( ( static_cast< const typename graphdom::graph<VertexType>::non_mixed_graph_vertex_container<K>* >( edge_begin_point_vertex_container ) )->adj )
178 :
179 nullptr
180 );
181 auto* const directed_adj =
182 ( iterator_owner_graph_edges_type == mixed ) ?
183 &( ( static_cast< const typename graphdom::graph<VertexType>::mixed_graph_vertex_container<K>* >( edge_begin_point_vertex_container ) )->directed_adj )
184 :
185 (
186 ( iterator_owner_graph_edges_type == directed ) ?
187 &( ( static_cast< const typename graphdom::graph<VertexType>::non_mixed_graph_vertex_container<K>* >( edge_begin_point_vertex_container ) )->adj )
188 :
189 nullptr
190 );
191 if ( edge_type == edge_type::undirected ) {
192 if ( edges_type_restriction != directed_edges ) {
193 return undirected_adj;
194 }
195 return nullptr;
196 }
197 if ( edges_type_restriction != undirected_edges ) {
198 return directed_adj;
199 }
200 return nullptr;
201}
202
203#endif //GRAPHDOM_ADJ_LIST_BASE_ITERATOR_IMPL_H
Every graph created using this library is an instance of a concrete class publicly derived,...
Definition graph.h:43
edge_type
The enumerated type whose values represent the two types of edges of a graph.
Definition graph.h:21
@ undirected
This enum value means undirected edge.
Definition graph.h:22
@ directed
This enum value means directed edge.
Definition graph.h:23