53 : m_trace_mng(trace_mng)
61 template <
class ContainerT>
71 typedef typename ContainerT::iterator iterator;
72 typedef typename ContainerT::const_iterator const_iterator;
74 iterator begin() {
return m_elements.begin();}
75 const_iterator begin()
const {
return m_elements.begin();}
77 iterator end() {
return m_elements.end();}
78 const_iterator end()
const {
return m_elements.end();}
80 Integer size() {
return m_elements.size();}
82 Integer size()
const {
return m_elements.size();}
90 typedef std::reference_wrapper<VertexType> VertexTypeRef;
91 typedef std::reference_wrapper<const VertexType> VertexTypeConstRef;
92 typedef std::reference_wrapper<EdgeType> EdgeTypeRef;
93 typedef std::reference_wrapper<const EdgeType> EdgeTypeConstRef;
94 typedef std::list<VertexType> VertexList;
95 typedef std::list<EdgeType> EdgeList;
100 typedef std::map<VertexTypeConstRef,std::pair<VertexTypeRefArray,EdgeTypeRefArray>> AdjacencyListType;
101 typedef std::pair<VertexTypeRef,VertexTypeRef> VertexPair;
102 typedef std::map<EdgeTypeConstRef, VertexPair> EdgeToVertexMap;
112 if (std::is_pointer_v<EdgeType> && edge ==
nullptr)
return true;
133 template <
class Vertex,
class Edge>
134 void _addEdge(Vertex source_vertex, Vertex target_vertex, Edge source_to_target_edge)
136 bool has_edge = (_getEdgeIndex(source_vertex,target_vertex).first != -1 ||
137 m_edge_to_vertex_map.find(source_to_target_edge) != m_edge_to_vertex_map.end() && !isNull(source_to_target_edge));
138 if (has_edge)
throw FatalErrorException(
"Cannot insert existing edge.");
139 m_edges.push_back(source_to_target_edge);
140 EdgeType& inserted_edge = m_edges.back();
141 VertexType& inserted_source_vertex = _addVertex(source_vertex);
142 VertexType& inserted_target_vertex = _addVertex(target_vertex);
144 auto adjacency_entry = m_adjacency_list[inserted_source_vertex];
145 adjacency_entry.first.push_back(inserted_target_vertex);
146 adjacency_entry.second.push_back(inserted_edge);
148 auto transposed_adjacency_entry = m_adjacency_list_transposed[inserted_target_vertex];
149 transposed_adjacency_entry.first.push_back(inserted_source_vertex);
150 transposed_adjacency_entry.second.push_back(inserted_edge);
152 m_edge_to_vertex_map.insert(std::make_pair(std::ref(inserted_edge),std::make_pair(std::ref(inserted_source_vertex),std::ref(inserted_target_vertex))));
180 VertexType* getSourceVertex(
const EdgeType& edge)
182 typename EdgeToVertexMap::iterator edge_entry = m_edge_to_vertex_map.find(edge);
183 if (edge_entry != m_edge_to_vertex_map.end())
return &(edge_entry->second.first.get());
187 const VertexType* getSourceVertex(
const EdgeType& edge)
const
189 auto edge_entry = m_edge_to_vertex_map.find(edge);
190 if (edge_entry != m_edge_to_vertex_map.end())
return &edge_entry->second.first.get();
194 VertexType* getTargetVertex(
const EdgeType& edge)
196 auto edge_entry = m_edge_to_vertex_map.find(edge);
197 if (edge_entry != m_edge_to_vertex_map.end())
return &edge_entry->second.second.get();
201 const VertexType* getTargetVertex(
const EdgeType& edge)
const
203 auto edge_entry = m_edge_to_vertex_map.find(edge);
204 if (edge_entry != m_edge_to_vertex_map.end())
return &edge_entry->second.second.get();
208 VertexSet vertices() {
return VertexSet(m_vertices);}
209 EdgeSet edges() {
return EdgeSet(m_edges);}
211 ConnectedEdgeSet inEdges(
const VertexType& vertex)
213 auto found_vertex = m_adjacency_list_transposed.find(vertex);
214 if (found_vertex == m_adjacency_list_transposed.end())
216 return ConnectedEdgeSet();
218 else return ConnectedEdgeSet(found_vertex->second.second);
221 ConnectedEdgeSet outEdges(
const VertexType& vertex)
223 auto found_vertex = m_adjacency_list.find(vertex);
224 if (found_vertex == m_adjacency_list.end())
226 return ConnectedEdgeSet();
228 else return ConnectedEdgeSet(found_vertex->second.second);
232 ITraceMng* m_trace_mng;
233 VertexList m_vertices;
235 AdjacencyListType m_adjacency_list;
241 template <
class Vertex>
245 auto found_vertex = std::find_if(m_vertices.begin(), m_vertices.end(), [&
vertex](
const VertexType& u){return (!(u < vertex) && !(vertex < u));});
248 m_vertices.push_back(
vertex);
249 return m_vertices.back();
254 template <
class Vertex>
258 if (
found_source_vertex == m_adjacency_list.end())
return std::make_pair(-1,EdgeTypeRefArray());
263 template <
class Vertex>
264 Integer _getTargetVertexIndex(
typename AdjacencyListType::iterator source_vertex_map_entry, Vertex target_vertex)
266 if (source_vertex_map_entry == m_adjacency_list.end())
return -1;
267 return _getConnectedVertexIndex(source_vertex_map_entry,target_vertex);
270 template <
class Vertex>
271 Integer _getConnectedVertexIndex(
typename AdjacencyListType::iterator vertex_map_entry, Vertex connected_vertex)
273 VertexTypeRefArray& vertex_array = vertex_map_entry->second.first;
275 std::iota(indexes.begin(),indexes.end(),0);
276 auto connected_vertex_index = std::find_if(indexes.begin(), indexes.end(),
277 [&](
const Integer index) {return (!(vertex_array[index] < connected_vertex) && !(connected_vertex < vertex_array[index]));} );
278 if (connected_vertex_index == indexes.end())
return -1;
279 else return *connected_vertex_index;