Tulip  4.6.0
Better Visualization Through Research
library/tulip-core/include/tulip/PropertyWrapper.h
00001 /*
00002  *
00003  * This file is part of Tulip (www.tulip-software.org)
00004  *
00005  * Authors: David Auber and the Tulip development Team
00006  * from LaBRI, University of Bordeaux
00007  *
00008  * Tulip is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation, either version 3
00011  * of the License, or (at your option) any later version.
00012  *
00013  * Tulip is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  *
00018  */
00019 
00020 #ifndef PROPERTYWRAPPER_H
00021 #define PROPERTYWRAPPER_H
00022 
00023 #include <tulip/DoubleProperty.h>
00024 #include <tulip/IntegerProperty.h>
00025 #include <tulip/LayoutProperty.h>
00026 #include <tulip/BooleanProperty.h>
00027 #include <tulip/ColorProperty.h>
00028 #include <tulip/StringProperty.h>
00029 #include <tulip/SizeProperty.h>
00030 
00031 /**
00032  * @brief simple implementation of the copy-on-write idiom.
00033  */
00034 template<typename PROPERTYTYPE, typename Type>
00035 class ValueWrapper {
00036 public:
00037   ValueWrapper(PROPERTYTYPE* prop, tlp::node n) : _prop(prop), _n(n) {
00038   }
00039 
00040   ValueWrapper(PROPERTYTYPE* prop, tlp::edge e) : _prop(prop), _e(e) {
00041   }
00042 
00043   void operator=(Type other) {
00044     if(_n.isValid())
00045       _prop->setNodeValue(_n, other);
00046 
00047     if(_e.isValid())
00048       _prop->setEdgeValue(_e, other);
00049   }
00050 
00051   /**
00052    * @brief Implicit conversion to Type
00053    */
00054   operator Type() const {
00055     if(_n.isValid())
00056       return _prop->getNodeValue(_n);
00057 
00058     if(_e.isValid())
00059       return _prop->getEdgeValue(_e);
00060 
00061     std::cout << "WTF!?" << std::endl;
00062     return Type();
00063   }
00064 
00065   /**
00066    * @brief operator= when prop[n] = prop[n2]
00067    * @param other
00068    */
00069   void operator=(ValueWrapper<PROPERTYTYPE, Type> other) {
00070     if(_n.isValid())
00071       _prop->setNodeValue(_n, Type(other));
00072 
00073     if(_e.isValid())
00074       _prop->setEdgeValue(_e, Type(other));
00075   }
00076 
00077 private:
00078   PROPERTYTYPE* _prop;
00079   tlp::node _n;
00080   tlp::edge _e;
00081 };
00082 
00083 template<typename PROPERTYTYPE, typename Type>
00084 class PropertyWrapper {
00085 public:
00086   PropertyWrapper(tlp::PropertyInterface* internal) {
00087     PROPERTYTYPE* castedInternal = dynamic_cast<PROPERTYTYPE*>(internal);
00088 
00089     if(castedInternal == nullptr) {
00090       tlp::error() << "error: could not convert tulip property to " << tlp::demangleTlpClassName(typeid(PROPERTYTYPE).name()) << std::endl;
00091     }
00092 
00093     _internal = castedInternal;
00094   }
00095   PropertyWrapper() : _internal(nullptr) {}
00096 
00097   bool isValid() const {
00098     return _internal != nullptr;
00099   }
00100 
00101   void setAllNodeValue(Type value) {
00102     _internal->setAllNodeValue(value);
00103   }
00104 
00105   void setAllEdgeValue(Type value) {
00106     _internal->setAllEdgeValue(value);
00107   }
00108 
00109   Type getNodeValue(tlp::node n) const {
00110     return _internal->getNodeValue(n);
00111   }
00112   void setNodeValue(tlp::node n, Type value) {
00113     _internal->setNodeValue(n, value);
00114   }
00115 
00116   Type getEdgeValue(tlp::edge e) const {
00117     return _internal->getEdgeValue(e);
00118   }
00119   void setEdgeValue(tlp::edge e, Type value) {
00120     _internal->setEdgeValue(e, value);
00121   }
00122 
00123   Type operator[](tlp::node n) const {
00124     return _internal->getNodeValue(n);
00125   }
00126   Type operator[](tlp::edge e) const {
00127     return _internal->getEdgeValue(e);
00128   }
00129   ValueWrapper<PROPERTYTYPE, Type> operator[](tlp::node n) {
00130     return ValueWrapper<PROPERTYTYPE, Type>(_internal, n);
00131   }
00132 
00133   ValueWrapper<PROPERTYTYPE, Type> operator[](tlp::edge e) {
00134     return ValueWrapper<PROPERTYTYPE, Type>(_internal, e);
00135   }
00136 
00137   PROPERTYTYPE* internal() const {
00138     return _internal;
00139   }
00140 
00141   operator PROPERTYTYPE*() {
00142     return _internal;
00143   }
00144 
00145 private:
00146   PROPERTYTYPE* _internal;
00147 };
00148 
00149 template<typename PROPERTYTYPE, typename NodeType, typename EdgeType>
00150 class ComplexValueWrapper {
00151 public:
00152   ComplexValueWrapper(PROPERTYTYPE* prop, tlp::node n) : _prop(prop), _n(n) {
00153   }
00154 
00155   ComplexValueWrapper(PROPERTYTYPE* prop, tlp::edge e) : _prop(prop), _e(e) {
00156   }
00157 
00158   void operator=(NodeType other) {
00159     if(_n.isValid())
00160       _prop->setNodeValue(_n, other);
00161   }
00162 
00163   void operator=(EdgeType other) {
00164     if(_e.isValid())
00165       _prop->setEdgeValue(_e, other);
00166   }
00167 
00168   operator NodeType() const {
00169     if(_n.isValid())
00170       return _prop->getNodeValue(_n);
00171   }
00172   operator EdgeType() const {
00173     if(_e.isValid())
00174       return _prop->getEdgeValue(_e);
00175   }
00176 
00177 private:
00178   PROPERTYTYPE* _prop;
00179   tlp::node _n;
00180   tlp::edge _e;
00181 };
00182 
00183 template<typename PROPERTYTYPE, typename NodeType, typename EdgeType>
00184 class ComplexPropertyWrapper {
00185 public:
00186   ComplexPropertyWrapper(tlp::PropertyInterface* internal) {
00187     PROPERTYTYPE* castedInternal = dynamic_cast<PROPERTYTYPE*>(internal);
00188 
00189     if(castedInternal == nullptr) {
00190       tlp::error() << "error: could not convert tulip property to " << tlp::demangleTlpClassName(typeid(PROPERTYTYPE).name()) << std::endl;
00191     }
00192 
00193     _internal = castedInternal;
00194   }
00195   ComplexPropertyWrapper() : _internal(nullptr) {}
00196 
00197   bool isValid() const {
00198     return _internal != nullptr;
00199   }
00200 
00201   void setAllNodeValue(NodeType value) {
00202     _internal->setAllNodeValue(value);
00203   }
00204 
00205   void setAllEdgeValue(EdgeType value) {
00206     _internal->setAllEdgeValue(value);
00207   }
00208 
00209   NodeType getNodeValue(tlp::node n) const {
00210     return _internal->getNodeValue(n);
00211   }
00212   void setNodeValue(tlp::node n, EdgeType value) {
00213     _internal->setNodeValue(n, value);
00214   }
00215 
00216   NodeType getEdgeValue(tlp::edge e) const {
00217     return _internal->getEdgeValue(e);
00218   }
00219   void setEdgeValue(tlp::edge e, NodeType value) {
00220     _internal->setEdgeValue(e, value);
00221   }
00222 
00223   NodeType operator[](tlp::node n) const {
00224     return _internal->getNodeValue(n);
00225   }
00226   EdgeType operator[](tlp::edge e) const {
00227     return _internal->getEdgeValue(e);
00228   }
00229   ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType> operator[](tlp::node n) {
00230     return ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType>(_internal, n);
00231   }
00232 
00233   ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType> operator[](tlp::edge e) {
00234     return ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType>(_internal, e);
00235   }
00236 
00237   PROPERTYTYPE* internal() const;
00238 
00239   operator PROPERTYTYPE*() {
00240     return _internal;
00241   }
00242 
00243 private:
00244   PROPERTYTYPE* _internal;
00245 };
00246 
00247 typedef PropertyWrapper<tlp::DoubleProperty, double> DoublePropertyWrapper;
00248 typedef PropertyWrapper<tlp::IntegerProperty, int> IntegerPropertyWrapper;
00249 typedef PropertyWrapper<tlp::BooleanProperty, bool> BooleanPropertyWrapper;
00250 typedef PropertyWrapper<tlp::ColorProperty, tlp::Color> ColorPropertyWrapper;
00251 typedef PropertyWrapper<tlp::StringProperty, std::string> StringPropertyWrapper;
00252 typedef PropertyWrapper<tlp::SizeProperty, tlp::Size> SizePropertyWrapper;
00253 typedef ComplexPropertyWrapper<tlp::LayoutProperty, tlp::Coord, tlp::LineType> LayoutPropertyWrapper;
00254 
00255 #endif // PROPERTYWRAPPER_H
 All Classes Files Functions Variables Enumerations Enumerator Properties