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