Tulip  5.3.1
Large graphs analysis and drawing
Graph.h
1 /*
2  *
3  * This file is part of Tulip (http://tulip.labri.fr)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef Tulip_SUPERGRAPH_H
21 #define Tulip_SUPERGRAPH_H
22 
23 #include <iostream>
24 #include <functional>
25 #include <set>
26 #include <string>
27 #include <vector>
28 #include <unordered_map>
29 
30 #include <climits>
31 #include <tulip/tulipconf.h>
32 #include <tulip/DataSet.h>
33 #include <tulip/Node.h>
34 #include <tulip/Edge.h>
35 #include <tulip/Observable.h>
36 
37 namespace tlp {
38 
39 class PropertyInterface;
40 class BooleanProperty;
41 class PluginProgress;
42 template <class C>
43 struct Iterator;
44 
45 /**
46  * @enum This Enum describes the possible types of an element of the graph.
47  *
48  * It is used in functions that can return an edge or a node, to distinguish between the two cases.
49  **/
51  /** This element describes a node **/
52  NODE = 0,
53  /** This element describes an edge **/
54  EDGE = 1
55 };
56 
57 /**
58  * @ingroup Graph
59  * @brief Loads a graph from a file (extension can be any of the Tulip supported input graph file
60  *format).
61  *
62  * This function loads a graph serialized in a file trough the available Tulip import plugins.
63  * Since Tulip 4.8, the selection of the import plugin is based on the provided filename extension.
64  * The import will fail if the selected import plugin is not loaded.
65  * The graph file formats that can currently be imported are : TLP (*.tlp, *.tlp.gz, *.tlpz), TLP
66  *Binary (*.tlpb, *.tlpb.gz, *.tlpbz), TLP JSON (*.json),
67  * Gephi (*.gexf), Pajek (*.net, *.paj), GML (*.gml), Graphviz (*.dot) and UCINET (*.txt)
68  *
69  * Before Tulip 4.8 and as a fallback, the function uses the "TLP Import" import plugin
70  * (always loaded as it is linked into the tulip-core library).
71  *
72  * If the import fails (no such file, parse error, ...) nullptr is returned.
73  *
74  * @param filename the file in one of the supported formats to parse.
75  * @return Graph* the imported Graph, nullptr if the import failed.
76  **/
77 TLP_SCOPE Graph *loadGraph(const std::string &filename, tlp::PluginProgress *progress = nullptr);
78 
79 /**
80  * @ingroup Graph
81  * @brief Saves the corresponding graph to a file (extension can be any of the Tulip supported ouput
82  *graph file format)..
83  *
84  * This function serializes the corresponding graph and all its subgraphs (depending on the format)
85  *to a file
86  * through the available Tulip export plugins.
87  * Since Tulip 4.8, the selection of the export plugin is based on the provided filename extension.
88  * The export will fail if the selected export plugin is not loaded.
89  *
90  * Before Tulip 4.8 and as a fallback, this function uses the "TLP Export" export plugin
91  * (always loaded as it is linked into the tulip-core library).
92  *
93  * @param graph the graph to save.
94  * @param filename the file to save the graph to.
95  * @param progress PluginProgress to report the progress of the operation, as well as final state.
96  *Defaults to nullptr.
97  * @param data Parameters to pass to the export plugin (e.g. additional data, options for the
98  *format)
99  * @return bool whether the export was successfull or not.
100  **/
101 TLP_SCOPE bool saveGraph(Graph *graph, const std::string &filename,
102  tlp::PluginProgress *progress = nullptr, tlp::DataSet *data = nullptr);
103 
104 /**
105  * @ingroup Graph
106  * @brief Exports a graph using the specified export plugin with parameters stored in the DataSet.
107  *
108  * You determine the destination, whether by using a fstream, or by saving the contents of the
109  *stream to the destination of your choice.
110  *
111  * @param graph The graph to export.
112  * @param outputStream The stream to export to. Can be a standard ostream, an ofstream, or even a
113  *gzipped ostream.
114  * @param format The format to use to export the Graph.
115  * @param dataSet Parameters to pass to the export plugin (e.g. additional data, options for the
116  *format)
117  * @param progress A PluginProgress to report the progress of the operation, as well as final state.
118  *Defaults to nullptr.
119  * @return bool Whether the export was successfull or not.
120  **/
121 TLP_SCOPE bool exportGraph(Graph *graph, std::ostream &outputStream, const std::string &format,
122  DataSet &dataSet, PluginProgress *progress = nullptr);
123 
124 /**
125  * @ingroup Graph
126  * @brief Imports a graph using the specified import plugin with the parameters stored in the
127  *DataSet.
128  *
129  * If no graph is passed, then a new graph will be created. You can pass a graph in order to import
130  *data into it.
131  * Returns the graph with imported data, or nullptr if the import failed. In this case, the
132  *Pluginprogress should have an error that can be displayed.
133  *
134  * @param format The format to use to import the graph.
135  * @param dataSet The parameters to pass to the import plugin (file to read, ...)
136  * @param progress A PluginProgress to report the progress of the operation, as well as final state.
137  *Defaults to nullptr.
138  * @param newGraph The graph to import the data into. This can be useful to import data into a
139  *subgraph. Defaults to nullptr.
140  * @return :Graph* The graph containing the imported data, or nullptr in case of failure.
141  **/
142 TLP_SCOPE Graph *importGraph(const std::string &format, DataSet &dataSet,
143  PluginProgress *progress = nullptr, Graph *newGraph = nullptr);
144 
145 /**
146  * @ingroup Graph
147  * @brief Creates a new, empty graph.
148  *
149  * This is a simple method factory to create a Graph implementation (remember, Graph is only an
150  *interface).
151  *
152  * This is the recommended way to create a new Graph.
153  *
154  * @return :Graph* A new, empty graph.
155  **/
156 TLP_SCOPE Graph *newGraph();
157 
158 /**
159  * @ingroup Graph
160  * Appends the selected part of the graph inG (properties, nodes and edges) into the graph outG.
161  * If no selection is done (inSel=nullptr), the whole inG graph is appended.
162  * The output selection is used to select the appended nodes & edges
163  * \warning The input selection is extended to all selected edge ends.
164  */
165 TLP_SCOPE void copyToGraph(Graph *outG, const Graph *inG, BooleanProperty *inSelection = nullptr,
166  BooleanProperty *outSelection = nullptr);
167 
168 /**
169  * @ingroup Graph
170  * Removes the selected part of the graph ioG (properties values, nodes and edges).
171  * If no selection is done (inSel=nullptr), the whole graph is reseted to default value.
172  * \warning The selection is extended to all selected edge ends.
173  */
174 TLP_SCOPE void removeFromGraph(Graph *ioG, BooleanProperty *inSelection = nullptr);
175 
176 /**
177  * @ingroup Graph
178  * Gets an iterator over the root graphs. That is all the currently existing graphs which have been
179  * created using the tlp::newGraph, tlp::loadGraph or tlp::importGraph functions and are the root
180  * graphs of an existing graph hierarchy.
181  * @return An iterator over all the root graphs. The caller of this function is responsible of the
182  * deletion of the returned iterator.
183  */
184 TLP_SCOPE Iterator<Graph *> *getRootGraphs();
185 
186 /**
187  * @ingroup Graph
188  * The class Graph is the interface of a Graph in the Tulip Library.
189  *
190  * There are a few principles to know when working with a Tulip Graph.
191  *
192  * @chapter Directed
193  * Every edge is directed in a Tulip Graph.
194  * You can choose to ignore this, but every edge has a source and destination.
195  *
196  * @chapter Inheritance
197  *
198  * Subgraphs inherit from their parent graph.
199  * This is true of nodes and edges; every node and edge in a subgraph also exists in each of its
200  *parent graphs.
201  * This is also true of properties; every property in a graph exist in all of its subgraphs, except
202  *if it has been replaced
203  * by a local property.
204  *
205  * For instance, if you have the following graph hierarchy:
206  * root
207  * / \
208  * A B
209  *
210  * Every node in A is in root, and every node in B is in root.
211  * Nodes can be in A and root but not B; or in B and root but not A.
212  *
213  * For instance, imagine a graph. You want to compare it to its Delaunay triangulation.
214  * You need to create a subgraph that is a clone of the original (say this is A) to keep the
215  *original graph,
216  * and another copy (say this one is B) on which you will perform the delaunay triangulation.
217  *
218  * B will have none of the original edges, and A will have only the original edges.
219  *
220  * As for properties; let's imagine the same graph hierarchy.
221  * You want to compare two different layouts on the same graph.
222  * You need to create two clone subgraphs, on each you make the 'viewLayout' property local.
223  * This results in A and B having different values for the layout, but everything else in common.
224  * You then can apply two different algorithms on A and B (e.g. Bubble Tree and Tree Radial).
225  *
226  * @chapter Meta Nodes
227  * A meta node is a node representing a subgraph of the current graph.
228  *
229  * @chapter Undo Redo
230  * The Tulip Graph object supports for undo and redo of modifications.
231  *The operations affect the whole graph hierarchy, and cannot be limited to a subgraph.
232  *
233  */
234 class TLP_SCOPE Graph : public Observable {
235 
236  friend class GraphAbstract;
237  friend class GraphUpdatesRecorder;
238  friend class GraphDecorator;
239  friend class PropertyManager;
240  friend class PropertyInterface;
241 
242 public:
243  Graph() : id(0) {}
244  ~Graph() override {}
245 
246  /**
247  * @brief Applies an algorithm plugin, identified by its name.
248  * Algorithm plugins are subclasses of the tlp::Algorithm interface.
249  * Parameters are transmitted to the algorithm trough the DataSet.
250  * To determine a plugin's parameters, you can either:
251  *
252  * * refer to its documentation
253  *
254  * * use buildDefaultDataSet on the plugin object if you have an instance of it
255  *
256  * * call getPluginParameters() with the name of the plugin on the PluginLister
257  *
258  *
259  * If an error occurs, a message describing the error should be stored in errorMessage.
260  *
261  * @param algorithm The algorithm to apply.
262  * @param errorMessage A string that will be modified to contain an error message if an error
263  *occurs.
264  * @param parameters The parameters of the algorithm. Defaults to nullptr.
265  * @param progress A PluginProgress to report the progress of the operation, as well as the final
266  *state. Defaults to nullptr.
267  * @return bool Whether the algorithm applied successfully or not. If not, check the error
268  *message.
269  **/
270  bool applyAlgorithm(const std::string &algorithm, std::string &errorMessage,
271  DataSet *parameters = nullptr, PluginProgress *progress = nullptr);
272 
273  //=========================================================================
274  // Graph hierarchy access and building
275  //=========================================================================
276 
277  /**
278  * @brief Removes all nodes, edges and subgraphs from this graph.
279  *
280  * Contrarily to creating a new Graph, this keeps attributes and properties.
281  *
282  * @return void
283  **/
284  virtual void clear() = 0;
285 
286  /**
287  * @brief Creates and returns a new subgraph of this graph.
288  *
289  * If a BooleanProperty is provided, only nodes and edges for which it is true will be added to
290  *the subgraph.
291  * If none is provided, then the subgraph will be empty.
292  *
293  * @param selection The elements to add to the new subgraph. Defaults to nullptr.
294  * @param name The name of the newly created subgraph. Defaults to "unnamed".
295  * @return :Graph* The newly created subgraph.
296  **/
297  virtual Graph *addSubGraph(BooleanProperty *selection = nullptr,
298  const std::string &name = "unnamed") = 0;
299 
300  /**
301  * @brief Creates and returns a new named subgraph of this graph.
302  *
303  * @param name The name of the newly created subgraph.
304  * @return :Graph* The newly created subgraph.
305  **/
306  Graph *addSubGraph(const std::string &name);
307 
308  /**
309  * @brief Creates and returns a subgraph that contains all the elements of this graph.
310  *
311  * @param name The name of the newly created subgraph. Defaults to "unnamed".
312  * @param addSibling if true the clone subgraph will be a sibling of this graph, if false (the
313  *default) it will be a subgraph of this graph
314  * @param addSiblingProperties if true the local properties will be cloned into the sibling of
315  *this graph, if false (the default) the local properties will not be cloned
316  * @return :Graph* The newly created clone subgraph. nullptr will be returned if addSibling is set
317  *to
318  *true and this graph is a root graph.
319  **/
320  virtual Graph *addCloneSubGraph(const std::string &name = "unnamed", bool addSibling = false,
321  bool addSiblingProperties = false);
322 
323  /**
324  * @brief Creates and returns a new subgraph of the graph induced by a vector of nodes.
325  * @since Tulip 5.0
326  * Every node contained in the given vector is added to the subgraph.
327  * Every edge connecting any two nodes in the set of given nodes is also added.
328  * @param nodes The nodes to add to the subgraph. All the edges between these nodes are added too.
329  * @param parentSubGraph If provided, is used as parent graph for the newly created subgraph
330  * instead of the graph this method is called on.
331  * @param name The name of the newly created subgraph.
332  * @return The newly created subgraph.
333  */
334  Graph *inducedSubGraph(const std::vector<node> &nodes, Graph *parentSubGraph = nullptr,
335  const std::string &name = "unnamed");
336 
337  /**
338  * @brief deprecated, use inducedSubGraph(const std::set<node>&, Graph* = nullptr, const
339  * std::string&
340  * = "unamed") instead
341  */
342  _DEPRECATED Graph *inducedSubGraph(const std::set<node> &nodeSet, Graph *parentSubGraph = nullptr,
343  const std::string &name = "unnamed");
344 
345  /**
346  * @brief Creates and returns a new subgraph of the graph induced by a selection of nodes and
347  * edges.
348  * @since Tulip 4.10
349  * Every node contained in the selection is added to the subgraph.
350  * Every edge and its source and target node contained in the selection is added to the subgraph.
351  * Every edge connecting any two nodes in the resulting set of nodes is also added.
352  * @param selection a selection of nodes and edges.
353  * @param parentSubGraph If provided, is used as parent graph for the newly created subgraph
354  * instead of the graph this method is called on.
355  * @param name The name of the newly created subgraph.
356  * @return The newly created subgraph.
357  */
358  Graph *inducedSubGraph(BooleanProperty *selection, Graph *parentSubGraph = nullptr,
359  const std::string &name = "unnamed");
360 
361  /**
362  * @brief Deletes a subgraph of this graph.
363  * All subgraphs of the removed graph are re-parented to this graph.
364  * For instance, with a graph hierarchy as follows :
365  * root
366  * / \
367  * A B
368  * /|\
369  * C D E
370  *
371  * @code root->delSubGraph(B);
372  * would result in the following hierarchy:
373  * root
374  * / | \\
375  * A C D E
376  *
377  * @param graph The subgraph to delete.
378  *
379  * @see delAllSubGraphs() if you want to remove all descendants of a graph.
380  */
381  virtual void delSubGraph(Graph *graph) = 0;
382 
383  /**
384  * @brief Deletes a subgraph of this graph and all of its subgraphs.
385  ** For instance, with a graph hierarchy as follows :
386  * root
387  * / \
388  * A B
389  * /|\
390  * C D E
391  *
392  * @codeline root->delSubGraph(B); @endcode
393  * would result in the following hierarchy:
394  * root
395  * |
396  * A
397  *
398  * @param graph The subgraph to delete.
399  * @see delSubGraph() if you want to keep the descendants of the subgraph to remove.
400  */
401  virtual void delAllSubGraphs(Graph *graph = nullptr) = 0;
402 
403  /**
404  * @brief Returns the parent of the graph. If called on the root graph, it returns itself.
405  * @return The parent of this graph (or itself if it is the root graph).
406  * @see getRoot() to directly retrieve the root graph.
407  */
408  virtual Graph *getSuperGraph() const = 0;
409 
410  /**
411  * @brief Gets the root graph of the graph hierarchy.
412  * @return The root graph of the graph hierarchy.
413  */
414  virtual Graph *getRoot() const = 0;
415 
416  /**
417  * @cond DOXYGEN_HIDDEN
418  * @brief Sets the parent of a graph.
419  * @warning ONLY USE IF YOU KNOW EXACTLY WHAT YOU ARE DOING.
420  * @endcond
421  */
422  virtual void setSuperGraph(Graph *) = 0;
423 
424  /**
425  * @brief Gets an iterator over all the subgraphs of the graph.
426  * For instance, in the following graph hierarchy:
427  ** root
428  * / \
429  * A B
430  * /|\
431  * C D E
432  *
433  * @codeline root->getSubGraphs(); @endcode
434  * Will return an iterator over A and B, but not C, D and E.
435  * @return An iterator over this graph's direct subgraphs.
436  */
437  virtual Iterator<Graph *> *getSubGraphs() const = 0;
438 
439  /**
440  * @brief Return a const reference on the vector of subgraphs of the graph
441  * It is the fastest way to access to subgraphs, Iterators are 25% slower.
442  * @remark o(1)
443  */
444  virtual const std::vector<Graph *> &subGraphs() const = 0;
445 
446  /**
447  * @brief This method returns the nth subgraph.
448  * Since subgraphs order cannot be ensured in every implementation, this method should be
449  equivalent to:
450  * @code
451  int i=0;
452  Iterator<Graph *> *it = g->getSubGraphs();
453  while (it->hasNext()) {
454  Graph *result = it->next();
455  if (i++ == n) {
456  delete it;
457  return result;
458  }
459  }
460  delete it;
461  return nullptr;
462  * @endcode
463  * @param n the index of the subgraph to retrieve.
464  * @return The n-th subgraph.
465  */
466  virtual Graph *getNthSubGraph(unsigned int n) const;
467 
468  /**
469  * @brief Return the number of direct subgraphs.
470  * For instance, in the following graph hierarchy:
471  * root
472  * / \
473  * A B
474  * /|\
475  * C D E
476  *
477  * @codeline root->numberOfSubGraphs(); @endcode
478  * Will return 2.
479  * @return The number of direct subgraphs.
480  * @see numberOfDescendantGraphs() to count in the whole hierarchy.
481  */
482  virtual unsigned int numberOfSubGraphs() const = 0;
483 
484  /**
485  * @brief Return the number of descendant subgraphs.
486  * For instance, in the following graph hierarchy:
487  * root
488  * / \
489  * A B
490  * /|\
491  * C D E
492  *
493  * @codeline root->numberOfSubGraphs(); @endcode
494  * Will return 5.
495  * @return The number of descendants subgraphs.
496  * @see numberOfSubGraphs() to count only direct subgraphs.
497  */
498  virtual unsigned int numberOfDescendantGraphs() const = 0;
499 
500  /**
501  * @brief Indicates if the graph argument is a direct subgraph.
502  * @param subGraph The graph to check is a subgraph of this graph.
503  * @return Whether subGraph is a direct subgraph of this graph.
504  * @see isDescendantGraph() to search in the whole hierarchy.
505  */
506  virtual bool isSubGraph(const Graph *subGraph) const = 0;
507 
508  /**
509  * @brief Indicates if the graph argument is a descendant of this graph.
510  * @param subGraph The graph to check is a descendant of this graph.
511  * @return Whether subGraph is a descendant of this graph.
512  * @see isSubGraph to search only in direct subgraphs.
513  */
514  virtual bool isDescendantGraph(const Graph *subGraph) const = 0;
515 
516  /**
517  * @brief Returns a pointer on the subgraph with the corresponding id
518  * or nullptr if there is no subgraph with that id.
519  * @param id The id of the subgraph to retrieve.
520  * @return A subgraph of the given id, or null if no such subgraph exists on this graph.
521  * @see getDescendantGraph(unsigned int) to search in the whole hierarchy.
522  */
523  virtual Graph *getSubGraph(unsigned int id) const = 0;
524 
525  /**
526  * @brief Returns a pointer on the subgraph with the corresponding name
527  * or nullptr if there is no subgraph with that name.
528  * @param name The name of the subgraph to retrieve.
529  * @return A Graph named name, or nullptr if no such subgraph exists on this graph.
530  * @see getDescendantGraph(const std::string &) to search in the whole hierarchy.
531  */
532  virtual Graph *getSubGraph(const std::string &name) const = 0;
533 
534  /**
535  * @brief Returns a pointer on the descendant with the corresponding id
536  * or nullptr if there is no descendant with that id.
537  * @param id The id of the descendant graph to retrieve.
538  * @return A graph with the given id, or nullptr if no such graph exists in this graph's
539  * descendants.
540  * @see getSubGraph(unsigned int) to search only in direct subgraphs.
541  */
542  virtual Graph *getDescendantGraph(unsigned int id) const = 0;
543 
544  /**
545  * @brief Returns a pointer on the first descendant graph with the corresponding name
546  * or nullptr if there is no descendant graph with that name.
547  * @param name The name of the descendant graph to look for.
548  * @return A graph named name, or nullptr if there is no such graph in this graph's descendants.
549  * @see getSubGraph(const std::string &) to search only in direct subgraphs.
550  */
551  virtual Graph *getDescendantGraph(const std::string &name) const = 0;
552 
553  /**
554  * @brief Gets an iterator over all the descendant subgraphs of the graph.
555  * For instance, in the following graph hierarchy:
556  ** root
557  * / \
558  * A B
559  * /|\
560  * C D E
561  *
562  * @codeline root->getSubGraphs(); @endcode
563  * Will return an iterator over A B, C, D and E.
564  * @return An iterator over this graph's descendant subgraphs.
565  */
566  Iterator<Graph *> *getDescendantGraphs() const;
567 
568  //==============================================================================
569  // Modification of the graph structure
570  //==============================================================================
571  /**
572  * @brief Adds a new node in the graph and returns it. This node is also added in all
573  * the ancestor graphs.
574  * @return The newly added node.
575  * @see addNodes() if you want to add more than one node.
576  */
577  virtual node addNode() = 0;
578 
579  /**
580  * @brief Adds new nodes in the graph.
581  * The new nodes are also added in all the ancestor graphs.
582  *
583  * @param nbNodes The number of nodes to add.
584  * @see addNode() to add a single node.
585  */
586  virtual void addNodes(unsigned int nbNodes) = 0;
587 
588  /**
589  * @brief Adds new nodes in the graph and returns them in the addedNodes vector.
590  * The new nodes are also added in all the ancestor graphs.
591  *
592  * @param nbNodes The number of nodes to add.
593  * @param addedNodes The newly added nodes. This vector is cleared before being filled.
594  * @see addNode() to add a single node.
595  */
596  virtual void addNodes(unsigned int nbNodes, std::vector<node> &addedNodes) = 0;
597 
598  /**
599  * @brief Adds an existing node in the graph. This node is also added in all the ancestor graphs.
600  * This node must exists in the graph hierarchy (which means it must exist in the root graph).
601  * You cannot add a node to the root graph this way (as it must already be an element of the root
602  * graph).
603  * @warning Using this method on the root graph will display a warning on the console.
604  *
605  * @param n The node to add to a subgraph. This node must exist in the root graph.
606  * @see addNode() to add a new node to a graph.
607  */
608  virtual void addNode(const node n) = 0;
609 
610  /**
611  * @brief Adds existing nodes in the graph. The nodes are also added in all the ancestor graphs.
612  * as with addNode(const tlp::node), the nodes must exist in the graph hierarchy and thus exist in
613  the root graph,
614  * and node cannot be added this way to the root graph.
615 
616  * @warning Using this method on the root graph will display a warning on the console.
617  * @warning The graph does not take ownership of the Iterator.
618  *
619  * @param nodes An iterator over nodes to add to this subgraph. The graph does not takes ownership
620  of this iterator.
621  */
622  virtual void addNodes(Iterator<node> *nodes) = 0;
623 
624  /**
625  * @brief Adds existing nodes in the graph. The nodes are also added in all the ancestor graphs.
626  * as with addNode(const tlp::node), the nodes must exist in the graph hierarchy and thus exist in
627  the root graph,
628  * and nodes cannot be added this way to the root graph.
629 
630  * @warning Using this method on the root graph will display a warning on the console.
631  *
632  * @param nodes a vector of nodes to add to this subgraph.
633  */
634  void addNodes(const std::vector<node> &nodes);
635 
636  /**
637  * @brief Deletes a node in the graph.
638  * This node is also removed in the subgraphs hierarchy of the current graph.
639  * @param n The node to delete.
640  * @param deleteInAllGraphs Whether to delete in all its parent graphs or only in this graph. By
641  * default only removes in the current graph.
642  * @see delNodes() to remove multiple nodes.
643  */
644  virtual void delNode(const node n, bool deleteInAllGraphs = false) = 0;
645 
646  /**
647  * @brief Deletes nodes in the graph.
648  * These nodes are also removed in the subgraphs hierarchy of the current graph.
649  * @warning the graph does not take ownership of the Iterator.
650  * @param it The nodes to delete.
651  * @param deleteInAllGraphs Whether to delete in all its parent graphs or only in this graph. By
652  * default only removes in the current graph.
653  * @see delNode() to remove a single node.
654  */
655  virtual void delNodes(Iterator<node> *it, bool deleteInAllGraphs = false) = 0;
656 
657  /**
658  * @brief Deletes nodes in the graph.
659  * These nodes are also removed in the subgraphs hierarchy of the current graph.
660  * @warning the graph does not take ownership of the Iterator.
661  * @param nodes a vector of the nodes to delete.
662  * @param deleteInAllGraphs Whether to delete in all its parent graphs or only in this graph. By
663  * default only removes in the current graph.
664  * @see delNode() to remove a single node.
665  */
666  void delNodes(const std::vector<node> &nodes, bool deleteInAllGraphs = false);
667 
668  /**
669  * @brief Adds a new edge in the graph
670  * This edge is also added in all the super-graph of the graph.
671  * @param source The source of the edge.
672  * @param target The target of the edge.
673  * @return The newly added edge.
674  * @see addEdges() to add multiple edges at once.
675  */
676  virtual edge addEdge(const node source, const node target) = 0;
677 
678  /**
679  * @brief Adds new edges in the graph.
680  * The new edges are also added in all graph ancestors.
681  *
682  * @warning If the edges vector contains a node that does not belong to this graph,
683  * undefined behavior will ensue.
684  * @param edges A vector describing between which nodes to add edges.
685  * The first element of the pair is the source, the second is the destination.
686  *
687  */
688  virtual void addEdges(const std::vector<std::pair<node, node>> &edges) = 0;
689 
690  /**
691  * @brief Adds new edges in the graph and returns them in the addedEdges vector.
692  * The new edges are also added in all graph ancestors.
693  *
694  * @warning If the edges vector contains a node that does not belong to this graph,
695  * undefined behavior will ensue.
696  * @param edges A vector describing between which nodes to add edges.
697  * The first element of the pair is the source, the second is the destination.
698  * @param addedEdges The newly added edges. This vector is cleared before being filled.
699  *
700  */
701  virtual void addEdges(const std::vector<std::pair<node, node>> &edges,
702  std::vector<edge> &addedEdges) = 0;
703 
704  /**
705  * @brief Adds an existing edge in the graph. This edge is also added in all
706  * the ancestor graphs.
707  * The edge must be an element of the graph hierarchy, thus it must be
708  * an element of the root graph.
709  * @warning Using this method on the root graph will display a warning on the console.
710  * @param e The edge to add to this subgraph.
711  * @see addEgdes() to add more than one edge at once.
712  * @see addNode() to add nodes.
713  */
714  virtual void addEdge(const edge e) = 0;
715 
716  /**
717  * @brief Adds existing edges in the graph. The edges are also added in all
718  * the ancestor graphs.
719  * The added edges must be elements of the graph hierarchy,
720  * thus they must be elements of the root graph.
721  * @warning Using this method on the root graph will display a warning on the console.
722  * @warning The graph does not take ownership of the iterator.
723  * @param edges The edges to add on this subgraph.
724  */
725  virtual void addEdges(Iterator<edge> *edges) = 0;
726 
727  /**
728  * @brief Adds existing edges in the graph. The edges are also added in all
729  * the ancestor graphs.
730  * The added edges must be elements of the graph hierarchy,
731  * thus they must be elements of the root graph.
732  * @warning Using this method on the root graph will display a warning on the console.
733  * @param edges a vector of the edges to add on this subgraph.
734  */
735  void addEdges(const std::vector<edge> &edges);
736 
737  /**
738  * @brief Deletes an edge in the graph. The edge is also removed in
739  * the subgraphs hierarchy.
740  * The ordering of remaining edges is preserved.
741  * @param e The edge to delete.
742  * @param deleteInAllGraphs Whether to delete in all its parent graphs or only in this graph. By
743  * default only removes in the current graph.
744  */
745  virtual void delEdge(const edge e, bool deleteInAllGraphs = false) = 0;
746 
747  /**
748  * @brief Deletes edges in the graph. These edges are also removed in the subgraphs hierarchy.
749  * The ordering of remaining edges is preserved.
750  * @warning The graph does not take ownership of the Iterator.
751  * @param itE
752  * @param deleteInAllGraphs Whether to delete in all its parent graphs or only in this graph. By
753  * default only removes in the current graph.
754  */
755  virtual void delEdges(Iterator<edge> *itE, bool deleteInAllGraphs = false) = 0;
756 
757  /**
758  * @brief Deletes edges in the graph. These edges are also removed in the subgraphs hierarchy.
759  * The ordering of remaining edges is preserved.
760  * @warning The graph does not take ownership of the Iterator.
761  * @param edges a vector of the edges to delete
762  * @param deleteInAllGraphs Whether to delete in all its parent graphs or only in this graph. By
763  * default only removes in the current graph.
764  */
765  void delEdges(const std::vector<edge> &edges, bool deleteInAllGraphs = false);
766 
767  /**
768  * @brief Sets the order of the edges around a node.
769  * This operation ensures that adjacent edges of a node will
770  * be ordered as they are in the vector of edges given in parameter.
771  *
772  * This can be useful if you want to make sure you retrieve the edges in a specific order when
773  * iterating upon them.
774  * @param n The node whose edges to order.
775  * @param edges The edges, in the order you want them.
776  */
777  virtual void setEdgeOrder(const node n, const std::vector<edge> &edges) = 0;
778 
779  /**
780  * @brief Swaps two edges in the adjacency list of a node.
781  * @param n The node on whoch to swap the edges order.
782  * @param e1 The first edge, that will take the second edge's position.
783  * @param e2 The second edge, that will take the first edge's position.
784  */
785  virtual void swapEdgeOrder(const node n, const edge e1, const edge e2) = 0;
786 
787  /**
788  * @brief Sets the source of an edge to be the given node.
789  * @param e The edge to change the source of.
790  * @param source The new source of the edge.
791  */
792  virtual void setSource(const edge e, const node source) = 0;
793 
794  /**
795  * @brief Sets the target of an edge to be the given node.
796  * @param e The edge to change the target of.
797  * @param target The new target of the edge.
798  */
799  virtual void setTarget(const edge e, const node target) = 0;
800 
801  /**
802  * @brief Sets both the source and the target of an edge.
803  * @param e The edge to set the source and target of.
804  * @param source The new source of the edge.
805  * @param target The new target of the edge.
806  */
807  virtual void setEnds(const edge e, const node source, const node target) = 0;
808 
809  /**
810  * @brief Reverses the direction of an edge, the source becomes the target and the target
811  * becomes the source.
812  * @warning The ordering is global to the entire graph hierarchy. Thus, by changing
813  * the ordering of a graph you change the ordering of the hierarchy.
814  * @param e The edge top reverse.
815  */
816  virtual void reverse(const edge e) = 0;
817  // Attempts to reserve enough space to store nodes.
818  // Only defined on root graph.
819  virtual void reserveNodes(unsigned int nbNodes) = 0;
820  // Attempts to reserve enough space to store edges.
821  // Only defined on root graph.
822  virtual void reserveEdges(unsigned int nbEdges) = 0;
823  //================================================================================
824  // Iterators on the graph structure.
825  //================================================================================
826  /**
827  * @brief Finds the first node whose input degree equals 0.
828  *
829  * @return tlp::node The first encountered node with input degree of 0, or an invalid node if none
830  *was found.
831  **/
832  virtual tlp::node getSource() const;
833 
834  /**
835  * @brief Finds the first node whose output degree equals 0.
836  *
837  * @return tlp::node The first encountered node with output degree of 0, or an invalid node if
838  *none was found.
839  **/
840  virtual tlp::node getSink() const;
841 
842  /**
843  * @brief Returns the first node in the graph.
844  *
845  */
846  virtual node getOneNode() const = 0;
847 
848  /**
849  * @brief Returns a random node in the graph.
850  *
851  * @since Tulip 4.8
852  *
853  */
854  virtual node getRandomNode() const = 0;
855 
856  /**
857  * @brief Return a const reference on the vector of nodes of the graph
858  * It is the fastest way to access to nodes, Iterators are 25% slower.
859  * @remark o(1)
860  */
861  virtual const std::vector<node> &nodes() const = 0;
862 
863  /**
864  * @brief Return the position of a node in the vector of nodes of the graph
865  * @param n The node for which the position is requested
866  */
867  virtual unsigned int nodePos(const node n) const = 0;
868 
869  /**
870  * @brief Gets an iterator over this graph's nodes.
871  * @return An iterator over all the nodes of this graph.
872  * @see getInNodes()
873  * @see getOutNodes()
874  * @see getInOutNodes()
875  * @see getEdges()
876  */
877  virtual Iterator<node> *getNodes() const = 0;
878 
879  /**
880  * @brief Gets the i-th node in the input nodes of a given node.
881  * An input node 'in' of a node 'N' is the source of an edge going from
882  * 'in' to 'N'. e.g.
883  * @code
884  * node in = graph->addNode();
885  * node N = graph->addNode();
886  * graph->addEdge(in, N);
887  * //in == graph->getInNode(N, 1);
888  * @endcode
889  *
890  * If you have 5 input nodes on a node N, then
891  * @codeline graph->getInNode(2); @endcode
892  * will return the second of those nodes.
893  * It will ignore the output nodes of this node.
894  * @param n The node to get an input node of.
895  * @param i The index of the input node to get.
896  * @return The i-th input node of the given node.
897  * @see getInNodes()
898  * @see getInEdges()
899  */
900  virtual node getInNode(const node n, unsigned int i) const = 0;
901 
902  /**
903  * @brief Gets an iterator over the input nodes of a node.
904  * @param n The node to get the input nodes of.
905  * @return An iterator over the input nodes of a node.
906  * @see getInNode()
907  * @see getInOutNodes()
908  * @see getInEdges()
909  */
910  virtual Iterator<node> *getInNodes(const node n) const = 0;
911 
912  /**
913  * @brief Gets the i-th node in the output nodes of a given node.
914  * An output node 'out' of a node 'N' is the target of an edge going from
915  * 'N' to 'out'. e.g.
916  * @code
917  * node N = graph->addNode();
918  * node out = graph->addNode();
919  * graph->addEdge(N, out);
920  * //out == graph->getOutNode(N, 1);
921  * @endcode
922  *
923  * If you have 5 output nodes on a node N, then
924  * @codeline graph->getOutNode(2); @endcode
925  * will return the second of those nodes.
926  * It will ignore the input nodes of this node.
927  * @param n The node to get an output node of.
928  * @param i The index of the output node to get.
929  * @return The i-th output node of the given node.
930  * @see getOutNodes()
931  * @see getOutEdges()
932  */
933  virtual node getOutNode(const node n, unsigned int i) const = 0;
934 
935  /**
936  * @brief Gets an iterator over the output nodes of a node.
937  * @param n The node to get the output nodes of.
938  * @return An iterator over the output nodes of a node.
939  * @see getOutNode()
940  * @see getInOutNodes()
941  * @see getOutEdges()
942  */
943  virtual Iterator<node> *getOutNodes(const node n) const = 0;
944 
945  /**
946  * @brief Gets an iterator over the neighbors of a given node.
947  * @param n The node to retrieve the neighbors of.
948  * @return An iterator over the node's neighbors.
949  */
950  virtual Iterator<node> *getInOutNodes(const node n) const = 0;
951 
952  /**
953  * @brief Gets an iterator performing a breadth-first search on the graph.
954  * @param root The node from whom to start the BFS. If not provided, the root
955  * node will be assigned to a source node in the graph (node with input degree equals to 0).
956  * If there is no source node in the graph, a random node will be picked.
957  * @return A stable iterator over the graph nodes in the BFS order.
958  */
959  virtual Iterator<node> *bfs(const node root = node()) const = 0;
960 
961  /**
962  * @brief Gets an iterator performing a depth-first search on the graph.
963  * @param root The node from whom to start the DFS. If not provided, the root
964  * node will be assigned to a source node in the graph (node with input degree equals to 0).
965  * If there is no source node in the graph, a random node will be picked.
966  * @return A stable iterator over the graph nodes in the DFS order.
967  */
968  virtual Iterator<node> *dfs(const node root = node()) const = 0;
969 
970  /**
971  * @brief Gets the underlying graph of a meta node.
972  * @param metaNode The metanode.
973  * @return The Graph pointed to by the metanode.
974  * @see getEdgeMetaInfo()
975  */
976  virtual Graph *getNodeMetaInfo(const node metaNode) const = 0;
977 
978  /**
979  * @brief Return a const reference on the vector of edges of the graph
980  * It is the fastest way to access to edges, Iterators are 25% slower.
981  * @remark o(1)
982  */
983  virtual const std::vector<edge> &edges() const = 0;
984 
985  /**
986  * @brief Return the position of an edge in the vector of edges of the graph
987  * @param e The edge for which the position is requested
988  */
989  virtual unsigned int edgePos(const edge e) const = 0;
990 
991  /**
992  * @brief Get an iterator over all the graph's edges.
993  * @return An iterator over all the graph's edges.
994  * @see getInEdges()
995  * @see getOutEdges()
996  * @see getInOutEdges()
997  */
998  virtual Iterator<edge> *getEdges() const = 0;
999 
1000  /**
1001  * @brief Returns the first edge in the graph.
1002  *
1003  */
1004  virtual edge getOneEdge() const = 0;
1005 
1006  /**
1007  * @brief Returns a random edge in the graph.
1008  *
1009  * @since Tulip 4.8
1010  *
1011  */
1012  virtual edge getRandomEdge() const = 0;
1013 
1014  /**
1015  * @brief Gets an iterator over the output edges of a node.
1016  * @param n The node to get the output edges from.
1017  * @return An iterator over the node's output edges.
1018  * @see getEdges()
1019  * @see getOutEdges()
1020  * @see getInOutEdges()
1021  */
1022  virtual Iterator<edge> *getOutEdges(const node n) const = 0;
1023 
1024  /**
1025  * @brief Gets an iterator over the edges of a node.
1026  * @param n The node to get the edges from.
1027  * @return An iterator over the node's edges.
1028  * @see getEdges()
1029  * @see getOutEdges()
1030  * @see getInEdges()
1031  */
1032  virtual Iterator<edge> *getInOutEdges(const node n) const = 0;
1033 
1034  /**
1035  * @brief Gets an iterator over the input edges of a node.
1036  * @param n The node to get the input edges from.
1037  * @return An iterator over the node's input edges.
1038  * @see getEdges()
1039  * @see getOutEdges()
1040  * @see getInOutEdges()
1041  */
1042  virtual Iterator<edge> *getInEdges(const node n) const = 0;
1043 
1044  /**
1045  * @brief Gets all input/output edges of a node existing in the root graph
1046  * @warning If the current graph is not the root, the existence of the edge
1047  * can be tested with isElement(edge) function.
1048  * @param n The node to get the input/ouput edges from.
1049  * @return a const reference to the vector of all edges of a node
1050  */
1051  virtual const std::vector<edge> &allEdges(const node n) const = 0;
1052 
1053  /**
1054  * @brief Gets an iterator over the edges composing a meta edge.
1055  * @param metaEdge The metaEdge to get the real edges of.
1056  * @return An Iterator over the edges composing the metaEdge.
1057  * @see getNodeMetaInfo()
1058  */
1059  virtual Iterator<edge> *getEdgeMetaInfo(const edge metaEdge) const = 0;
1060 
1061  /**
1062  * @brief sort the graph elements in ascending order
1063  * @warning: That operation modify the vector of nodes and the vector of edges
1064  * and thus devalidate all iterators.
1065  */
1066  virtual void sortElts() = 0;
1067 
1068  //================================================================================
1069  // Graph, nodes and edges information about the graph stucture
1070  //================================================================================
1071  /**
1072  * @brief Gets the unique identifier of the graph.
1073  * @return The unique identifier of this graph.
1074  */
1075  unsigned int getId() const {
1076  return id;
1077  }
1078 
1079  /**
1080  * @brief return whether the graph is empty or not.
1081  * @return true if the graph has no nodes, false if not.
1082  */
1083  virtual inline bool isEmpty() const {
1084  return nodes().empty();
1085  }
1086 
1087  /**
1088  * @brief Gets the number of nodes in this graph.
1089  * @return The number of nodes in this graph.
1090  * @see numberOfEdges()
1091  */
1092  virtual unsigned int numberOfNodes() const = 0;
1093 
1094  /**
1095  * @brief Gets the number of edges in this graph.
1096  * @return The number of edges in this graph.
1097  * @see numberOfNodes()
1098  */
1099  virtual unsigned int numberOfEdges() const = 0;
1100 
1101  /**
1102  * @param n The node to get the degree of.
1103  * @return The degree of the given node.
1104  */
1105  virtual unsigned int deg(const node n) const = 0;
1106 
1107  /**
1108  * @brief Get the input degree of a node.
1109  * @param n The node to get the input degree of.
1110  * @return The input degree of the given node.
1111  */
1112  virtual unsigned int indeg(const node n) const = 0;
1113 
1114  /**
1115  * @brief Get the output degree of a node.
1116  * @param n The node to get the output degree of.
1117  * @return The output degree of the given node.
1118  */
1119  virtual unsigned int outdeg(const node n) const = 0;
1120 
1121  /**
1122  * @brief Gets the source of an edge.
1123  * @param e The edge to get the source of.
1124  * @return The source of the given edge.
1125  */
1126  virtual node source(const edge e) const = 0;
1127 
1128  /**
1129  * @brief Gets the target of an edge.
1130  * @param e The edge to get the target of.
1131  * @return The target of the given edge.
1132  */
1133  virtual node target(const edge e) const = 0;
1134 
1135  /**
1136  * @brief Gets the source and the target of an edge.
1137  * @param e The edge to get the ends of.
1138  * @return A pair whose first element is the source, and second is the target.
1139  */
1140  virtual const std::pair<node, node> &ends(const edge e) const = 0;
1141 
1142  /**
1143  * @brief Gets the opposite node of n through e.
1144  * @param e The edge linking the two nodes.
1145  * @param n The node at one end of e.
1146  * @return The node at the other end of e.
1147  */
1148  virtual node opposite(const edge e, const node n) const = 0;
1149 
1150  /**
1151  * @brief Checks if an element belongs to this graph.
1152  * @param n The node to check if it is an element of the graph.
1153  * @return Whether or not the element belongs to the graph.
1154  */
1155  virtual bool isElement(const node n) const = 0;
1156 
1157  /**
1158  * @brief Checks if a node is a meta node.
1159  * @param n The node to check if it is a meta node.
1160  * @return Whether or not the node is a meta node.
1161  */
1162  virtual bool isMetaNode(const node n) const = 0;
1163 
1164  /**
1165  * @brief Checks if an element belongs to this graph.
1166  * @param e The edge to check if it is an element of the graph.
1167  * @return Whether or not the element belongs to the graph.
1168  */
1169  virtual bool isElement(const edge e) const = 0;
1170 
1171  /**
1172  * @brief Checks if an edge is a meta edge.
1173  * @param e The edge to check if it is a meta edge.
1174  * @return Whether or not the edge is a meta edge.
1175  */
1176  virtual bool isMetaEdge(const edge e) const = 0;
1177 
1178  /**
1179  * @brief Checks if an edge exists between two given nodes.
1180  * @param source The source of the hypothetical edge.
1181  * @param target The target of the hypothetical edge.
1182  * @param directed When set to false edges from target to source are also considered
1183  * @return true if such an edge exists
1184  */
1185  virtual bool hasEdge(const node source, const node target, bool directed = true) const {
1186  return existEdge(source, target, directed).isValid();
1187  }
1188 
1189  /**
1190  * @brief Returns all the edges between two nodes.
1191  * @param source The source of the hypothetical edges.
1192  * @param target The target of the hypothetical edges.
1193  * @param directed When set to false edges from target to source are also considered
1194  * @return a vector of existing edges
1195  */
1196  virtual std::vector<edge> getEdges(const node source, const node target,
1197  bool directed = true) const = 0;
1198 
1199  /**
1200  * @brief Returns the first edge found between the two given nodes.
1201  * @warning This function always returns an edge,
1202  * you need to check if this edge is valid with edge::isValid().
1203  * @param source The source of the hypothetical edge.
1204  * @param target The target of the hypothetical edge.
1205  * @param directed When set to false
1206  * an edge from target to source may also be returned
1207  * @return An edge that is only valid if it exists.
1208  */
1209  virtual edge existEdge(const node source, const node target, bool directed = true) const = 0;
1210 
1211  //================================================================================
1212  // Access to the graph attributes and to the node/edge property.
1213  //================================================================================
1214  /**
1215  * @brief Sets the name of the graph.
1216  * The name does not have to be unique, it is used for convenience.
1217  * @param name The new name of the graph.
1218  */
1219  virtual void setName(const std::string &name) = 0;
1220 
1221  /**
1222  * @brief Retrieves the name of the graph.
1223  * @return The name of the graph.
1224  */
1225  virtual std::string getName() const = 0;
1226 
1227  /**
1228  * @brief Gets the attributes of the graph.
1229  *
1230  * The attributes contains the name and any user-defined value.
1231  * @return The attributes of the graph.
1232  */
1233  const DataSet &getAttributes() const {
1234  return const_cast<Graph *>(this)->getNonConstAttributes();
1235  }
1236 
1237  /**
1238  * @brief Gets an attribute on the graph.
1239  * @param name The name of the attribute to set.
1240  * @param value The value to set.
1241  * @return Whether the setting of the attribute was sucessful.
1242  */
1243  template <typename ATTRIBUTETYPE>
1244  bool getAttribute(const std::string &name, ATTRIBUTETYPE &value) const;
1245 
1246  /**
1247  * @brief Gets a copy of the attribute.
1248  * @param name The name of the attribute to retrieve.
1249  * @return A copy of the attribute to retrieve.
1250  */
1251  DataType *getAttribute(const std::string &name) const;
1252 
1253  /**
1254  * @brief Sets an attribute on the graph.
1255  * @param name The name of the attribute to set.
1256  * @param value The value to set on this attribute.
1257  */
1258  template <typename ATTRIBUTETYPE>
1259  void setAttribute(const std::string &name, const ATTRIBUTETYPE &value);
1260 
1261  /**
1262  * @brief Sets an attribute on the graph.
1263  * @param name The name of the attribute to set.
1264  * @param value The value to set.
1265  */
1266  void setAttribute(const std::string &name, const DataType *value);
1267 
1268  /**
1269  * @brief Removes an attribute on the graph.
1270  * @param name The name of the attribute to remove.
1271  */
1272  void removeAttribute(const std::string &name) {
1273  notifyRemoveAttribute(name);
1274  getNonConstAttributes().remove(name);
1275  }
1276 
1277  /**
1278  * @brief Checks if an attribute exists.
1279  * @param name The name of the attribute to check for.
1280  * @return Whether the attribute exists.
1281  */
1282  bool existAttribute(const std::string &name) const {
1283  return getAttributes().exists(name);
1284  }
1285 
1286  /**
1287  * @brief deprecated, use existAttribute instead.
1288  */
1289  _DEPRECATED bool attributeExist(const std::string &name) const {
1290  return existAttribute(name);
1291  }
1292 
1293  /**
1294  * @brief Adds a property to the graph.
1295  * The graph takes ownership of the property. If you want to delete it, use
1296  * Graph::delLocalProperty().
1297  * @param name The unique identifier of the property.
1298  * @param prop The property to add.
1299  */
1300  virtual void addLocalProperty(const std::string &name, PropertyInterface *prop) = 0;
1301 
1302  /**
1303  * @brief Gets an existing property.
1304  * In DEBUG mode an assertion checks the existence of the property.
1305  *
1306  * The graph keeps ownership of the property, if you wish to remove it from the graph use
1307  * Graph::delLocalProperty().
1308  *
1309  * @param name The unique identifier of the property.
1310  * @return An existing property, or nullptr if no property with the given name exists.
1311  */
1312  virtual PropertyInterface *getProperty(const std::string &name) const = 0;
1313 
1314  /**
1315  * @brief Gets a property on this graph.
1316  * The name of a property identifies it uniquely.
1317  * Either there already exists a property with the given name, in which case it is returned.
1318  * Either no such property exists and it is created.
1319  *
1320  * The graph keeps ownership of the property, if you wish to remove it from the graph use
1321  * Graph::delLocalProperty().
1322  * @warning using the wrong template parameter will cause a segmentation fault.
1323  * @param The unique identifier of the property.
1324  * @return The property of given name.
1325  */
1326  template <typename PropertyType>
1327  PropertyType *getLocalProperty(const std::string &name);
1328 
1329  /**
1330  * @brief Gets a property on this graph or one of its ancestors.
1331  * If the property already exists on the graph or in one of its ancestors, it is returned.
1332  * Otherwise a new property is created on this graph.
1333  *
1334  * The graph keeps ownership of the property, if you wish to remove it from the graph use
1335  * Graph::delLocalProperty().
1336  *
1337  * @warning using the wrong propertyType will result in a segmentation fault. Using an invalid
1338  * property type will always return nullptr.
1339  * @param name The unique identifier of the property.
1340  * @return An existing property, or a new one if none exists with the given name.
1341  */
1342  template <typename PropertyType>
1343  PropertyType *getProperty(const std::string &name);
1344 
1345  /**
1346  * @brief Gets a property on this graph, and this graph only.
1347  * This forwards the call to the template version of getLocalProperty(), with the correct template
1348  * parameter deduced from the propertyType parameter.
1349  *
1350  * The graph keeps ownership of the property, if you wish to remove it from the graph use
1351  * Graph::delLocalProperty().
1352  *
1353  * @warning using the wrong propertyType will result in a segmentation fault. Using an invalid
1354  * property type will always return nullptr.
1355  * @param propertyName The unique identifier of the property.
1356  * @param propertyType A string describing the type of the property.
1357  * @return The property of given name.
1358  * @see getLocalProperty().
1359  */
1360  PropertyInterface *getLocalProperty(const std::string &propertyName,
1361  const std::string &propertyType);
1362 
1363  /**
1364  * @brief Gets a property on this graph or one of its ancestors.
1365  * This forwards the call to the template version of getProperty(), with the correct template
1366  * parameter deduced from the propertyType parameter.
1367  *
1368  * The graph keeps ownership of the property, if you wish to remove it from the graph use
1369  * Graph::delLocalProperty().
1370  *
1371  * @warning using the wrong propertyType will result in a segmentation fault. Using an invalid
1372  * property type will always return nullptr.
1373  * @param propertyName The unique identifier of the property.
1374  * @param propertyType A string describing the type of the property.
1375  * @return The property of given name.
1376  * @see getProperty().
1377  */
1378  PropertyInterface *getProperty(const std::string &propertyName, const std::string &propertyType);
1379 
1380  /**
1381  * @brief Checks if a property exists in this graph or one of its ancestors.
1382  * @param The unique identifier of the property.
1383  * @return Whether a property with the given name exists.
1384  */
1385  virtual bool existProperty(const std::string &name) const = 0;
1386 
1387  /**
1388  * @brief Checks if a property exists in this graph.
1389  * @param The unique identifier of the property.
1390  * @return Whether a property with the given name exists.
1391  */
1392  virtual bool existLocalProperty(const std::string &name) const = 0;
1393 
1394  /**
1395  * @brief Removes and deletes a property from this graph.
1396  * The property is removed from the graph's property pool, meaning its name can now be used by
1397  * another property.
1398  * The object is deleted and the memory freed.
1399  * @param name The unique identifier of the property.
1400  */
1401  virtual void delLocalProperty(const std::string &name) = 0;
1402 
1403  /**
1404  * @brief Gets an iterator over the names of the local properties of this graph.
1405  * @return An iterator over this graph's properties names.
1406  */
1407  virtual Iterator<std::string> *getLocalProperties() const = 0;
1408 
1409  /**
1410  * @brief Gets an iterator over the local properties of this graph.
1411  * @return An iterator over this graph's properties.
1412  */
1413  virtual Iterator<PropertyInterface *> *getLocalObjectProperties() const = 0;
1414 
1415  /**
1416  * @brief Gets an iterator over the names of the properties inherited from this graph's ancestors,
1417  * excluding this graph's local properties.
1418  * @return An iterator over the names of the properties this graph inherited.
1419  */
1420  virtual Iterator<std::string> *getInheritedProperties() const = 0;
1421 
1422  /**
1423  * @brief Gets an iterator over the properties inherited from this graph's ancestors,
1424  * excluding this graph's local properties.
1425  * @return An iterator over the properties this graph inherited.
1426  */
1427  virtual Iterator<PropertyInterface *> *getInheritedObjectProperties() const = 0;
1428 
1429  /**
1430  * @brief Gets an iterator over the names of all the properties attached to this graph,
1431  * whether they are local or inherited.
1432  * @return An iterator over the names of all the properties attached to this graph.
1433  */
1434  virtual Iterator<std::string> *getProperties() const = 0;
1435 
1436  /**
1437  * @brief Gets an iterator over the properties attached to this graph,
1438  * whether they are local or inherited.
1439  * @return An iterator over all of the properties attached to this graph.
1440  */
1441  virtual Iterator<PropertyInterface *> *getObjectProperties() const = 0;
1442 
1443  /**
1444  * @brief Runs a plugin on the graph, whose result is a property.
1445  *
1446  * @param algorithm The name of the plugin to run.
1447  * @param result The property in which to store the computed nodes/edges associated values. All
1448  * previous values will be erased.
1449  * @param errorMessage Stores the error message if the plugin fails.
1450  * @param parameters The parameters of the algorithm. Some algorithms use this DataSet to output
1451  * @param progress A PluginProgress to report the progress of the operation, as well as the final
1452  * state. Defaults to nullptr.
1453  * some additional information.
1454  * @return Whether the plugin applied successfully or not. If not, check the error message.
1455  *
1456  * @see PluginLister::getPluginParameters() to retrieve the list of default parameters for the
1457  * plugin.
1458  */
1459  bool applyPropertyAlgorithm(const std::string &algorithm, PropertyInterface *result,
1460  std::string &errorMessage, DataSet *parameters = nullptr,
1461  PluginProgress *progress = nullptr);
1462 
1463  /**
1464  * @brief Deprecated, use applyPropertyAlgorithm(const std::string &algorithm, PropertyInterface
1465  * *result, std::string &errorMessage, DataSet *parameters = nullptr, PluginProgress *progress =
1466  * nullptr) instead
1467  */
1468  _DEPRECATED bool applyPropertyAlgorithm(const std::string &algorithm, PropertyInterface *result,
1469  std::string &errorMessage, PluginProgress *progress,
1470  DataSet *parameters = nullptr) {
1471  return applyPropertyAlgorithm(algorithm, result, errorMessage, parameters, progress);
1472  }
1473 
1474  // updates management
1475  /**
1476  * @brief Saves the current state of the whole graph hierarchy and allows to revert to this state
1477  * later on, using pop().
1478  * All modifications except those altering the ordering of the edges will be undone.
1479  *
1480  * This allows to undo/redo modifications on a graph.
1481  * This is mostly useful from a user interface point of view, but some algorithms use this
1482  * mechanism to clean up before finishing.
1483  * For instance:
1484  * @code
1485  * Graph* graph = tlp::newGraph();
1486  * DoubleProperty* prop = graph->getProperty<DoubleProperty>("metric");
1487  * string errorMessage;
1488  *
1489  * //our super metric stuff we want to kee
1490  * DoubleProperty* superProperty = graph->getProperty<DoubleProperty>("superStuff");
1491  * vector<PropertyInterface*> propertiesToKeep;
1492  * propertiesToKeep.push_back(superProperty);
1493  *
1494  *
1495  * //apply some metric
1496  * graph->applyPropertyAlgorithm("Degree", prop, errorMessage);
1497  *
1498  * // save this state to be able to revert to it later
1499  * //however we do not want to allow to unpop(), which would go forward again to the state where
1500  * prop contains 'Depth'.
1501  * //this saves some memory.
1502  * //Also we always want to keep the value of our super property, so we pass it in the collection
1503  * of properties to leave unaffected by the pop().
1504  * graph->push(false, propertiesToKeep);
1505  *
1506  * //compute the quality of this metric, or whatever makes sense
1507  * int degreeQuality = prop->getMax();
1508  *
1509  * //compute another metric
1510  * graph->applyPropertyAlgorithm("Depth", prop, errorMessage);
1511  *
1512  * //compute our secret metric, that depends on depth
1513  * graph->applyPropertyAlgorithm("MySuperSecretAlgorithm", superProperty, errorMessage);
1514  *
1515  * //compute its quality
1516  * int depthQuality = prop->getMax();
1517  *
1518  * //if the degree was better, revert back to the state where its contents were in prop.
1519  * if(degreeQuality > depthQuality) {
1520  * //this does not affect superProperty, as we told the system not to consider it when
1521  * recording modifications to potentially revert.
1522  * graph->pop();
1523  * }
1524  *
1525  * //do some stuff using our high quality metric
1526  * ColorProperty* color = graph->getProperty("viewColor");
1527  * graph->applyPropertyAlgorithm("Color Mapping", color, errorMessage);
1528  *
1529  * @endcode
1530  *
1531  * @param unpopAllowed Whether or not to allow to re-do the modifications once they are undone.
1532  * @param propertiesToPreserveOnPop A collection of properties whose state to preserve when using
1533  * pop().
1534  * @see pop()
1535  * @see popIfNoUpdates()
1536  * @see unpop()
1537  * @see canPop()
1538  * @see canUnPop()
1539  * @see canPopThenUnPop()
1540  */
1541  virtual void push(bool unpopAllowed = true,
1542  std::vector<PropertyInterface *> *propertiesToPreserveOnPop = nullptr) = 0;
1543 
1544  /**
1545  * @brief Undoes modifications and reverts the whole graph hierarchy back to a previous state.
1546  *
1547  * @param unpopAllowed Whether or not it is possible to redo what will be undoe by this call.
1548  */
1549  virtual void pop(bool unpopAllowed = true) = 0;
1550 
1551  /**
1552  * @brief abort last push if no updates have been recorded
1553  */
1554  virtual void popIfNoUpdates() = 0;
1555 
1556  /**
1557  * @brief Re-perform actions that were undone using pop().
1558  *
1559  * For instance:
1560  * @code
1561  * DoubleProperty* prop = graph->getProperty<DoubleProperty>("metric");
1562  * string errorMessage;
1563  *
1564  * //apply some metric
1565  * graph->applyPropertyAlgorithm("Degree", prop, errorMessage);
1566  *
1567  * // save this state to be able to revert to it later
1568  * graph->push();
1569  *
1570  * //compute the quality of this metric, or whatever makes sense
1571  * int degreeQuality = prop->getMax();
1572  *
1573  * //compute another metric
1574  * graph->applyPropertyAlgorithm("Depth", prop, errorMessage);
1575  *
1576  * //compute its quality
1577  * int depthQuality = prop->getMax();
1578  *
1579  * //if the degree was better, revert back to the state where its contents were in prop.
1580  * if(degreeQuality > depthQuality) {
1581  * graph->pop();
1582  * }
1583  *
1584  * ...
1585  *
1586  * //revert back to the depth for some reason.
1587  * graph->unpop();
1588  * @endcode
1589  */
1590  virtual void unpop() = 0;
1591 
1592  /**
1593  * @brief Checks if there is a state to revert to.
1594  * @return Whether there was a previous call to push() that was not yet pop()'ed.
1595  */
1596  virtual bool canPop() = 0;
1597 
1598  /**
1599  * @brief Checks if the last undone modifications can be redone.
1600  * @return Whether it is possible to re-do modifications that have been undone by pop().
1601  */
1602  virtual bool canUnpop() = 0;
1603 
1604  /**
1605  * @brief Checks if it is possible to call pop() and then unPop(), to undo then re-do
1606  * modifications.
1607  * @return Whether it is possible to undo and then redo.
1608  */
1609  virtual bool canPopThenUnpop() = 0;
1610 
1611  // meta nodes management
1612  /**
1613  * @brief Creates a meta-node from a vector of nodes.
1614  * Every edges from any node in the vector to another node of the graph will be replaced with meta
1615  * edges
1616  * from the meta node to the other nodes.
1617  * @warning This method will fail when called on the root graph.
1618  *
1619  * @param nodes The vector of nodes to put into the meta node.
1620  * @param multiEdges Whether a meta edge should be created for each underlying edge.
1621  * @param delAllEdge Whether the underlying edges will be removed from the whole hierarchy.
1622  * @return The newly created meta node.
1623  */
1624  virtual node createMetaNode(const std::vector<node> &nodes, bool multiEdges = true,
1625  bool delAllEdge = true);
1626 
1627  /**
1628  * @brief Deprecated, use createMetaNode(const std::vector<node>&, bool multiEdges = true, bool
1629  * delAllEdge = true) instead
1630  */
1631  _DEPRECATED node createMetaNode(const std::set<node> &nodeSet, bool multiEdges = true,
1632  bool delAllEdge = true);
1633 
1634  /**
1635  * @brief Populates a quotient graph with one meta node
1636  * for each iterated graph.
1637  *
1638  * @param itS a Graph iterator, (typically a subgraph iterator)
1639  * @param quotientGraph the graph that will contain the meta nodes
1640  * @param metaNodes will contains all the added meta nodes after the call
1641  *
1642  */
1643  virtual void createMetaNodes(Iterator<Graph *> *itS, Graph *quotientGraph,
1644  std::vector<node> &metaNodes);
1645  /**
1646  * @brief Closes an existing subgraph into a metanode. Edges from nodes
1647  * in the subgraph to nodes outside the subgraph are replaced with
1648  * edges from the metanode to the nodes outside the subgraph.
1649  * @warning this method will fail when called on the root graph.
1650  *
1651  * @param subGraph an existing subgraph
1652  * @param multiEdges indicates if a meta edge will be created for each underlying edge
1653  * @param delAllEdge indicates if the underlying edges will be removed from the entire hierarchy
1654  */
1655  virtual node createMetaNode(Graph *subGraph, bool multiEdges = true, bool delAllEdge = true);
1656 
1657  /**
1658  * @brief Opens a metanode and replaces all edges between that
1659  * meta node and other nodes in the graph.
1660  *
1661  * @warning this method will fail when called on the root graph.
1662  *
1663  * @param n The meta node to open.
1664  * @param updateProperties If set to true, open meta node will update inner nodes layout, color,
1665  * size, etc
1666  */
1667  void openMetaNode(node n, bool updateProperties = true);
1668 
1669  ///@cond DOXYGEN_HIDDEN
1670 protected:
1671  virtual DataSet &getNonConstAttributes() = 0;
1672  // designed to reassign an id to a previously deleted elt
1673  // used by GraphUpdatesRecorder
1674  virtual void restoreNode(node) = 0;
1675  virtual void restoreEdge(edge, node source, node target) = 0;
1676  // designed to only update own structures
1677  // used by GraphUpdatesRecorder
1678  virtual void removeNode(const node) = 0;
1679  virtual void removeEdge(const edge) = 0;
1680 
1681  // to check if a property can be deleted
1682  // used by PropertyManager
1683  virtual bool canDeleteProperty(Graph *g, PropertyInterface *prop) {
1684  return getRoot()->canDeleteProperty(g, prop);
1685  }
1686 
1687  // local property renaming
1688  // can failed if a property with the same name already exists
1689  virtual bool renameLocalProperty(PropertyInterface *prop, const std::string &newName) = 0;
1690 
1691  // internally used to deal with sub graph deletion
1692  virtual void removeSubGraph(Graph *) = 0;
1693  virtual void clearSubGraphs() = 0;
1694  virtual void restoreSubGraph(Graph *) = 0;
1695  virtual void setSubGraphToKeep(Graph *) = 0;
1696 
1697  // for notification of GraphObserver
1698  void notifyAddNode(const node n);
1699  void notifyAddNode(Graph *, const node n) {
1700  notifyAddNode(n);
1701  }
1702  void notifyAddEdge(const edge e);
1703  void notifyAddEdge(Graph *, const edge e) {
1704  notifyAddEdge(e);
1705  }
1706  void notifyBeforeSetEnds(const edge e);
1707  void notifyBeforeSetEnds(Graph *, const edge e) {
1708  notifyBeforeSetEnds(e);
1709  }
1710  void notifyAfterSetEnds(const edge e);
1711  void notifyAfterSetEnds(Graph *, const edge e) {
1712  notifyAfterSetEnds(e);
1713  }
1714  void notifyDelNode(const node n);
1715  void notifyDelNode(Graph *, const node n) {
1716  notifyDelNode(n);
1717  }
1718  void notifyDelEdge(const edge e);
1719  void notifyDelEdge(Graph *, const edge e) {
1720  notifyDelEdge(e);
1721  }
1722  void notifyReverseEdge(const edge e);
1723  void notifyReverseEdge(Graph *, const edge e) {
1724  notifyReverseEdge(e);
1725  }
1726  void notifyBeforeAddSubGraph(const Graph *);
1727  void notifyAfterAddSubGraph(const Graph *);
1728  void notifyBeforeAddSubGraph(Graph *, const Graph *sg) {
1729  notifyBeforeAddSubGraph(sg);
1730  }
1731  void notifyAfterAddSubGraph(Graph *, const Graph *sg) {
1732  notifyAfterAddSubGraph(sg);
1733  }
1734  void notifyBeforeDelSubGraph(const Graph *);
1735  void notifyAfterDelSubGraph(const Graph *);
1736  void notifyBeforeDelSubGraph(Graph *, const Graph *sg) {
1737  notifyBeforeDelSubGraph(sg);
1738  }
1739  void notifyAfterDelSubGraph(Graph *, const Graph *sg) {
1740  notifyAfterDelSubGraph(sg);
1741  }
1742 
1743  void notifyBeforeAddDescendantGraph(const Graph *);
1744  void notifyAfterAddDescendantGraph(const Graph *);
1745  void notifyBeforeDelDescendantGraph(const Graph *);
1746  void notifyAfterDelDescendantGraph(const Graph *);
1747 
1748  void notifyBeforeAddLocalProperty(const std::string &);
1749  void notifyAddLocalProperty(const std::string &);
1750  void notifyAddLocalProperty(Graph *, const std::string &name) {
1751  notifyAddLocalProperty(name);
1752  }
1753  void notifyBeforeDelLocalProperty(const std::string &);
1754  void notifyAfterDelLocalProperty(const std::string &);
1755  void notifyDelLocalProperty(Graph *, const std::string &name) {
1756  notifyBeforeDelLocalProperty(name);
1757  }
1758  void notifyBeforeSetAttribute(const std::string &);
1759  void notifyBeforeSetAttribute(Graph *, const std::string &name) {
1760  notifyBeforeSetAttribute(name);
1761  }
1762  void notifyAfterSetAttribute(const std::string &);
1763  void notifyAfterSetAttribute(Graph *, const std::string &name) {
1764  notifyAfterSetAttribute(name);
1765  }
1766  void notifyRemoveAttribute(const std::string &);
1767  void notifyRemoveAttribute(Graph *, const std::string &name) {
1768  notifyRemoveAttribute(name);
1769  }
1770  void notifyDestroy();
1771  void notifyDestroy(Graph *) {
1772  notifyDestroy();
1773  }
1774 
1775  unsigned int id;
1776  std::unordered_map<std::string, tlp::PropertyInterface *> circularCalls;
1777  ///@endcond
1778 };
1779 
1780 /**
1781  * @ingroup Observation
1782  * Event class for specific events on Graph
1783  **/
1784 class TLP_SCOPE GraphEvent : public Event {
1785 public:
1786  // be careful about the ordering of the constants
1787  // in the enum below because it is used in some assertions
1788  enum GraphEventType {
1789  TLP_ADD_NODE = 0,
1790  TLP_DEL_NODE = 1,
1791  TLP_ADD_EDGE = 2,
1792  TLP_DEL_EDGE = 3,
1793  TLP_REVERSE_EDGE = 4,
1794  TLP_BEFORE_SET_ENDS = 5,
1795  TLP_AFTER_SET_ENDS = 6,
1796  TLP_ADD_NODES = 7,
1797  TLP_ADD_EDGES = 8,
1798  TLP_BEFORE_ADD_DESCENDANTGRAPH = 9,
1799  TLP_AFTER_ADD_DESCENDANTGRAPH = 10,
1800  TLP_BEFORE_DEL_DESCENDANTGRAPH = 11,
1801  TLP_AFTER_DEL_DESCENDANTGRAPH = 12,
1802  TLP_BEFORE_ADD_SUBGRAPH = 13,
1803  TLP_AFTER_ADD_SUBGRAPH = 14,
1804  TLP_BEFORE_DEL_SUBGRAPH = 15,
1805  TLP_AFTER_DEL_SUBGRAPH = 16,
1806  TLP_ADD_LOCAL_PROPERTY = 17,
1807  TLP_BEFORE_DEL_LOCAL_PROPERTY = 18,
1808  TLP_AFTER_DEL_LOCAL_PROPERTY = 19,
1809  TLP_ADD_INHERITED_PROPERTY = 20,
1810  TLP_BEFORE_DEL_INHERITED_PROPERTY = 21,
1811  TLP_AFTER_DEL_INHERITED_PROPERTY = 22,
1812  TLP_BEFORE_RENAME_LOCAL_PROPERTY = 23,
1813  TLP_AFTER_RENAME_LOCAL_PROPERTY = 24,
1814  TLP_BEFORE_SET_ATTRIBUTE = 25,
1815  TLP_AFTER_SET_ATTRIBUTE = 26,
1816  TLP_REMOVE_ATTRIBUTE = 27,
1817  TLP_BEFORE_ADD_LOCAL_PROPERTY = 28,
1818  TLP_BEFORE_ADD_INHERITED_PROPERTY = 29
1819  };
1820 
1821  // constructor for node/edge/nodes/edges events
1822  GraphEvent(const Graph &g, GraphEventType graphEvtType, unsigned int id,
1823  Event::EventType evtType = Event::TLP_MODIFICATION)
1824  : Event(g, evtType), evtType(graphEvtType) {
1825  if (graphEvtType == TLP_ADD_NODES || graphEvtType == TLP_ADD_EDGES)
1826  info.nbElts = id;
1827  else
1828  info.eltId = id;
1829 
1830  vectInfos.addedNodes = nullptr;
1831  }
1832  // constructor for subgraph events
1833  GraphEvent(const Graph &g, GraphEventType graphEvtType, const Graph *sg)
1834  : Event(g, Event::TLP_MODIFICATION), evtType(graphEvtType) {
1835  info.subGraph = sg;
1836  vectInfos.addedNodes = nullptr;
1837  }
1838 
1839  // constructor for attribute/property events
1840  GraphEvent(const Graph &g, GraphEventType graphEvtType, const std::string &str,
1841  Event::EventType evtType = Event::TLP_MODIFICATION)
1842  : Event(g, evtType), evtType(graphEvtType) {
1843  info.name = new std::string(str);
1844  vectInfos.addedNodes = nullptr;
1845  }
1846 
1847  // constructor for rename property events
1848  GraphEvent(const Graph &g, GraphEventType graphEvtType, PropertyInterface *prop,
1849  const std::string &newName)
1850  : Event(g, Event::TLP_MODIFICATION), evtType(graphEvtType) {
1851  info.renamedProp = new std::pair<PropertyInterface *, std::string>(prop, newName);
1852  vectInfos.addedNodes = nullptr;
1853  }
1854 
1855  ~GraphEvent() override;
1856 
1857  Graph *getGraph() const {
1858  return static_cast<Graph *>(sender());
1859  }
1860 
1861  node getNode() const {
1862  assert(evtType < TLP_ADD_EDGE);
1863  return node(info.eltId);
1864  }
1865 
1866  edge getEdge() const {
1867  assert(evtType > TLP_DEL_NODE && evtType < TLP_ADD_NODES);
1868  return edge(info.eltId);
1869  }
1870 
1871  const std::vector<node> &getNodes() const;
1872 
1873  unsigned int getNumberOfNodes() const {
1874  assert(evtType == TLP_ADD_NODES);
1875  return info.nbElts;
1876  }
1877 
1878  const std::vector<edge> &getEdges() const;
1879 
1880  unsigned int getNumberOfEdges() const {
1881  assert(evtType == TLP_ADD_EDGES);
1882  return info.nbElts;
1883  }
1884 
1885  const Graph *getSubGraph() const {
1886  assert(evtType > TLP_ADD_EDGES && evtType < TLP_ADD_LOCAL_PROPERTY);
1887  return info.subGraph;
1888  }
1889 
1890  const std::string &getAttributeName() const {
1891  assert(evtType > TLP_AFTER_DEL_INHERITED_PROPERTY);
1892  return *(info.name);
1893  }
1894 
1895  const std::string &getPropertyName() const;
1896 
1897  PropertyInterface *getProperty() const {
1898  assert(evtType == TLP_BEFORE_RENAME_LOCAL_PROPERTY ||
1899  evtType == TLP_AFTER_RENAME_LOCAL_PROPERTY);
1900  return info.renamedProp->first;
1901  }
1902 
1903  const std::string &getPropertyNewName() const {
1904  assert(evtType == TLP_BEFORE_RENAME_LOCAL_PROPERTY);
1905  return info.renamedProp->second;
1906  }
1907 
1908  const std::string &getPropertyOldName() const {
1909  assert(evtType == TLP_AFTER_RENAME_LOCAL_PROPERTY);
1910  return info.renamedProp->second;
1911  }
1912 
1913  GraphEventType getType() const {
1914  return evtType;
1915  }
1916 
1917 protected:
1918  GraphEventType evtType;
1919  union {
1920  unsigned int eltId;
1921  const Graph *subGraph;
1922  std::string *name;
1923  unsigned int nbElts;
1924  std::pair<PropertyInterface *, std::string> *renamedProp;
1925  } info;
1926  union {
1927  std::vector<node> *addedNodes;
1928  std::vector<edge> *addedEdges;
1929  } vectInfos;
1930 };
1931 } // namespace tlp
1932 
1933 /// Print the graph (only nodes and edges) in ostream, in the tulip format
1934 TLP_SCOPE std::ostream &operator<<(std::ostream &, const tlp::Graph *);
1935 
1936 #include "cxx/Graph.cxx"
1937 #endif
virtual bool hasEdge(const node source, const node target, bool directed=true) const
Checks if an edge exists between two given nodes.
Definition: Graph.h:1185
void removeFromGraph(Graph *ioG, BooleanProperty *inSelection=nullptr)
A graph property that maps a boolean value to graph elements.
Interface for Tulip iterators. Allows basic iteration operations only.
Definition: Graph.h:43
Graph * newGraph()
Creates a new, empty graph.
PropertyInterface describes the interface of a graph property.
Describes a value of any type.
Definition: DataSet.h:57
A container that can store data from any type.
Definition: DataSet.h:189
const DataSet & getAttributes() const
Gets the attributes of the graph.
Definition: Graph.h:1233
Graph * loadGraph(const std::string &filename, tlp::PluginProgress *progress=nullptr)
Loads a graph from a file (extension can be any of the Tulip supported input graph file format)...
Graph * importGraph(const std::string &format, DataSet &dataSet, PluginProgress *progress=nullptr, Graph *newGraph=nullptr)
Imports a graph using the specified import plugin with the parameters stored in the DataSet...
Iterator< Graph * > * getRootGraphs()
ElementType
Definition: Graph.h:50
virtual bool isEmpty() const
return whether the graph is empty or not.
Definition: Graph.h:1083
The edge struct represents an edge in a Graph object.
Definition: Edge.h:40
The node struct represents a node in a Graph object.
Definition: Node.h:40
Event is the base class for all events used in the Observation mechanism.
Definition: Observable.h:52
unsigned int getId() const
Gets the unique identifier of the graph.
Definition: Graph.h:1075
PluginProcess subclasses are meant to notify about the progress state of some process (typically a pl...
bool applyPropertyAlgorithm(const std::string &algorithm, PropertyInterface *result, std::string &errorMessage, PluginProgress *progress, DataSet *parameters=nullptr)
Deprecated, use applyPropertyAlgorithm(const std::string &algorithm, PropertyInterface *result...
Definition: Graph.h:1468
void removeAttribute(const std::string &name)
Removes an attribute on the graph.
Definition: Graph.h:1272
void copyToGraph(Graph *outG, const Graph *inG, BooleanProperty *inSelection=nullptr, BooleanProperty *outSelection=nullptr)
The Observable class is the base of Tulip&#39;s observation system.
Definition: Observable.h:127
bool attributeExist(const std::string &name) const
deprecated, use existAttribute instead.
Definition: Graph.h:1289
bool saveGraph(Graph *graph, const std::string &filename, tlp::PluginProgress *progress=nullptr, tlp::DataSet *data=nullptr)
Saves the corresponding graph to a file (extension can be any of the Tulip supported ouput graph file...
bool existAttribute(const std::string &name) const
Checks if an attribute exists.
Definition: Graph.h:1282
bool exportGraph(Graph *graph, std::ostream &outputStream, const std::string &format, DataSet &dataSet, PluginProgress *progress=nullptr)
Exports a graph using the specified export plugin with parameters stored in the DataSet.
std::ostream & operator<<(std::ostream &os, const Array< T, N > &array)
operator << stream operator to easily print an array, or save it to a file.