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