5 #ifndef BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H 6 #define BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H 14 #include <type_traits> 17 #include "../Clonable.h" 18 #include "../Exceptions.h" 19 #include "../Text/TextTools.h" 25 template<
class N,
class E,
class GraphImpl>
35 using Eref = std::shared_ptr<E>;
36 using Nref = std::shared_ptr<N>;
116 subjectGraph_(
std::shared_ptr<GraphImpl>(new GraphImpl(directed))),
139 subjectGraph_(subjectGraph ? subjectGraph :
std::shared_ptr<GraphImpl>(new GraphImpl(true))),
157 template<
class N2,
class E2>
159 subjectGraph_(graphObserver.
getGraph()),
160 graphidToN_(graphObserver.graphidToN_.size()),
161 graphidToE_(graphObserver.graphidToE_.size()),
164 indexToN_(graphObserver.indexToN_.size()),
165 indexToE_(graphObserver.indexToE_.size()),
173 NToGraphid_[node] = itN.second;
174 graphidToN_[itN.second] = node;
176 const auto& indN = graphObserver.
NToIndex_.find(itN.first);
178 if (indN != graphObserver.
NToIndex_.end())
180 NToIndex_[node] = indN->second;
181 indexToN_[indN->second] = node;
189 EToGraphid_[edge] = itE.second;
190 graphidToE_[itE.second] = edge;
192 const auto& indE = graphObserver.
EToIndex_.find(itE.first);
194 if (indE != graphObserver.
EToIndex_.end())
196 EToIndex_[edge] = indE->second;
197 indexToE_[indE->second] = edge;
205 subjectGraph_(graphObserver.subjectGraph_),
206 graphidToN_(graphObserver.graphidToN_.size()),
207 graphidToE_(graphObserver.graphidToE_.size()),
210 indexToN_(graphObserver.indexToN_.size()),
211 indexToE_(graphObserver.indexToE_.size()),
219 NToGraphid_[node] = itN.second;
220 graphidToN_[itN.second] = node;
222 const auto& indN = graphObserver.
NToIndex_.find(itN.first);
224 if (indN != graphObserver.
NToIndex_.end())
226 NToIndex_[node] = indN->second;
227 indexToN_[indN->second] = node;
235 EToGraphid_[edge] = itE.second;
236 graphidToE_[itE.second] = edge;
238 const auto& indE = graphObserver.
EToIndex_.find(itE.first);
240 if (indE != graphObserver.
EToIndex_.end())
242 EToIndex_[edge] = indE->second;
243 indexToE_[indE->second] = edge;
257 this->graphidToN_.resize(graphObserver.
graphidToN_.size());
258 this->graphidToE_.resize(graphObserver.
graphidToE_.size());
259 this->indexToN_.resize(graphObserver.
indexToN_.size());
260 this->indexToE_.resize(graphObserver.
indexToE_.size());
266 NToGraphid_[node] = itN.second;
267 graphidToN_[itN.second] = node;
269 const auto& indN = graphObserver.
NToIndex_.find(itN.first);
271 if (indN != graphObserver.
NToIndex_.end())
273 NToIndex_[node] = indN->second;
274 indexToN_[indN->second] = node;
282 EToGraphid_[edge] = itE.second;
283 graphidToE_[itE.second] = edge;
285 const auto& indE = graphObserver.
EToIndex_.find(itE.first);
287 if (indE != graphObserver.
EToIndex_.end())
289 EToIndex_[edge] = indE->second;
290 indexToE_[indE->second] = edge;
294 this->subjectGraph_ = graphObserver.
getGraph();
296 this->
getGraph()->registerObserver(
this);
307 getGraph()->unregisterObserver(
this);
334 return NToGraphid_.find(nodeObject) != NToGraphid_.end();
341 return EToGraphid_.find(edgeObject) != EToGraphid_.end();
389 std::vector<NodeGraphid> neighbors;
393 neighbors =
getGraph()->getOutgoingNeighbors(node);
396 neighbors =
getGraph()->getIncomingNeighbors(node);
399 neighbors =
getGraph()->getNeighbors(node);
412 std::vector<EdgeGraphid> edges;
416 edges =
getGraph()->getOutgoingEdges(node);
419 edges =
getGraph()->getIncomingEdges(node);
441 throw Exception(
"AssociationGraphImplObserver::createNode : node already exists: " +
nodeToString(nodeObject));
443 unsigned int newGraphNode =
getGraph()->createNode();
458 link(objectOriginNode, newNodeObject, newEdgeObject);
479 if (edgeObject != 00 &&
hasEdge(edgeObject))
482 throw Exception(
"AssociationGraphImplObserver::link: The given edge is already associated to a relation in the subjectGraph: " +
edgeToString(edgeObject) +
":" +
nodeToString(nodes.first) +
" -> " +
nodeToString(nodes.second));
485 EdgeGraphid newGraphEdge =
getGraph()->link(NToGraphid_.at(nodeObjectA), NToGraphid_.at(nodeObjectB));
487 if (graphidToE_.size() < newGraphEdge + 1)
488 graphidToE_.resize(newGraphEdge + 1);
489 graphidToE_.at(newGraphEdge) = edgeObject;
490 EToGraphid_[edgeObject] = newGraphEdge;
505 getGraph()->unlink(NToGraphid_.at(nodeObjectA), NToGraphid_.at(nodeObjectB));
537 throw Exception(
"AssociationGraphImplObserver::associateNode : node already exists: " +
nodeToString(nodeObject));
541 if (graphidToN_.size() < graphNode + 1)
542 graphidToN_.resize(graphNode + 1);
545 graphidToN_.at(graphNode) = nodeObject;
546 NToGraphid_[nodeObject] = graphNode;
557 throw Exception(
"AssociationGraphImplObserver::associateEdge : edge already exists: " +
edgeToString(edgeObject));
561 if (graphidToE_.size() < graphEdge + 1)
562 graphidToE_.resize(graphEdge + 1);
565 graphidToE_.at(graphEdge) = edgeObject;
566 EToGraphid_[edgeObject] = graphEdge;
575 typename std::map<Nref, NodeGraphid>::iterator nodeToForget = NToGraphid_.find(nodeObject);
576 graphidToN_.at(nodeToForget->second) = 00;
577 NToGraphid_.erase(nodeToForget);
583 typename std::map<Eref, EdgeGraphid>::iterator edgeToForget = EToGraphid_.find(edgeObject);
584 graphidToE_.at(edgeToForget->second) = 00;
585 EToGraphid_.erase(edgeToForget);
596 typename std::map<Nref, NodeGraphid>::const_iterator found = NToGraphid_.find(nodeObject);
597 if (found == NToGraphid_.end())
599 return found->second;
610 typename std::map<Eref, EdgeGraphid>::const_iterator found = EToGraphid_.find(edgeObject);
611 if (found == EToGraphid_.end())
613 return found->second;
622 if (node >= graphidToN_.size())
624 return graphidToN_.at(node);
629 if (node >= graphidToN_.size())
631 return graphidToN_.at(node);
636 std::vector<Nref > nodeObjects;
637 for (
typename std::vector<NodeGraphid>::iterator currNode = nodes.begin(); currNode != nodes.end(); currNode++)
639 if (*currNode > graphidToN_.size())
641 Nref foundNodeObject = graphidToN_.at(*currNode);
642 if (!foundNodeObject)
644 nodeObjects.push_back(foundNodeObject);
651 if (edge >= graphidToE_.size())
654 return graphidToE_.at(edge);
659 if (edge >= graphidToE_.size())
662 return graphidToE_.at(edge);
667 std::vector<Eref > edgeObjects;
668 for (
const auto& currEdge:edges)
670 if (currEdge > graphidToE_.size())
672 Eref foundEdgeObject = graphidToE_.at(currEdge);
673 if (!foundEdgeObject)
675 edgeObjects.push_back(foundEdgeObject);
715 return NToIndex_.find(nodeObject) != NToIndex_.end();
720 return EToIndex_.find(edgeObject) != EToIndex_.end();
730 const auto found = NToIndex_.find(nodeObject);
731 if (found == NToIndex_.end())
734 return found->second;
739 std::vector<NodeIndex> nodeIndexes(nodes.size());
741 std::transform(nodes.begin(), nodes.end(), nodeIndexes.begin(), [
this](
const Nref& nodeObject){
return this->
getNodeIndex(nodeObject);});
753 auto found = EToIndex_.find(edgeObject);
754 if (found == EToIndex_.end())
756 return found->second;
761 std::vector<EdgeIndex> edgeIndexes(edges.size());
763 std::transform(edges.begin(), edges.end(), edgeIndexes.begin(), [
this](
const Eref& edgeObject){
return this->
getEdgeIndex(edgeObject);});
779 throw Exception(
"AssociationGraphImplObserver::setNodeIndex : index already exists: " +
nodeToString(nodeObject));
780 if (NToIndex_.find(nodeObject) != NToIndex_.end())
781 throw Exception(
"AssociationGraphImplObserver::setNodeIndex : nodeObject has already an index: " +
nodeToString(nodeObject));
783 if (index >= indexToN_.size())
784 indexToN_.resize(index + 1);
787 indexToN_.at(index) = nodeObject;
788 NToIndex_[nodeObject] = index;
803 throw Exception(
"AssociationGraphImplObserver::setEdgeIndex : index already exists: " +
edgeToString(edgeObject));
804 if (EToIndex_.find(edgeObject) != EToIndex_.end())
805 throw Exception(
"AssociationGraphImplObserver::setEdgeIndex : edgeObject has already an index: " +
edgeToString(edgeObject));
807 if (index >= indexToE_.size())
808 indexToE_.resize(index + 1);
811 indexToE_.at(index) = edgeObject;
812 EToIndex_[edgeObject] = index;
825 if (NToIndex_.find(nodeObject) != NToIndex_.end())
826 throw Exception(
"AssociationGraphImplObserver::addNodeIndex : nodeObject has already an index: " +
nodeToString(nodeObject));
828 NodeIndex index =
NodeIndex(indexToN_.size());
829 for (
auto i = 0; i < indexToN_.size(); i++)
831 if (!indexToN_.at(
size_t(i)))
838 if (index >= indexToN_.size())
839 indexToN_.resize(index + 1);
842 indexToN_.at(index) = nodeObject;
843 NToIndex_[nodeObject] = index;
856 if (EToIndex_.find(edgeObject) != EToIndex_.end())
857 throw Exception(
"AssociationGraphImplObserver::addEdgeIndex : edgeObject has already an index: " +
edgeToString(edgeObject));
859 EdgeIndex index = indexToE_.size();
860 for (
auto i = 0; i < indexToE_.size(); i++)
862 if (!indexToE_.at(i))
869 if (index >= indexToE_.size())
870 indexToE_.resize(index + 1);
873 indexToE_.at(index) = edgeObject;
874 EToIndex_[edgeObject] = index;
884 return node < indexToN_.size() && indexToN_.at(node);
893 return edge < indexToE_.size() && indexToE_.at(edge);
903 return indexToN_.at(node);
913 return indexToE_.at(edge);
935 void outputToDot(
const std::string& fname,
const std::string& name)
const 943 void outputToDot(std::ostream& out,
const std::string& name)
const 945 out << (
getGraph()->isDirected() ?
"digraph" :
"graph") <<
" " << name <<
" {\n ";
946 std::set<std::pair<Nref, Nref>> alreadyFigured;
949 for (
const auto& node: allNodes)
952 for (
const auto& currChild : children)
954 if (alreadyFigured.find(std::pair<Nref, Nref>(node, currChild)) != alreadyFigured.end() || (
getGraph()->isDirected() && alreadyFigured.find(std::pair<Nref, Nref>(currChild, node)) != alreadyFigured.end()))
957 alreadyFigured.insert(std::pair<Nref, Nref>(node, currChild));
962 out << NToGraphid_.at(node);
964 out << (
getGraph()->isDirected() ?
" -> " :
" -- ");
969 out << NToGraphid_.at(currChild);
973 out <<
" [style = dotted]";
976 out <<
" [label = e";
979 out << EToGraphid_.at(edge) <<
"]";
992 template<
class GraphIterator,
bool is_const>
1030 std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator>
allNodesIterator()
const 1195 std::vector<Nref > leavesToReturn;
1197 std::vector<NodeGraphid> graphLeaves =
getGraph()->getAllLeaves();
1199 for (
typename std::vector<NodeGraphid>::iterator currGraphLeave = graphLeaves.begin(); currGraphLeave != graphLeaves.end(); currGraphLeave++)
1201 Nref foundLeafObject = graphidToN_.at(*currGraphLeave);
1202 if (foundLeafObject != 00)
1203 leavesToReturn.push_back(foundLeafObject);
1205 return leavesToReturn;
1216 std::vector<NodeIndex> leavesToReturn;
1219 std::vector<NodeGraphid> graphLeaves =
getGraph()->getAllLeaves();
1221 for (
typename std::vector<NodeGraphid>::iterator currGraphLeave = graphLeaves.begin(); currGraphLeave != graphLeaves.end(); currGraphLeave++)
1223 Nref foundLeafObject = graphidToN_.at(*currGraphLeave);
1224 if (foundLeafObject != 00)
1225 leavesToReturn.push_back(
getNodeIndex(foundLeafObject));
1227 return leavesToReturn;
1238 std::vector<Nref > nodesToReturn;
1240 std::vector<NodeGraphid> graphNodes =
getGraph()->getAllInnerNodes();
1242 for (
const auto& currGraphNode : graphNodes)
1244 Nref foundNodeObject = graphidToN_.at(currGraphNode);
1245 if (foundNodeObject != 00)
1246 nodesToReturn.push_back(foundNodeObject);
1248 return nodesToReturn;
1259 std::vector<NodeIndex> nodesToReturn;
1261 std::vector<NodeGraphid> graphNodes =
getGraph()->getAllInnerNodes();
1263 for (
const auto& currGraphNode : graphNodes)
1265 Nref foundNodeObject = graphidToN_.at(currGraphNode);
1266 if (foundNodeObject != 00)
1267 nodesToReturn.push_back(
getNodeIndex(foundNodeObject));
1269 return nodesToReturn;
1280 std::vector<Nref > nodesToReturn;
1281 for (
typename std::vector<Nref >::const_iterator currNodeObject = graphidToN_.begin(); currNodeObject != graphidToN_.end(); currNodeObject++)
1283 if (*currNodeObject != 00)
1285 nodesToReturn.push_back(*currNodeObject);
1288 return nodesToReturn;
1299 std::vector<NodeIndex> indexesToReturn;
1300 for (
const auto& currNodeObject : graphidToN_)
1302 if (currNodeObject != 00)
1304 indexesToReturn.push_back(
getNodeIndex(currNodeObject));
1307 return indexesToReturn;
1318 std::vector<typename AssociationGraphObserver<N, E>::EdgeIndex > indexesToReturn;
1319 for (
typename std::vector<Eref >::const_iterator currEdgeObject = graphidToE_.begin(); currEdgeObject != graphidToE_.end(); currEdgeObject++)
1321 if (*currEdgeObject != 00)
1323 indexesToReturn.push_back(
getEdgeIndex(*currEdgeObject));
1326 return indexesToReturn;
1330 template<
class GraphIterator,
bool is_const>
1368 std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator>
allEdgesIterator()
const 1407 std::vector<Eref > branchesToReturn;
1408 for (
typename std::vector<Eref >::const_iterator currBrObject = graphidToE_.begin(); currBrObject != graphidToE_.end(); currBrObject++)
1410 if (*currBrObject != 00)
1412 branchesToReturn.push_back(*currBrObject);
1415 return branchesToReturn;
1479 for (
typename std::vector<EdgeGraphid>::const_iterator currEdge = edgesToDelete.begin(); currEdge != edgesToDelete.end(); currEdge++)
1481 if (graphidToE_.size() > *currEdge)
1483 Eref edgeObject = graphidToE_.at(*currEdge);
1484 graphidToE_.at(*currEdge) = 00;
1486 EToGraphid_.erase(edgeObject);
1497 for (
typename std::vector<EdgeGraphid>::const_iterator currNode = nodesToDelete.begin(); currNode != nodesToDelete.end(); currNode++)
1499 if (graphidToN_.size() > *currNode)
1501 Nref nodeObject = graphidToN_.at(*currNode);
1502 graphidToN_.at(*currNode) = 00;
1504 NToGraphid_.erase(nodeObject);
1523 return NToGraphid_.size();
1533 return EToGraphid_.size();
1545 for (
typename std::vector<Nref >::const_iterator currNodeObject = graphidToN_.begin(); currNodeObject != graphidToN_.end(); currNodeObject++)
1547 if ((*currNodeObject != 00) && (
isLeaf(*currNodeObject)))
1571 template<
class N,
class E>
1574 #endif // BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H
std::vector< Nref > getAllNodes() const
std::vector< NodeIndex > getAllLeavesIndexes() const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > allEdgesIterator()
std::vector< EdgeIndex > getIncomingEdges(NodeIndex node) const
std::vector< Nref > getOutgoingNeighbors(const Nref node) const
void link(Nref nodeObjectA, Nref nodeObjectB, Eref edgeObject=00)
const AssociationGraphImplObserver< N, E, GraphImpl > & agio_
std::vector< Eref > getIncomingEdges(const Nref node) const
NodeIndex setNodeIndex(const Nref nodeObject, NodeIndex index)
std::vector< Nref > getLeavesFromNode(Nref node, unsigned int maxDepth) const
Defines a Graph Associator. It is a template which follows (subscribed to) a Graph.
std::vector< Eref > getOutgoingEdges(const Nref node) const
void setEdgeLinking(Nref nodeA, Nref nodeB, Eref edge)
NodeGraphid getNodeGraphid(const Nref nodeObject) const
virtual bool end() const =0
std::vector< Nref > getAllInnerNodes() const
void outputToDot(std::ostream &out, const std::string &name) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > allNodesIterator() const
std::vector< Nref > graphidToN_
bool hasEdge(Eref edgeObject) const
NodeIndex getRootIndex() const
size_t getDegree(const Nref node) const
std::vector< EdgeIndex > getEdgeIndexes(std::vector< Eref > edges) const
bool isLeaf(const Nref node) const
Is the node a leaf?
Eref getEdgeFromGraphid(EdgeGraphid edge)
size_t getNumberOfNodes() const
AssociationGraphImplObserver(AssociationGraphImplObserver< N2, E2, GraphImpl > const &graphObserver)
NodesIteratorClass< GraphIterator, is_const > it_
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > allEdgesIterator() const
std::string edgeToString(const Eref edgeObject) const
std::shared_ptr< GraphImpl > subjectGraph_
std::vector< NodeIndex > getAllInnerNodesIndexes() const
std::vector< Nref > getNodesFromGraphid(std::vector< NodeGraphid > nodes) const
void deleteNode(Nref nodeObject)
void deletedNodesUpdate(const std::vector< unsigned int > &nodesToDelete)
void associateNode(Nref nodeObject, NodeGraphid graphNode)
std::shared_ptr< GraphImpl > getGraph()
std::vector< Nref > getNeighbors(const Nref node) const
std::map< Eref, EdgeIndex > EToIndex_
std::vector< Nref > getAllLeaves() const
std::vector< Eref > graphidToE_
size_t getNumberOfLeaves() const
define categories of iterators
AssociationGraphImplObserver< N, E, GraphImpl > * clone() const
AssociationGraphImplObserver(bool directed=false)
EdgeGraphid getEdgeGraphid(const Eref edgeObject) const
AssociationGraphObserver< N, E >::EdgeIndex EdgeIndex
std::map< Nref, NodeGraphid > NToGraphid_
NodeIndex addNodeIndex(const Nref nodeObject)
size_t getNumberOfEdges() const
const std::shared_ptr< GraphImpl > getGraph() const
std::vector< Eref > getEdgesFromGraphid(std::vector< EdgeGraphid > edges) const
void dissociateNode(Nref nodeObject)
AssociationGraphImplObserver< N, E, GraphImpl > & operator=(bpp::AssociationGraphImplObserver< N, E, GraphImpl > const &graphObserver)
void outputToDot(const std::string &fname, const std::string &name) const
std::shared_ptr< N > Nref
Graph::NodeId NodeGraphid
NodeIndex getNodeIndex(const Nref nodeObject) const
std::vector< EdgeIndex > getEdges(NodeIndex node) const
void createNode(Nref nodeObject)
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > incomingNeighborNodesIterator(Nref node) const
virtual bool end() const =0
std::map< Eref, EdgeGraphid > EToGraphid_
void setRoot(const Nref newRoot)
set the root (but no checking, to be used at first construction)
std::vector< Eref > indexToE_
std::vector< NodeIndex > getNodeIndexes(std::vector< Nref > nodes) const
Graph::EdgeId EdgeGraphid
std::vector< Nref > indexToN_
std::vector< EdgeIndex > getOutgoingEdges(NodeIndex node) const
std::shared_ptr< E > Eref
std::vector< NodeIndex > getIncomingNeighbors(NodeIndex node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > outgoingEdgesIterator(Nref node) const
std::map< Nref, NodeIndex > NToIndex_
std::pair< Nref, Nref > getNodes(Eref edge) const
EdgeIndex setEdgeIndex(const Eref edgeObject, EdgeIndex index)
std::vector< NodeIndex > getOutgoingNeighbors(NodeIndex node) const
std::vector< NodeIndex > getNeighbors(NodeIndex node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > allNodesIterator()
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > incomingEdgesIterator(Nref node) const
std::vector< Eref > getAllEdges() const
std::vector< Nref > getIncomingNeighbors(const Nref node) const
std::string nodeToString(const Nref nodeObject) const
std::vector< Eref > getEdges_(const Nref nodeObject, neighborType type) const
bool isLeaf(const NodeIndex nodeid) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > outgoingNeighborNodesIterator(Nref node) const
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
EdgeIndex getEdgeIndex(const Eref edgeObject) const
std::vector< EdgeIndex > getAllEdgesIndexes() const
const Nref getNodeFromGraphid(NodeGraphid node) const
Nref getNode(NodeIndex node) const
const Eref getEdgeFromGraphid(EdgeGraphid edge) const
EdgesIteratorClass< GraphIterator, is_const > it_
void associateEdge(Eref edgeObject, EdgeGraphid graphEdge)
std::vector< Eref > getEdges(const Nref node) const
void unlink(Nref nodeObjectA, Nref nodeObjectB)
const AssociationGraphImplObserver< N, E, GraphImpl > & agio_
AssociationGraphObserver< N, E >::NodeIndex NodeIndex
Eref getEdge(EdgeIndex edge) const
bool hasNodeIndex(const Nref nodeObject) const
return if the object has an index.
Nref getNodeFromGraphid(NodeGraphid node)
bool hasEdgeIndex(const Eref edgeObject) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > outgoingNeighborNodesIterator(Nref node)
std::string toString(T t)
General template method to convert to a string.
bool hasNode(Nref nodeObject) const
AssociationGraphImplObserver(AssociationGraphImplObserver< N, E, GraphImpl > const &graphObserver)
std::vector< Nref > getNeighbors_(const Nref nodeObject, neighborType type) const
EdgeIndex addEdgeIndex(const Eref edgeObject)
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > incomingNeighborNodesIterator(Nref node)
bool hasNode(NodeIndex node) const
std::vector< NodeIndex > getAllNodesIndexes() const
bool hasEdge(EdgeIndex edge) const
Eref getEdgeLinking(Nref nodeA, Nref nodeB) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > incomingEdgesIterator(Nref node)
void dissociateEdge(Eref edgeObject)
void createNode(Nref objectOriginNode, Nref newNodeObject, Eref newEdgeObject=00)
~AssociationGraphImplObserver()
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > outgoingEdgesIterator(Nref node)
void deletedEdgesUpdate(const std::vector< unsigned int > &edgesToDelete)
AssociationGraphImplObserver(std::shared_ptr< GraphImpl > subjectGraph=00)
Constructor.