![]() |
Tulip
4.6.0
Better Visualization Through Research
|
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 ///@cond DOXYGEN_HIDDEN 00020 00021 #ifndef VECTORGRAPHPROPERTY_H 00022 #define VECTORGRAPHPROPERTY_H 00023 #include <algorithm> 00024 00025 namespace tlp { 00026 class VectorGraph; 00027 /** 00028 * @brief Internal class to access to a stl::vector in VectorGraph 00029 * @warning never use that class 00030 */ 00031 class ValArrayInterface { 00032 friend class VectorGraph; 00033 protected: 00034 virtual void addElement(const unsigned int id) = 0; 00035 virtual void reserve(const size_t size) = 0; 00036 virtual ~ValArrayInterface() {} 00037 }; 00038 //=========================================== 00039 /** 00040 * @brief Internal class to access to a stl::vector in VectorGraph 00041 * @warning never use that class 00042 */ 00043 template <typename TYPE> 00044 class ValArray : public ValArrayInterface { 00045 friend class VectorGraph; 00046 protected: 00047 ValArray(const unsigned int size = 0, const unsigned int capacity = 0) { 00048 _data.reserve(capacity); 00049 _data.resize(size); 00050 } 00051 virtual ~ValArray() {} 00052 void addElement(const unsigned int id) { 00053 if (id >= _data.size()) { 00054 _data.resize(id); 00055 _data.push_back(TYPE()); 00056 } 00057 } 00058 void reserve(const size_t size) { 00059 _data.reserve(size); 00060 } 00061 00062 public: 00063 std::vector<TYPE> _data; /**< TODO */ 00064 }; 00065 /** 00066 * @class VectorGraphProperty 00067 * @brief That class enables to factorize code for NodeProperty and EdgeProperty in VectorGraph, it could not be used directly. 00068 * @see NodeProperty 00069 * @see EdgeProperty 00070 * @see VectorGraph 00071 */ 00072 template <typename TYPE> 00073 class VectorGraphProperty { 00074 friend class VectorGraph; 00075 public: 00076 /** 00077 * @brief read/write accessor 00078 * 00079 * return the value of the ith element and enables to modify it. 00080 */ 00081 typename std::vector<TYPE>::reference operator[](const size_t id) { 00082 //assert(isValid()); 00083 assert(id < (*_array)._data.size()); 00084 return (*_array)._data[id]; 00085 } 00086 /** 00087 * @brief read accessor 00088 * 00089 * return the value of the ith element. 00090 */ 00091 typename std::vector<TYPE>::const_reference operator[](const size_t id) const { 00092 //assert(isValid()); 00093 assert(id < (*_array)._data.size()); 00094 return (*_array)._data[id]; 00095 } 00096 /** 00097 * @bried Set all the value of the property to the value given in parameter 00098 * 00099 * That function affect the same value to all elements of the vector, there 00100 * is no effect on the future value added in the vector 00101 * @warning There is differences between the setAll of the MutableContainer and 00102 * the setAll of VectorProperty (NodeProperty or EdgeProperty). The MutableContainer, 00103 * ensures that new inserted element will have the value given by the last setAll 00104 * 00105 * @see MutableContainer 00106 */ 00107 void setAll(const TYPE &obj) { 00108 fill(_array->_data.begin(), _array->_data.end(), obj); 00109 } 00110 /** 00111 * @brief write accessor 00112 * 00113 * change the value of the ith element. 00114 */ 00115 void set(const size_t id, const TYPE &obj) { 00116 (*this)[id] = obj; 00117 } 00118 /** 00119 * @brief read accessor 00120 * 00121 * return the value of the ith element. 00122 */ 00123 typename std::vector<TYPE>::const_reference get(const size_t id) const { 00124 return (*this)[id]; 00125 } 00126 #ifndef NDEBUG 00127 virtual bool isValid() const = 0; 00128 #endif 00129 00130 protected: 00131 VectorGraphProperty():_array(0), _graph(0) { 00132 } 00133 VectorGraphProperty(const VectorGraphProperty &obj): _array(obj._array), _graph(obj._graph) { 00134 } 00135 VectorGraphProperty(ValArray<TYPE> *array, VectorGraph *graph):_array(array), _graph(graph) { 00136 } 00137 protected: 00138 ValArray<TYPE> *_array; /**< TODO */ 00139 VectorGraph *_graph; /**< TODO */ 00140 }; 00141 00142 /** 00143 * @class EdgeProperty 00144 * @brief That class enables to define a property/attribute on edges on a VectorGraph. 00145 * 00146 * Using EdgeProperty you can assign any kind of attribute to edges. To use that class 00147 * you must first create an instance of EdgeProperty and then connect it to your graph. 00148 * NodeProperty can be copied in another EdgeProperty, however the to NodeProperty will 00149 * share the same content. You can consider that EdgeProperty is just a pointer on a stl:vector. 00150 * to free memory used by a EdgeProperty connected to a graph you must use the free function. 00151 * @warning After the call to free all The copy of the orignal EdgeProperty are no more valid 00152 * 00153 * Using EdgeProperty you can store and access to values with the same efficiency as if 00154 * you created manually a vector. EdgeProperty manage for you the resize, etc... when the 00155 * graph is modified. 00156 * 00157 * Furthemrore, in DEBUG mode, operator[] check if one try to access outside of the Array Bound. 00158 * in DEBUG mode, the validy of the Property is also checked (if it has been free/alloc etc...) 00159 * 00160 * @code 00161 * VectorGraph g; 00162 * EdgeProperty<double> weight; 00163 * g.alloc(weight); //connect weight to g, g allocate memory for that attribute 00164 * edge e; 00165 * forEach(e, g.getEdges()) { 00166 * weight[n] = g.deg(g.target(e)) + g.deg(g.source(e)); 00167 * } 00168 * EdgeProperty<double> weight2 = weight; //weight2 and weight are pointing on the same memory addres 00169 * weight2[g[0]] = 3; 00170 * tlp::debug() << weight[g[0]]; //output 3 00171 * g.free(weight2); //free the memory, weight and weight2 are no more valid. 00172 * @endcode 00173 * @see VectorGraph alloc(EdgeProperty) 00174 * @see VectorGraph free(EdgeProperty) 00175 * @see VectorGraph 00176 */ 00177 template <typename TYPE> 00178 class EdgeProperty : public VectorGraphProperty<TYPE> { 00179 friend class VectorGraph; 00180 public: 00181 EdgeProperty():VectorGraphProperty<TYPE>() {} 00182 EdgeProperty(const EdgeProperty &obj): VectorGraphProperty<TYPE>(obj) {} 00183 #ifndef NDEBUG 00184 bool isValid() const; 00185 #endif 00186 00187 private: 00188 EdgeProperty(ValArray<TYPE> *array, VectorGraph *graph):VectorGraphProperty<TYPE>(array, graph) {} 00189 00190 }; 00191 /** 00192 * @class NodeProperty 00193 * @brief That class enables to define a property/attribute on nodes on a VectorGraph. 00194 * 00195 * Using NodeProperty you can assign any kind of attribute to nodes. To use that class 00196 * you must first create an instance of NodeProperty and then connect it to your graph. 00197 * NodeProperty can be copied in another NodeProperty, however the to NodeProperty will 00198 * share the same content. You can consider that NodeProperty is just a pointer on a stl:vector. 00199 * to free memory used by a NodeProperty connected to a graph you must use the free function. 00200 * @warning After the call to free all The copy of the orignal NodeProperty are no more valid 00201 * 00202 * Using NodeProperty you can store and access to values with the same efficiency as if 00203 * you created manually a vector. NodeProperty manage for you the resize, etc... when the 00204 * graph is modified. 00205 * 00206 * Furthemrore, in DEBUG mode, operator[] check if one try to access outside of the Array Bound. 00207 * in DEBUG mode, the validy of the Property is also checked (if it has been free/alloc etc...) 00208 * 00209 * @code 00210 * VectorGraph g; 00211 * NodeProperty<double> weight; 00212 * g.alloc(weight); //connect weight to g, g allocate memory for that attribute 00213 * node n; 00214 * forEach(n, g.getNodes()) { 00215 * weight[n] = g.deg(n); 00216 * } 00217 * NodeProperty<double> weight2 = weight; //weight2 and weight are pointing on the same memory addres 00218 * weight2[g[0]] = 3; 00219 * tlp::debug() << weight[g[0]]; //output 3 00220 * g.free(weight2); //free the memory, weight and weight2 are no more valid. 00221 * @endcode 00222 * @see VectorGraph alloc(NodeProperty) 00223 * @see VectorGraph free(NodeProperty) 00224 */ 00225 template <typename TYPE> 00226 class NodeProperty : public VectorGraphProperty<TYPE> { 00227 friend class VectorGraph; 00228 public: 00229 NodeProperty():VectorGraphProperty<TYPE>() {} 00230 NodeProperty(const NodeProperty &obj): VectorGraphProperty<TYPE>(obj) {} 00231 #ifndef NDEBUG 00232 bool isValid() const; 00233 #endif 00234 00235 private: 00236 NodeProperty(ValArray<TYPE> *array, VectorGraph *graph):VectorGraphProperty<TYPE>(array, graph) {} 00237 }; 00238 00239 } 00240 #endif // VECTORGRAPHPROPERTY_H 00241 ///@endcond