Tulip  5.2.0
Large graphs analysis and drawing
PropertyWrapper.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 ///@cond DOXYGEN_HIDDEN
20 
21 #ifndef PROPERTYWRAPPER_H
22 #define PROPERTYWRAPPER_H
23 
24 #include <tulip/DoubleProperty.h>
25 #include <tulip/IntegerProperty.h>
26 #include <tulip/LayoutProperty.h>
27 #include <tulip/BooleanProperty.h>
28 #include <tulip/ColorProperty.h>
29 #include <tulip/StringProperty.h>
30 #include <tulip/SizeProperty.h>
31 
32 /**
33  * @brief simple implementation of the copy-on-write idiom.
34  */
35 template <typename PROPERTYTYPE, typename Type>
36 class ValueWrapper {
37 public:
38  ValueWrapper(PROPERTYTYPE *prop, tlp::node n) : _prop(prop), _n(n) {}
39 
40  ValueWrapper(PROPERTYTYPE *prop, tlp::edge e) : _prop(prop), _e(e) {}
41 
42  void operator=(Type other) {
43  if (_n.isValid())
44  _prop->setNodeValue(_n, other);
45 
46  if (_e.isValid())
47  _prop->setEdgeValue(_e, other);
48  }
49 
50  /**
51  * @brief Implicit conversion to Type
52  */
53  operator Type() const {
54  if (_n.isValid())
55  return _prop->getNodeValue(_n);
56 
57  if (_e.isValid())
58  return _prop->getEdgeValue(_e);
59 
60  std::cout << "WTF!?" << std::endl;
61  return Type();
62  }
63 
64  /**
65  * @brief operator= when prop[n] = prop[n2]
66  * @param other
67  */
68  void operator=(ValueWrapper<PROPERTYTYPE, Type> other) {
69  if (_n.isValid())
70  _prop->setNodeValue(_n, Type(other));
71 
72  if (_e.isValid())
73  _prop->setEdgeValue(_e, Type(other));
74  }
75 
76 private:
77  PROPERTYTYPE *_prop;
78  tlp::node _n;
79  tlp::edge _e;
80 };
81 
82 template <typename PROPERTYTYPE, typename Type>
83 class PropertyWrapper {
84 public:
85  PropertyWrapper(tlp::PropertyInterface *internal) {
86  PROPERTYTYPE *castedInternal = dynamic_cast<PROPERTYTYPE *>(internal);
87 
88  if (castedInternal == nullptr) {
89  tlp::error() << "error: could not convert tulip property to "
90  << tlp::demangleTlpClassName(typeid(PROPERTYTYPE).name()) << std::endl;
91  }
92 
93  _internal = castedInternal;
94  }
95  PropertyWrapper() : _internal(nullptr) {}
96 
97  bool isValid() const {
98  return _internal != nullptr;
99  }
100 
101  void setAllNodeValue(Type value) {
102  _internal->setAllNodeValue(value);
103  }
104 
105  void setAllEdgeValue(Type value) {
106  _internal->setAllEdgeValue(value);
107  }
108 
109  Type getNodeValue(tlp::node n) const {
110  return _internal->getNodeValue(n);
111  }
112  void setNodeValue(tlp::node n, Type value) {
113  _internal->setNodeValue(n, value);
114  }
115 
116  Type getEdgeValue(tlp::edge e) const {
117  return _internal->getEdgeValue(e);
118  }
119  void setEdgeValue(tlp::edge e, Type value) {
120  _internal->setEdgeValue(e, value);
121  }
122 
123  Type operator[](tlp::node n) const {
124  return _internal->getNodeValue(n);
125  }
126  Type operator[](tlp::edge e) const {
127  return _internal->getEdgeValue(e);
128  }
129  ValueWrapper<PROPERTYTYPE, Type> operator[](tlp::node n) {
130  return ValueWrapper<PROPERTYTYPE, Type>(_internal, n);
131  }
132 
133  ValueWrapper<PROPERTYTYPE, Type> operator[](tlp::edge e) {
134  return ValueWrapper<PROPERTYTYPE, Type>(_internal, e);
135  }
136 
137  PROPERTYTYPE *internal() const {
138  return _internal;
139  }
140 
141  operator PROPERTYTYPE *() {
142  return _internal;
143  }
144 
145 private:
146  PROPERTYTYPE *_internal;
147 };
148 
149 template <typename PROPERTYTYPE, typename NodeType, typename EdgeType>
150 class ComplexValueWrapper {
151 public:
152  ComplexValueWrapper(PROPERTYTYPE *prop, tlp::node n) : _prop(prop), _n(n) {}
153 
154  ComplexValueWrapper(PROPERTYTYPE *prop, tlp::edge e) : _prop(prop), _e(e) {}
155 
156  void operator=(NodeType other) {
157  if (_n.isValid())
158  _prop->setNodeValue(_n, other);
159  }
160 
161  void operator=(EdgeType other) {
162  if (_e.isValid())
163  _prop->setEdgeValue(_e, other);
164  }
165 
166  operator NodeType() const {
167  if (_n.isValid())
168  return _prop->getNodeValue(_n);
169  }
170  operator EdgeType() const {
171  if (_e.isValid())
172  return _prop->getEdgeValue(_e);
173  }
174 
175 private:
176  PROPERTYTYPE *_prop;
177  tlp::node _n;
178  tlp::edge _e;
179 };
180 
181 template <typename PROPERTYTYPE, typename NodeType, typename EdgeType>
182 class ComplexPropertyWrapper {
183 public:
184  ComplexPropertyWrapper(tlp::PropertyInterface *internal) {
185  PROPERTYTYPE *castedInternal = dynamic_cast<PROPERTYTYPE *>(internal);
186 
187  if (castedInternal == nullptr) {
188  tlp::error() << "error: could not convert tulip property to "
189  << tlp::demangleTlpClassName(typeid(PROPERTYTYPE).name()) << std::endl;
190  }
191 
192  _internal = castedInternal;
193  }
194  ComplexPropertyWrapper() : _internal(nullptr) {}
195 
196  bool isValid() const {
197  return _internal != nullptr;
198  }
199 
200  void setAllNodeValue(NodeType value) {
201  _internal->setAllNodeValue(value);
202  }
203 
204  void setAllEdgeValue(EdgeType value) {
205  _internal->setAllEdgeValue(value);
206  }
207 
208  NodeType getNodeValue(tlp::node n) const {
209  return _internal->getNodeValue(n);
210  }
211  void setNodeValue(tlp::node n, EdgeType value) {
212  _internal->setNodeValue(n, value);
213  }
214 
215  NodeType getEdgeValue(tlp::edge e) const {
216  return _internal->getEdgeValue(e);
217  }
218  void setEdgeValue(tlp::edge e, NodeType value) {
219  _internal->setEdgeValue(e, value);
220  }
221 
222  NodeType operator[](tlp::node n) const {
223  return _internal->getNodeValue(n);
224  }
225  EdgeType operator[](tlp::edge e) const {
226  return _internal->getEdgeValue(e);
227  }
228  ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType> operator[](tlp::node n) {
229  return ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType>(_internal, n);
230  }
231 
232  ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType> operator[](tlp::edge e) {
233  return ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType>(_internal, e);
234  }
235 
236  PROPERTYTYPE *internal() const;
237 
238  operator PROPERTYTYPE *() {
239  return _internal;
240  }
241 
242 private:
243  PROPERTYTYPE *_internal;
244 };
245 
246 typedef PropertyWrapper<tlp::DoubleProperty, double> DoublePropertyWrapper;
247 typedef PropertyWrapper<tlp::IntegerProperty, int> IntegerPropertyWrapper;
248 typedef PropertyWrapper<tlp::BooleanProperty, bool> BooleanPropertyWrapper;
249 typedef PropertyWrapper<tlp::ColorProperty, tlp::Color> ColorPropertyWrapper;
250 typedef PropertyWrapper<tlp::StringProperty, std::string> StringPropertyWrapper;
251 typedef PropertyWrapper<tlp::SizeProperty, tlp::Size> SizePropertyWrapper;
252 typedef ComplexPropertyWrapper<tlp::LayoutProperty, tlp::Coord, tlp::LineType>
253  LayoutPropertyWrapper;
254 
255 #endif // PROPERTYWRAPPER_H
256 ///@endcond
PropertyInterface describes the interface of a graph property.
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
std::string demangleTlpClassName(const char *className)
Demangles the name of a C++ class defined in the tlp namespace.
Definition: TlpTools.h:75