Tulip  4.8.0
Better Visualization Through Research
 All Classes Files Functions Variables Enumerations Enumerator Properties Groups Pages
vectorgraphproperty.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
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 ///@cond DOXYGEN_HIDDEN
20 
21 #ifndef VECTORGRAPHPROPERTY_H
22 #define VECTORGRAPHPROPERTY_H
23 #include <algorithm>
24 #include <cassert>
25 
26 namespace tlp {
27 class VectorGraph;
28 /**
29  * @brief Internal class to access to a stl::vector in VectorGraph
30  * @warning never use that class
31  */
32 class ValArrayInterface {
33  friend class VectorGraph;
34 protected:
35  virtual void addElement(const unsigned int id) = 0;
36  virtual void reserve(const size_t size) = 0;
37  virtual ~ValArrayInterface() {}
38 };
39 //===========================================
40 /**
41  * @brief Internal class to access to a stl::vector in VectorGraph
42  * @warning never use that class
43  */
44 template <typename TYPE>
45 class ValArray : public ValArrayInterface {
46  friend class VectorGraph;
47 protected:
48  ValArray(const unsigned int size = 0, const unsigned int capacity = 0) {
49  _data.reserve(capacity);
50  _data.resize(size);
51  }
52  virtual ~ValArray() {}
53  void addElement(const unsigned int id) {
54  if (id >= _data.size()) {
55  _data.resize(id);
56  _data.push_back(TYPE());
57  }
58  }
59  void reserve(const size_t size) {
60  _data.reserve(size);
61  }
62 
63 public:
64  std::vector<TYPE> _data; /**< TODO */
65 };
66 /**
67  * @class VectorGraphProperty
68  * @brief That class enables to factorize code for NodeProperty and EdgeProperty in VectorGraph, it could not be used directly.
69  * @see NodeProperty
70  * @see EdgeProperty
71  * @see VectorGraph
72  */
73 template <typename TYPE>
74 class VectorGraphProperty {
75  friend class VectorGraph;
76 public:
77  virtual ~VectorGraphProperty() {}
78  /**
79  * @brief read/write accessor
80  *
81  * return the value of the ith element and enables to modify it.
82  */
83  typename std::vector<TYPE>::reference operator[](const size_t id) {
84  //assert(isValid());
85  assert(id < (*_array)._data.size());
86  return (*_array)._data[id];
87  }
88  /**
89  * @brief read accessor
90  *
91  * return the value of the ith element.
92  */
93  typename std::vector<TYPE>::const_reference operator[](const size_t id) const {
94  //assert(isValid());
95  assert(id < (*_array)._data.size());
96  return (*_array)._data[id];
97  }
98  /**
99  * @bried Set all the value of the property to the value given in parameter
100  *
101  * That function affect the same value to all elements of the vector, there
102  * is no effect on the future value added in the vector
103  * @warning There is differences between the setAll of the MutableContainer and
104  * the setAll of VectorProperty (NodeProperty or EdgeProperty). The MutableContainer,
105  * ensures that new inserted element will have the value given by the last setAll
106  *
107  * @see MutableContainer
108  */
109  void setAll(const TYPE &obj) {
110  fill(_array->_data.begin(), _array->_data.end(), obj);
111  }
112  /**
113  * @brief write accessor
114  *
115  * change the value of the ith element.
116  */
117  void set(const size_t id, const TYPE &obj) {
118  (*this)[id] = obj;
119  }
120  /**
121  * @brief read accessor
122  *
123  * return the value of the ith element.
124  */
125  typename std::vector<TYPE>::const_reference get(const size_t id) const {
126  return (*this)[id];
127  }
128 #ifndef NDEBUG
129  virtual bool isValid() const = 0;
130 #endif
131 
132 protected:
133  VectorGraphProperty():_array(0), _graph(0) {
134  }
135  VectorGraphProperty(const VectorGraphProperty &obj): _array(obj._array), _graph(obj._graph) {
136  }
137  VectorGraphProperty(ValArray<TYPE> *array, VectorGraph *graph):_array(array), _graph(graph) {
138  }
139 protected:
140  ValArray<TYPE> *_array; /**< TODO */
141  VectorGraph *_graph; /**< TODO */
142 };
143 
144 /**
145  * @class EdgeProperty
146  * @brief That class enables to define a property/attribute on edges on a VectorGraph.
147  *
148  * Using EdgeProperty you can assign any kind of attribute to edges. To use that class
149  * you must first create an instance of EdgeProperty and then connect it to your graph.
150  * NodeProperty can be copied in another EdgeProperty, however the to NodeProperty will
151  * share the same content. You can consider that EdgeProperty is just a pointer on a stl:vector.
152  * to free memory used by a EdgeProperty connected to a graph you must use the free function.
153  * @warning After the call to free all The copy of the orignal EdgeProperty are no more valid
154  *
155  * Using EdgeProperty you can store and access to values with the same efficiency as if
156  * you created manually a vector. EdgeProperty manage for you the resize, etc... when the
157  * graph is modified.
158  *
159  * Furthemrore, in DEBUG mode, operator[] check if one try to access outside of the Array Bound.
160  * in DEBUG mode, the validy of the Property is also checked (if it has been free/alloc etc...)
161  *
162  * @code
163  * VectorGraph g;
164  * EdgeProperty<double> weight;
165  * g.alloc(weight); //connect weight to g, g allocate memory for that attribute
166  * edge e;
167  * forEach(e, g.getEdges()) {
168  * weight[n] = g.deg(g.target(e)) + g.deg(g.source(e));
169  * }
170  * EdgeProperty<double> weight2 = weight; //weight2 and weight are pointing on the same memory addres
171  * weight2[g[0]] = 3;
172  * tlp::debug() << weight[g[0]]; //output 3
173  * g.free(weight2); //free the memory, weight and weight2 are no more valid.
174  * @endcode
175  * @see VectorGraph alloc(EdgeProperty)
176  * @see VectorGraph free(EdgeProperty)
177  * @see VectorGraph
178  */
179 template <typename TYPE>
180 class EdgeProperty : public VectorGraphProperty<TYPE> {
181  friend class VectorGraph;
182 public:
183  EdgeProperty():VectorGraphProperty<TYPE>() {}
184  EdgeProperty(const EdgeProperty &obj): VectorGraphProperty<TYPE>(obj) {}
185 #ifndef NDEBUG
186  bool isValid() const;
187 #endif
188 
189 private:
190  EdgeProperty(ValArray<TYPE> *array, VectorGraph *graph):VectorGraphProperty<TYPE>(array, graph) {}
191 
192 };
193 /**
194  * @class NodeProperty
195  * @brief That class enables to define a property/attribute on nodes on a VectorGraph.
196  *
197  * Using NodeProperty you can assign any kind of attribute to nodes. To use that class
198  * you must first create an instance of NodeProperty and then connect it to your graph.
199  * NodeProperty can be copied in another NodeProperty, however the to NodeProperty will
200  * share the same content. You can consider that NodeProperty is just a pointer on a stl:vector.
201  * to free memory used by a NodeProperty connected to a graph you must use the free function.
202  * @warning After the call to free all The copy of the orignal NodeProperty are no more valid
203  *
204  * Using NodeProperty you can store and access to values with the same efficiency as if
205  * you created manually a vector. NodeProperty manage for you the resize, etc... when the
206  * graph is modified.
207  *
208  * Furthemrore, in DEBUG mode, operator[] check if one try to access outside of the Array Bound.
209  * in DEBUG mode, the validy of the Property is also checked (if it has been free/alloc etc...)
210  *
211  * @code
212  * VectorGraph g;
213  * NodeProperty<double> weight;
214  * g.alloc(weight); //connect weight to g, g allocate memory for that attribute
215  * node n;
216  * forEach(n, g.getNodes()) {
217  * weight[n] = g.deg(n);
218  * }
219  * NodeProperty<double> weight2 = weight; //weight2 and weight are pointing on the same memory addres
220  * weight2[g[0]] = 3;
221  * tlp::debug() << weight[g[0]]; //output 3
222  * g.free(weight2); //free the memory, weight and weight2 are no more valid.
223  * @endcode
224  * @see VectorGraph alloc(NodeProperty)
225  * @see VectorGraph free(NodeProperty)
226  */
227 template <typename TYPE>
228 class NodeProperty : public VectorGraphProperty<TYPE> {
229  friend class VectorGraph;
230 public:
231  NodeProperty():VectorGraphProperty<TYPE>() {}
232  NodeProperty(const NodeProperty &obj): VectorGraphProperty<TYPE>(obj) {}
233 #ifndef NDEBUG
234  bool isValid() const;
235 #endif
236 
237 private:
238  NodeProperty(ValArray<TYPE> *array, VectorGraph *graph):VectorGraphProperty<TYPE>(array, graph) {}
239 };
240 
241 }
242 #endif // VECTORGRAPHPROPERTY_H
243 ///@endcond