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