53  : m_trace_mng(trace_mng)
 
 
   61  template <
class ContainerT>
 
   62  class IterableEnsembleT
 
   65    IterableEnsembleT(ContainerT& elements) : m_empty_container(
nullptr), m_elements(elements) {}
 
   67    IterableEnsembleT() : m_empty_container(
new ContainerT()), m_elements(*m_empty_container){}
 
   69    virtual ~IterableEnsembleT(){
if (m_empty_container) 
delete 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;