53 : m_trace_mng(trace_mng)
61 template <
class ContainerT>
65 IterableEnsembleT(ContainerT& elements) : m_empty_container(
nullptr), m_elements(elements) {}
67 IterableEnsembleT() : m_empty_container(
new ContainerT()), m_elements(*m_empty_container){}
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();}
85 ContainerT* m_empty_container;
86 ContainerT& m_elements;
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;
110 bool isNull(EdgeType
const& edge)
112 if (std::is_pointer_v<EdgeType> && edge ==
nullptr)
return true;
117 typedef VertexType VertexRef;
118 typedef EdgeType EdgeRef;
123 void addEdge(
const VertexType& source_vertex,
const VertexType& target_vertex,
const EdgeType& source_to_target_edge)
125 _addEdge(source_vertex,target_vertex,source_to_target_edge);
128 void addEdge(VertexType&& source_vertex, VertexType&& target_vertex, EdgeType&& source_to_target_edge)
130 _addEdge(source_vertex,target_vertex,source_to_target_edge);
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))));
158 EdgeType*
getEdge(
const VertexType& source_vertex,
const VertexType& target_vertex)
160 return _getEdge(source_vertex,target_vertex);
164 const EdgeType*
getEdge(
const VertexType& source_vertex,
const VertexType& target_vertex)
const
166 return _getEdge(source_vertex,target_vertex);
169 EdgeType* _getEdge(
const VertexType& source_vertex,
const VertexType& target_vertex)
172 EdgeTypeRefArray edge_array;
173 std::tie(edge_index,edge_array) = _getEdgeIndex(source_vertex,target_vertex);
174 if (edge_index == -1)
return nullptr;
175 else return &edge_array[edge_index].get();
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>
242 VertexType& _addVertex(Vertex vertex)
245 auto found_vertex = std::find_if(m_vertices.begin(), m_vertices.end(), [&vertex](
const VertexType& u){return (!(u < vertex) && !(vertex < u));});
246 if (found_vertex == m_vertices.end())
248 m_vertices.push_back(vertex);
249 return m_vertices.back();
251 else return *found_vertex;
254 template <
class Vertex>
255 std::pair<Integer,EdgeTypeRefArray> _getEdgeIndex(Vertex source_vertex, Vertex target_vertex)
257 typename AdjacencyListType::iterator found_source_vertex = m_adjacency_list.find(source_vertex);
258 if (found_source_vertex == m_adjacency_list.end())
return std::make_pair(-1,EdgeTypeRefArray());
259 Integer target_vertex_index = _getTargetVertexIndex(found_source_vertex,target_vertex);
260 return std::make_pair(target_vertex_index,found_source_vertex->second.second);
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;