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 typedef VertexType VertexRef;
111 typedef EdgeType EdgeRef;
116 void addEdge(
const VertexType& source_vertex,
const VertexType& target_vertex,
const EdgeType& source_to_target_edge)
118 _addEdge(source_vertex,target_vertex,source_to_target_edge);
121 void addEdge(VertexType&& source_vertex, VertexType&& target_vertex, EdgeType&& source_to_target_edge)
123 _addEdge(source_vertex,target_vertex,source_to_target_edge);
126 template <
class Vertex,
class Edge>
127 void _addEdge(Vertex source_vertex, Vertex target_vertex, Edge source_to_target_edge)
129 bool has_edge = (_getEdgeIndex(source_vertex,target_vertex).first != -1 || m_edge_to_vertex_map.find(source_to_target_edge) != m_edge_to_vertex_map.end());
130 if (has_edge)
throw FatalErrorException(
"Cannot insert existing edge.");
131 m_edges.push_back(source_to_target_edge);
132 EdgeType& inserted_edge = m_edges.back();
133 VertexType& inserted_source_vertex = _addVertex(source_vertex);
134 VertexType& inserted_target_vertex = _addVertex(target_vertex);
136 auto adjacency_entry = m_adjacency_list[inserted_source_vertex];
137 adjacency_entry.first.push_back(inserted_target_vertex);
138 adjacency_entry.second.push_back(inserted_edge);
140 auto transposed_adjacency_entry = m_adjacency_list_transposed[inserted_target_vertex];
141 transposed_adjacency_entry.first.push_back(inserted_source_vertex);
142 transposed_adjacency_entry.second.push_back(inserted_edge);
144 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))));
150 EdgeType*
getEdge(
const VertexType& source_vertex,
const VertexType& target_vertex)
152 return _getEdge(source_vertex,target_vertex);
156 const EdgeType*
getEdge(
const VertexType& source_vertex,
const VertexType& target_vertex)
const
158 return _getEdge(source_vertex,target_vertex);
161 EdgeType* _getEdge(
const VertexType& source_vertex,
const VertexType& target_vertex)
164 EdgeTypeRefArray edge_array;
165 std::tie(edge_index,edge_array) = _getEdgeIndex(source_vertex,target_vertex);
166 if (edge_index == -1)
return nullptr;
167 else return &edge_array[edge_index].get();
172 VertexType* getSourceVertex(
const EdgeType& edge)
174 typename EdgeToVertexMap::iterator edge_entry = m_edge_to_vertex_map.find(edge);
175 if (edge_entry != m_edge_to_vertex_map.end())
return &(edge_entry->second.first.get());
179 const VertexType* getSourceVertex(
const EdgeType& edge)
const
181 auto edge_entry = m_edge_to_vertex_map.find(edge);
182 if (edge_entry != m_edge_to_vertex_map.end())
return &edge_entry->second.first.get();
186 VertexType* getTargetVertex(
const EdgeType& edge)
188 auto edge_entry = m_edge_to_vertex_map.find(edge);
189 if (edge_entry != m_edge_to_vertex_map.end())
return &edge_entry->second.second.get();
193 const VertexType* getTargetVertex(
const EdgeType& edge)
const
195 auto edge_entry = m_edge_to_vertex_map.find(edge);
196 if (edge_entry != m_edge_to_vertex_map.end())
return &edge_entry->second.second.get();
200 VertexSet vertices() {
return VertexSet(m_vertices);}
201 EdgeSet edges() {
return EdgeSet(m_edges);}
203 ConnectedEdgeSet inEdges(
const VertexType& vertex)
205 auto found_vertex = m_adjacency_list_transposed.find(vertex);
206 if (found_vertex == m_adjacency_list_transposed.end())
208 return ConnectedEdgeSet();
210 else return ConnectedEdgeSet(found_vertex->second.second);
213 ConnectedEdgeSet outEdges(
const VertexType& vertex)
215 auto found_vertex = m_adjacency_list.find(vertex);
216 if (found_vertex == m_adjacency_list.end())
218 return ConnectedEdgeSet();
220 else return ConnectedEdgeSet(found_vertex->second.second);
224 ITraceMng* m_trace_mng;
225 VertexList m_vertices;
227 AdjacencyListType m_adjacency_list;
233 template <
class Vertex>
234 VertexType& _addVertex(Vertex vertex)
237 auto found_vertex = std::find_if(m_vertices.begin(), m_vertices.end(), [&vertex](
const VertexType& u){return (!(u < vertex) && !(vertex < u));});
238 if (found_vertex == m_vertices.end())
240 m_vertices.push_back(vertex);
241 return m_vertices.back();
243 else return *found_vertex;
246 template <
class Vertex>
247 std::pair<Integer,EdgeTypeRefArray> _getEdgeIndex(Vertex source_vertex, Vertex target_vertex)
249 typename AdjacencyListType::iterator found_source_vertex = m_adjacency_list.find(source_vertex);
250 if (found_source_vertex == m_adjacency_list.end())
return std::make_pair(-1,EdgeTypeRefArray());
251 Integer target_vertex_index = _getTargetVertexIndex(found_source_vertex,target_vertex);
252 return std::make_pair(target_vertex_index,found_source_vertex->second.second);
255 template <
class Vertex>
256 Integer _getTargetVertexIndex(
typename AdjacencyListType::iterator source_vertex_map_entry, Vertex target_vertex)
258 if (source_vertex_map_entry == m_adjacency_list.end())
return -1;
259 return _getConnectedVertexIndex(source_vertex_map_entry,target_vertex);
262 template <
class Vertex>
263 Integer _getConnectedVertexIndex(
typename AdjacencyListType::iterator vertex_map_entry, Vertex connected_vertex)
265 VertexTypeRefArray& vertex_array = vertex_map_entry->second.first;
267 std::iota(indexes.begin(),indexes.end(),0);
268 auto connected_vertex_index = std::find_if(indexes.begin(), indexes.end(),
269 [&](
const Integer index) {return (!(vertex_array[index] < connected_vertex) && !(connected_vertex < vertex_array[index]));} );
270 if (connected_vertex_index == indexes.end())
return -1;
271 else return *connected_vertex_index;