54 : m_trace_mng(trace_mng)
62 template <
class ContainerT>
63 class IterableEnsembleT
67 IterableEnsembleT(ContainerT& elements)
68 : m_empty_container(
nullptr)
69 , m_elements(elements)
73 : m_empty_container(
new ContainerT())
74 , m_elements(*m_empty_container)
77 virtual ~IterableEnsembleT()
79 if (m_empty_container)
80 delete m_empty_container;
83 typedef typename ContainerT::iterator iterator;
84 typedef typename ContainerT::const_iterator const_iterator;
86 iterator begin() {
return m_elements.begin(); }
87 const_iterator begin()
const {
return m_elements.begin(); }
89 iterator end() {
return m_elements.end(); }
90 const_iterator end()
const {
return m_elements.end(); }
92 Integer size() {
return m_elements.size(); }
94 Integer size()
const {
return m_elements.size(); }
98 ContainerT* m_empty_container;
99 ContainerT& m_elements;
104 typedef std::reference_wrapper<VertexType> VertexTypeRef;
105 typedef std::reference_wrapper<const VertexType> VertexTypeConstRef;
106 typedef std::reference_wrapper<EdgeType> EdgeTypeRef;
107 typedef std::reference_wrapper<const EdgeType> EdgeTypeConstRef;
108 typedef std::list<VertexType> VertexList;
109 typedef std::list<EdgeType> EdgeList;
114 typedef std::map<VertexTypeConstRef, std::pair<VertexTypeRefArray, EdgeTypeRefArray>> AdjacencyListType;
115 typedef std::pair<VertexTypeRef, VertexTypeRef> VertexPair;
116 typedef std::map<EdgeTypeConstRef, VertexPair> EdgeToVertexMap;
124 bool isNull(EdgeType
const& edge)
126 if (std::is_pointer_v<EdgeType> && edge ==
nullptr)
134 typedef VertexType VertexRef;
135 typedef EdgeType EdgeRef;
140 void addEdge(
const VertexType& source_vertex,
const VertexType& target_vertex,
const EdgeType& source_to_target_edge)
142 _addEdge(source_vertex, target_vertex, source_to_target_edge);
145 void addEdge(VertexType&& source_vertex, VertexType&& target_vertex, EdgeType&& source_to_target_edge)
147 _addEdge(source_vertex, target_vertex, source_to_target_edge);
150 template <
class Vertex,
class Edge>
151 void _addEdge(Vertex source_vertex, Vertex target_vertex, Edge source_to_target_edge)
153 bool has_edge = (_getEdgeIndex(source_vertex, target_vertex).first != -1 ||
156 throw FatalErrorException(
"Cannot insert existing edge.");
157 m_edges.push_back(source_to_target_edge);
158 EdgeType& inserted_edge = m_edges.back();
159 VertexType& inserted_source_vertex = _addVertex(source_vertex);
160 VertexType& inserted_target_vertex = _addVertex(target_vertex);
162 auto adjacency_entry = m_adjacency_list[inserted_source_vertex];
163 adjacency_entry.first.push_back(inserted_target_vertex);
164 adjacency_entry.second.push_back(inserted_edge);
167 transposed_adjacency_entry.first.push_back(inserted_source_vertex);
168 transposed_adjacency_entry.second.push_back(inserted_edge);
170 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))));
176 EdgeType*
getEdge(
const VertexType& source_vertex,
const VertexType& target_vertex)
178 return _getEdge(source_vertex, target_vertex);
182 const EdgeType*
getEdge(
const VertexType& source_vertex,
const VertexType& target_vertex)
const
184 return _getEdge(source_vertex, target_vertex);
187 EdgeType* _getEdge(
const VertexType& source_vertex,
const VertexType& target_vertex)
190 EdgeTypeRefArray edge_array;
191 std::tie(edge_index, edge_array) = _getEdgeIndex(source_vertex, target_vertex);
192 if (edge_index == -1)
195 return &edge_array[edge_index].get();
200 VertexType* getSourceVertex(
const EdgeType& edge)
204 return &(edge_entry->second.first.get());
209 const VertexType* getSourceVertex(
const EdgeType& edge)
const
213 return &edge_entry->second.first.get();
218 VertexType* getTargetVertex(
const EdgeType& edge)
222 return &edge_entry->second.second.get();
227 const VertexType* getTargetVertex(
const EdgeType& edge)
const
231 return &edge_entry->second.second.get();
236 VertexSet vertices() {
return VertexSet(m_vertices); }
237 EdgeSet edges() {
return EdgeSet(m_edges); }
239 ConnectedEdgeSet inEdges(
const VertexType& vertex)
243 return ConnectedEdgeSet();
246 return ConnectedEdgeSet(found_vertex->second.second);
249 ConnectedEdgeSet outEdges(
const VertexType& vertex)
251 auto found_vertex = m_adjacency_list.find(vertex);
252 if (found_vertex == m_adjacency_list.end()) {
253 return ConnectedEdgeSet();
256 return ConnectedEdgeSet(found_vertex->second.second);
261 ITraceMng* m_trace_mng;
262 VertexList m_vertices;
264 AdjacencyListType m_adjacency_list;
270 template <
class Vertex>
271 VertexType& _addVertex(Vertex vertex)
274 auto found_vertex = std::find_if(m_vertices.begin(), m_vertices.end(), [&vertex](
const VertexType& u) { return (!(u < vertex) && !(vertex < u)); });
275 if (found_vertex == m_vertices.end())
277 m_vertices.push_back(vertex);
278 return m_vertices.back();
281 return *found_vertex;
284 template <
class Vertex>
285 std::pair<Integer, EdgeTypeRefArray> _getEdgeIndex(Vertex source_vertex, Vertex target_vertex)
287 typename AdjacencyListType::iterator found_source_vertex = m_adjacency_list.find(source_vertex);
288 if (found_source_vertex == m_adjacency_list.end())
289 return std::make_pair(-1, EdgeTypeRefArray());
290 Integer target_vertex_index = _getTargetVertexIndex(found_source_vertex, target_vertex);
291 return std::make_pair(target_vertex_index, found_source_vertex->second.second);
294 template <
class Vertex>
295 Integer _getTargetVertexIndex(
typename AdjacencyListType::iterator source_vertex_map_entry, Vertex target_vertex)
297 if (source_vertex_map_entry == m_adjacency_list.end())
299 return _getConnectedVertexIndex(source_vertex_map_entry, target_vertex);
302 template <
class Vertex>
303 Integer _getConnectedVertexIndex(
typename AdjacencyListType::iterator vertex_map_entry, Vertex connected_vertex)
305 VertexTypeRefArray& vertex_array = vertex_map_entry->second.first;
307 std::iota(indexes.begin(), indexes.end(), 0);
308 auto connected_vertex_index = std::find_if(indexes.begin(), indexes.end(),
309 [&](
const Integer index) { return (!(vertex_array[index] < connected_vertex) && !(connected_vertex < vertex_array[index])); });
310 if (connected_vertex_index == indexes.end())
313 return *connected_vertex_index;