1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
|
/*
Ousía
Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file VariantConverter.hpp
*
* Contains the VariantConverter class which contains code commonly used by
* the Variant, Typesystem and Argument classes to cast Variants to other
* Variant types.
*
* @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de)
*/
#ifndef _OUSIA_VARIANT_CONVERTER_HPP_
#define _OUSIA_VARIANT_CONVERTER_HPP_
namespace ousia {
// Forward declaration
class Logger;
class Rtti;
class Variant;
/**
* The VariantConverter class is used to convert a variant to a certain
* prespecified type. The functions ensure that the variant has the requested
* type, even if the conversion fails.
*/
class VariantConverter {
public:
/**
* Enumeration used to define the mode of conversion -- either only safe
* conversions (without any data loss) are performed, or all possible
* conversions are tried (with possible data loss).
*/
enum class Mode {
/**
* Performs only lossless and sane conversions.
*/
SAFE,
/**
* Performs possibly lossy and probably unintuitive conversions.
*/
ALL
};
/**
* Converts the given variant to a boolean. If the "mode" parameter is set
* to Mode::SAFE, only booleans can be converted to booleans. For all other
* types the conversion fails. If "mode" is set to Mode::ALL, nullptr
* values and zero numeric values are treated as "false", all other values
* are treated as "true". If the conversion fails, false is returned as
* default value.
*
* @param var is instance of the Variant class that should be converted to
* the requested type.
* @param logger is a reference to the logger instance into which messages
* should be logged.
* @param mode is the conversion mode. See method description for the exact
* effect.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool toBool(Variant &var, Logger &logger, Mode mode = Mode::SAFE);
/**
* Converts the given variant to an integer. If the "mode" parameter is set
* to Mode::SAFE, only integers can be converted to integers. For all other
* types the conversion fails. If "mode" is set to Mode::ALL, booleans are
* converted to 0, 1, nullptr is converted to 0, doubles are truncated,
* strings are parsed and truncated, arrays and cardinalities with one
* element are converted to an integer. Conversion fails for objects,
* functions, maps and arrays with zero or more than one entry. If the
* conversion fails, 0 is returned as default value.
*
* @param var is instance of the Variant class that should be converted to
* the requested type.
* @param logger is a reference to the logger instance into which messages
* should be logged.
* @param mode is the conversion mode. See method description for the exact
* effect.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool toInt(Variant &var, Logger &logger, Mode mode = Mode::SAFE);
/**
* Converts the given variant to a double. If the "mode" parameter is set
* to Mode::SAFE, only integers and doubles can be converted to doubles. For
* all other types the conversion fails. If "mode" is set to Mode::ALL,
* booleans are converted to 0.0, 1.0, nullptr is converted to 0.0, strings
* are parsed, arrays and cardinalities with one element are converted to a
* double.
* Conversion fails for objects, functions, maps and arrays with zero or
* more than one entry. If the conversion fails, 0.0 is returned as default
* value.
*
* @param var is instance of the Variant class that should be converted to
* the requested type.
* @param logger is a reference to the logger instance into which messages
* should be logged.
* @param mode is the conversion mode. See method description for the exact
* effect.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool toDouble(Variant &var, Logger &logger, Mode mode = Mode::SAFE);
/**
* Converts the given variant to a string. If the "mode" parameter is set
* to Mode::SAFE, all primitive types can be converted to strings. For
* all other types the conversion fails. If "mode" is set to Mode::ALL,
* maps and arrays are converted to a JSON representation, cardinalities
* to their parsing syntax and objects and functions are converted to an
* informative string containing their pointer and type. If the conversion
* fails, an empty string is returned as default value.
*
* @param var is instance of the Variant class that should be converted to
* the requested type.
* @param logger is a reference to the logger instance into which messages
* should be logged.
* @param mode is the conversion mode. See method description for the exact
* effect.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool toString(Variant &var, Logger &logger, Mode mode = Mode::SAFE);
/**
* Converts the given variant to an array with the given inner type. If the
* "mode" parameter is set to Mode::SAFE, the given variant must be an
* array, If mode is set to Mode::ALL, other variant values are encapsulated
* in array with one entry. In both cases, if "innerType" points at a
* primitive Rtti type, conversion to that type is tried (using the
* specified conversion mode).
*
* @param var is instance of the Variant class that should be converted to
* the requested type.
* @param innerType is the inner type of the array entries. Should be set to
* RttiTypes::None in case the inner type of the array does not matter.
* @param logger is a reference to the logger instance into which messages
* should be logged.
* @param mode is the conversion mode. See method description for the exact
* effect.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool toArray(Variant &var, const Rtti &innerType, Logger &logger,
Mode mode = Mode::SAFE);
/**
* Converts the given variant to an map with the given inner type. The given
* variant must be a map. If "innerType" points at a primitive Rtti type,
* conversion to that type is tried with the specified conversion mode.
*
* @param var is instance of the Variant class that should be converted to
* the requested type.
* @param innerType is the inner type of the map entries. Should be set to
* RttiTypes::None in case the inner type of the map does not matter.
* @param logger is a reference to the logger instance into which messages
* should be logged.
* @param mode is the conversion mode used for converting the entries of the
* map to the inner type.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool toMap(Variant &var, const Rtti &innerType, Logger &logger,
Mode mode = Mode::SAFE);
/**
* Converts the given variant to a cardinality. If the "mode" parameter is
* set to Mode::SAFE, only integers are converted to a cardinality with
* exactly that elment. If mode is set to Mode::ALL, the conversion gets
* more creative:
*
* * NULLPTR is converted to an empty cardinality that accepts nothing
* * BOOL is converted to either that empty cardinality (false) or to a
* cardinality accepting everything (true).
* * DOUBLE gets rounded to the next integer and then converted.
* * STRING gets parsed as a cardinality using the VariantReader.
* * ARRAY (of ints) is interpreted as ranges with interleaving start and
* end notation.
*
* Other converstions are not made. If the conversion was not possible, an
* empty cardinality is returned.
*
* @param var is instance of the Variant class that should be converted to
* the requested type.
* @param logger is a reference to the logger instance into which messages
* should be logged.
* @param mode is the conversion mode. See method description for the exact
* effect.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool toCardinality(Variant &var, Logger &logger,
Mode mode = Mode::SAFE);
/**
* Makes sure the given variant is a function. If it is not, it is replaced
* by a dummy function which takes no arguments and returns nullptr.
*
* @param var is the variant that should be converted to a function.
* @param logger is the logger to which error messages should be written.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool toFunction(Variant &var, Logger &logger);
/**
* Tries conversion to the given Rtti with the given optional inner
* type.
*
* @param type describes the type to which the variant should be converted.
* This might either be a variant type such as RttiTypes::Bool,
* RttiTypes::Int, RttiTypes::Double, RttiTypes::String, RttiTypes::Array,
* RttiTypes::Map or RttiTypes::Function. All other types are regarded as
* managed object of this type. If RttiTypes::None is given, all types are
* accepted.
* @param innerType is used in case of maps or arrays to check the type of
* the elements of these containers. If RttiTypes::None is given, no special
* type is required.
* @param logger is a reference at the logger instance to which error
* messages are forwarded.
* @param mode is the conversion mode that is being enforced.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool convert(Variant &var, const Rtti &type, const Rtti &innerType,
Logger &logger, Mode mode = Mode::SAFE);
/**
* Tries conversion to the given Rtti without any enforcement regarding
* the inner type of container types.
*
* @param type describes the type to which the variant should be converted.
* This might either be a variant type such as RttiTypes::Bool,
* RttiTypes::Int, RttiTypes::Double, RttiTypes::String, RttiTypes::Array,
* RttiTypes::Map or RttiTypes::Function. All other types are regarded as
* managed object of this type. If RttiTypes::None is given, all types are
* accepted.
* @param logger is a reference at the logger instance to which error
* messages are forwarded.
* @param mode is the conversion mode that is being enforced.
* @return true if the operation was successful, false otherwise. In any
* case the input/output parameter "var" will have the requested type.
*/
static bool convert(Variant &var, const Rtti &type, Logger &logger,
Mode mode = Mode::SAFE);
};
}
#endif /* _OUSIA_VARIANT_CONVERTER_HPP_ */
|