Tulip 5.7.1
Large graphs analysis and drawing
Loading...
Searching...
No Matches
DataSet.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
20#ifndef _TULIPREFLECT
21#define _TULIPREFLECT
22
23#include <unordered_map>
24#include <tulip/tulipconf.h>
25#include <tulip/StlIterator.h>
26
27#include <string>
28#include <sstream>
29#include <typeinfo>
30#include <list>
31
32namespace tlp {
33
34class Graph;
35
36///@cond DOXYGEN_HIDDEN
37// basic interface to embed a data of any type
38struct TLP_SCOPE DataMem {
39 DataMem() {}
40 virtual ~DataMem() {}
41};
42
43// basic template to embed a value of a known type
44template <typename TYPE>
45struct TypedValueContainer : public DataMem {
46 TYPE value;
47 TypedValueContainer() {}
48 TypedValueContainer(const TYPE &val) : value(val) {}
49 ~TypedValueContainer() override {}
50};
51///@endcond
52
53/**
54 * @ingroup Structures
55 * @brief Describes a value of any type
56 */
57struct TLP_SCOPE DataType : public DataMem {
58 DataType() {}
59 DataType(void *value) : value(value) {}
60
61 /**
62 * @return A deep copy of the stored value.
63 */
64 virtual DataType *clone() const = 0;
65
66 /**
67 * @return The C++ typename of the stored element
68 */
69 virtual std::string getTypeName() const = 0;
70
71 /**
72 * @brief indicates if it is a Tulip property
73 */
74 static bool isTulipProperty(const std::string &typeName);
75
76 /**
77 * @brief indicates if it is a Tulip property
78 */
79 bool isTulipProperty() const {
80 return isTulipProperty(getTypeName());
81 }
82
83 /**
84 * @brief The actual pointer to the element's data
85 */
86 void *value;
87};
88
89///@cond DOXYGEN_HIDDEN
90// template class to embed value of known type
91template <typename T>
92struct TypedData : public DataType {
93 TypedData(void *value) : DataType(value) {}
94 ~TypedData() override {
95 delete static_cast<T *>(value);
96 }
97 DataType *clone() const override {
98 return new TypedData<T>(new T(getValue()));
99 }
100
101 std::string getTypeName() const override {
102 return std::string(typeid(T).name());
103 }
104
105 const T &getValue() const {
106 return *(static_cast<const T *>(this->value));
107 }
108};
109
110// forward declaration of DataSet
111class DataSet;
112
113// Basic class for serialization of DataType embedded value
114struct DataTypeSerializer {
115 // the readable type name the serializer is designed for
116 std::string outputTypeName;
117 // the current graph
118 Graph *graph;
119 DataTypeSerializer(const std::string &otn) : outputTypeName(otn), graph(nullptr) {}
120 virtual ~DataTypeSerializer() {}
121 // set the current graph if needed
122 void setGraph(Graph *g) {
123 graph = g;
124 }
125 // return a copy of this
126 virtual DataTypeSerializer *clone() const = 0;
127 // write the DataType embedded value into the output stream
128 virtual void writeData(std::ostream &os, const DataType *data) = 0;
129 // return the DataType embedded value as a std::string
130 virtual std::string toString(const DataType *data) {
131 std::stringstream ss;
132 writeData(ss, data);
133 return ss.str();
134 }
135 // build a DataType embedding value read from input stream
136 virtual DataType *readData(std::istream &is) = 0;
137 // set a value into a DataSet
138 virtual bool setData(DataSet &ds, const std::string &prop, const std::string &value) = 0;
139};
140
141// a template class designs to simplify the developer's work
142// when writing a serializer class
143template <typename T>
144struct TypedDataSerializer : public DataTypeSerializer {
145 TypedDataSerializer(const std::string &otn) : DataTypeSerializer(otn) {}
146 // declare new serialization virtual functions
147 virtual void write(std::ostream &os, const T &value) = 0;
148 // return true if the read of value succeeded, false if not
149 virtual bool read(std::istream &is, T &value) = 0;
150 // define virtually inherited functions using the previous ones
151 void writeData(std::ostream &os, const DataType *data) override {
152 write(os, *(static_cast<T *>(data->value)));
153 }
154 DataType *readData(std::istream &is) override {
155 T value;
156 bool ok = read(is, value);
157
158 if (ok)
159 return new TypedData<T>(new T(value));
160
161 return nullptr;
162 }
163 // set a value into a DataSet
164 bool setData(DataSet &ds, const std::string &prop, const std::string &value) override = 0;
165};
166
167// This class is there to ensure the destruction of DataTypeSerializer objects
168// when program ends
169class DataTypeSerializerContainer {
170
171public:
172 ~DataTypeSerializerContainer() {
173 std::unordered_map<std::string, DataTypeSerializer *>::iterator it = tnTodts.begin();
174
175 for (; it != tnTodts.end(); ++it) {
176 delete it->second;
177 }
178 }
179
180 std::unordered_map<std::string, DataTypeSerializer *> tnTodts;
181 std::unordered_map<std::string, DataTypeSerializer *> otnTodts;
182};
183///@endcond
184
185/**
186 * @ingroup Structures
187 * @brief A container that can store data from any type.
188 *
189 * The DataSet aggregate data of various types into a single structure and map each value to a key
190 *(std::string) describing its name.
191 * DataSet is mainly used in plugins. When creating a plugin, one can add input parameters (using
192 *tlp::WithParameter methods) and retrieve them from the dataSet member variable once they have been
193 *set by the user.
194 **/
195class TLP_SCOPE DataSet {
196 // Internal list of key-value pairs.
197 std::list<std::pair<std::string, DataType *>> data;
198
199 // list of deprecated properties
200 std::list<std::pair<std::string, std::string>> *deprecated;
201 // add a deprecated property name for compatibility management
202 void addDeprecated(const std::string &oldName, const std::string &usedName);
203 // return the property to be used
204 const std::string &getUsedName(const std::string &oldName) const;
205
206 /* management of data serialization
207 two hashmap to retrieve data serializer from their
208 type names and output type names
209 tnTodsts => typename to data type serializer
210 otnTodts => output type name to data type serializer */
211 static DataTypeSerializerContainer serializerContainer;
212 static void registerDataTypeSerializer(const std::string &typeName, DataTypeSerializer *dts);
213
214public:
215 DataSet() : deprecated(nullptr) {}
216 DataSet(const DataSet &set);
217 ~DataSet();
218
219 /**
220 * @brief Performs a deep copy of a DataSet into another
221 */
223
224 /**
225 * @brief Returns the stored value associated with the given key.
226 * The stored value is a copy of the original value that was set.
227 * If there is no value associated with the given key, the input value is left untouched.
228 *
229 * @param key The key with which the data we want to retrieve is associated.
230 * @param value A variable which will be overwritten with the value to retrieve.
231 * @return bool Whether there is a value associated with given key or not.
232 **/
233 template <typename T>
234 bool get(const std::string &key, T &value) const;
235
236 /**
237 * @brief Returns the stored value associated with the given key or the deprecated version of the
238 *key The stored value is a copy of the original value that was set. If there is no value
239 *associated with both keys, the input value is left untouched.
240 *
241 * @param key The key with which the data we want to retrieve is associated.
242 * @param oldKey The deprecated version of the key.
243 * @param value A variable which will be overwritten with the value to retrieve.
244 * @return bool Whether there is a value associated with one of the keys or not.
245 **/
246 template <typename T>
247 bool getDeprecated(const std::string &key, const std::string &oldKey, T &value) const;
248
249 /**
250 * @brief Returns the stored value, and deletes the stored copy.
251 * If no value is found, nothing is deleted.
252 *
253 * @param key The key with which the data we want to retrieve is associated.
254 * @param value A variable which will be overwritten with the value to retrieve.
255 * @return bool Whether there is a value associated with given key or not.
256 **/
257 template <typename T>
258 bool getAndFree(const std::string &key, T &value);
259
260 /**
261 * @brief Stores a copy of the given param, associated with the key.
262 * The value must have a well-formed copy constructor.
263 *
264 * @param key The key which can be used to retrieve the data.
265 * @param value The data to store.
266 * @return void
267 **/
268 template <typename T>
269 void set(const std::string &key, const T &value);
270
271 /**
272 * @brief Stores a copy of the given param, associated with a key and a deprected version of the
273 *key The value must have a well-formed copy constructor.
274 *
275 * @param key The key which can be used to retrieve the data.
276 * @param oldKey The deprecated version of the key.
277 * @param value The data to store.
278 * @return void
279 **/
280 template <typename T>
281 void setDeprecated(const std::string &key, const std::string &deprecatedKey, const T &value);
282
283 /**
284 * @brief Returns the mangled name of a type.
285 *.
286 * @return std::string the mangled name (typeid(T).name())
287 **/
288 template <typename T>
289 std::string getTypeName() const {
290 return std::string(typeid(T).name());
291 }
292
293 /**
294 * @brief Registers a serializer for a known type
295 *
296 * Serializers are used to write/read from std::ostream objects when saving DataSet instances.
297 */
298 template <typename T>
299 static void registerDataTypeSerializer(const DataTypeSerializer &serializer) {
300 registerDataTypeSerializer(std::string(typeid(T).name()), serializer.clone());
301 }
302
303 /**
304 * @brief write an embedded value
305 */
306 void writeData(std::ostream &os, const std::string &prop, const DataType *dt) const;
307
308 /**
309 * @brief Serializes a DataSet into a stream
310 */
311 static void write(std::ostream &os, const DataSet &ds);
312
313 /**
314 * @brief Read a value and stores it into the specified type
315 */
316 bool readData(std::istream &is, const std::string &prop, const std::string &outputTypeName);
317
318 /**
319 * @brief Reads a stream and stores its contents into a DataSet
320 */
321 static bool read(std::istream &is, DataSet &ds);
322
323 /**
324 * @param str the name of the member to look for
325 * @return true if str exists into the DataSet.
326 */
327 bool exists(const std::string &str) const;
328
329 /**
330 * @param str the name of the member to look for
331 * @return the mangled name of the type if str exists into the DataSet. An empty string if not.
332 */
333 std::string getTypeName(const std::string &str) const;
334
335 /**
336 * @brief Removes an element from the DataSet
337 * @param str the name of the element to remove
338 */
339 void remove(const std::string &str);
340
341 /**
342 * @param str The name of the element to retrieve
343 * @return A untyped value for a given element name. nullptr if the element does not exist
344 */
345 DataType *getData(const std::string &str) const;
346
347 /**
348 * @brief Set from an untyped value
349 */
350 void setData(const std::string &str, const DataType *value);
351
352 /**
353 * @return An iterator over stored values as a std::pair name => untyped value
354 */
356
357 /**
358 * @brief Returns the number of registered values
359 */
360 unsigned int size() const;
361
362 /**
363 * @brief Indicates whether the set is empty of not
364 */
365 bool empty() const;
366
367 /**
368 * @return the data type serializer associated to the given typename. nullptr if no serializer is
369 * found
370 */
371 static DataTypeSerializer *typenameToSerializer(const std::string &name);
372
373 /**
374 * @return A std::string representation of a DataSet
375 */
376 std::string toString() const;
377};
378} // namespace tlp
379
380#include "cxx/DataSet.cxx"
381
382#endif
A container that can store data from any type.
Definition: DataSet.h:195
void writeData(std::ostream &os, const std::string &prop, const DataType *dt) const
write an embedded value
bool empty() const
Indicates whether the set is empty of not.
std::string getTypeName(const std::string &str) const
void remove(const std::string &str)
Removes an element from the DataSet.
unsigned int size() const
Returns the number of registered values.
static void registerDataTypeSerializer(const DataTypeSerializer &serializer)
Registers a serializer for a known type.
Definition: DataSet.h:299
bool exists(const std::string &str) const
bool readData(std::istream &is, const std::string &prop, const std::string &outputTypeName)
Read a value and stores it into the specified type.
tlp::Iterator< std::pair< std::string, DataType * > > * getValues() const
DataType * getData(const std::string &str) const
std::string getTypeName() const
Returns the mangled name of a type.
Definition: DataSet.h:289
static void write(std::ostream &os, const DataSet &ds)
Serializes a DataSet into a stream.
void setData(const std::string &str, const DataType *value)
Set from an untyped value.
DataSet & operator=(const DataSet &set)
Performs a deep copy of a DataSet into another.
std::string toString() const
static DataTypeSerializer * typenameToSerializer(const std::string &name)
static bool read(std::istream &is, DataSet &ds)
Reads a stream and stores its contents into a DataSet.
Describes a value of any type.
Definition: DataSet.h:57
bool isTulipProperty() const
indicates if it is a Tulip property
Definition: DataSet.h:79
static bool isTulipProperty(const std::string &typeName)
indicates if it is a Tulip property
virtual std::string getTypeName() const =0
void * value
The actual pointer to the element's data.
Definition: DataSet.h:86
virtual DataType * clone() const =0
Interface for Tulip iterators. Allows basic iteration operations only.
Definition: Iterator.h:74