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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
|
/*
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 Argument.hpp
*
* Contains the declaration of the Argument and Arguments classes which are used
* to define the list of Arguments that can be passed to a Method or the set
* of attributes that are attached to an XML node or similar.
*
* The Argument and Arguments classes have some ressemblance to the Attribute
* and StructType types, however the classes defined here have been built to
* represent types which are known at compile time, whereas Attribute and
* StructType represent types defined at runtime by the user.
*
* @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de)
*/
#ifndef _OUSIA_ARGUMENT_HPP_
#define _OUSIA_ARGUMENT_HPP_
#include <initializer_list>
#include <vector>
#include <unordered_map>
#include "Variant.hpp"
namespace ousia {
// Forward declaration
class Logger;
class RttiType;
/**
* The Argument class represents a single argument that can be passed to a
* function.
*/
class Argument {
private:
/**
* Type that should be returned by the Variant rttiType function.
*/
const RttiType &type;
/**
* Describes the inner type of the variant -- e.g. the type of the elements
* inside an array. Normally set to RttiType::None.
*/
const RttiType &innerType;
/**
* Private constructor used for manually setting all internal data fields.
*
* @param name is the name of the Argument.
* @param variantType is the variant type of the argument that is to be
* expected.
* @param rttiType is the rttiType of the argument. Only used it the type
* of the variant is an object.
* @param defaultValue is the default value to be used.
* @param hasDefault indicates whether the defaultValue actually should be
* used.
*/
Argument(std::string name, const RttiType &type, const RttiType &innerType,
Variant defaultValue, bool hasDefault);
/**
* Private constructor used to build an argument describing a primitive type
* with default value.
*
* @param name is the name of the Argument.
* @param variantType is the variant type of the argument that is to be
* expected.
* @param defaultValue is the default value to be used.
*/
Argument(std::string name, const RttiType &type, Variant defaultValue);
/**
* Private constructor used to build an argument describing a primitive type
* without default value.
*
* @param name is the name of the Argument.
* @param variantType is the variant type of the argument that is to be
* expected.
*/
Argument(std::string name, const RttiType &type);
public:
/**
* Contains the name of the argument. Used for logging and in case the
* arguments are presented as map.
*/
const std::string name;
/**
* Default value. Note that a value of nullptr does not indicate that no
* default value has been set. Use the "hasDefault" flag for this purpose.
* Nullptr is a valid value for objects.
*/
const Variant defaultValue;
/**
* True if a default value is set, false otherwise.
*/
const bool hasDefault;
/**
* Named constructor for a boolean argument with no default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @return a new Argument instance.
*/
static Argument Bool(std::string name);
/**
* Named constructor for a boolean argument with default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param defaultValue is the default value to be used in case this argument
* is not supplied.
* @return a new Argument instance.
*/
static Argument Bool(std::string name, Variant::boolType defaultValue);
/**
* Named constructor for an integer argument with no default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @return a new Argument instance.
*/
static Argument Int(std::string name);
/**
* Named constructor for an integer argument with default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param defaultValue is the default value to be used in case this argument
* is not supplied.
* @return a new Argument instance.
*/
static Argument Int(std::string name, Variant::intType defaultValue);
/**
* Named constructor for a double argument with no default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @return a new Argument instance.
*/
static Argument Double(std::string name);
/**
* Named constructor for a double argument with default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param defaultValue is the default value to be used in case this argument
* is not supplied.
* @return a new Argument instance.
*/
static Argument Double(std::string name, Variant::doubleType defaultValue);
/**
* Named constructor for a string argument with no default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @return a new Argument instance.
*/
static Argument String(std::string name);
/**
* Named constructor for a string argument with default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param defaultValue is the default value to be used in case this argument
* is not supplied.
* @return a new Argument instance.
*/
static Argument String(std::string name,
const Variant::stringType &defaultValue);
/**
* Named constructor for an object argument with no default value. Object
* arguments always point at an instance of the Managed class. The concrete
* Object type must be specified in the "type" argument.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param type is the RttiType of acceptable objects. All objects where the
* "isa" function returns true for the given type are be accepted.
* @return a new Argument instance.
*/
static Argument Object(std::string name, const RttiType &type);
/**
* Named constructor for an object argument with default value. The default
* value can only be nullptr. Object arguments always point at an instance
* of the Managed class. The concrete Object type must be specified in the
* "type" argument.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param type is the RttiType of acceptable objects. All objects where the
* "isa" function returns true for the given type are be accepted.
* @return a new Argument instance.
*/
static Argument Object(std::string name, const RttiType &type,
std::nullptr_t defaultValue);
/**
* Named constructor for a function argument with no default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @return a new Argument instance.
*/
static Argument Function(std::string name);
/**
* Named constructor for a function argument with default value.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param defaultValue is the default value to be used in case this argument
* is not supplied.
* @return a new Argument instance.
*/
static Argument Function(std::string name,
Variant::functionType defaultValue);
/**
* Named constructor for an integer argument with no default and no specific
* inner type.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @return a new Argument instance.
*/
static Argument Array(std::string name);
/**
* Named constructor for an array argument with default value and no
* specific inner type.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param defaultValue is the default value to be used in case this argument
* is not supplied.
* @return a new Argument instance.
*/
static Argument Array(std::string name,
const Variant::arrayType &defaultValue);
/**
* Named constructor for an array argument of objects of the given RTTI
* type.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param innerType is the inner type of the array. All array elements are
* forced to be of this type.
* @return a new Argument instance.
*/
static Argument Array(std::string name, const RttiType &innerType);
/**
* Named constructor for an array argument of objects of the given RTTI
* type.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param innerType is the inner type of the array. All array elements are
* forced to be of this type.
* @return a new Argument instance.
* @param defaultValue is the default value to be used in case this argument
* is not supplied.
*/
static Argument Array(std::string name, const RttiType &innerType,
const Variant::arrayType &defaultValue);
/**
* Named constructor for a map argument with no default value and no
* specific inner type.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @return a new Argument instance.
*/
static Argument Map(std::string name);
/**
* Named constructor for a map argument with default value and no specific
* inner type.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param defaultValue is the default value to be used in case this argument
* is not supplied.
* @return a new Argument instance.
*/
static Argument Map(std::string name, const Variant::mapType &defaultValue);
/**
* Named constructor for a map argument with no default value and a given
* inner type.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param innerType is the inner type of the map. All map entries are forced
* to be of this type.
* @return a new Argument instance.
*/
static Argument Map(std::string name, const RttiType &innerType);
/**
* Named constructor for a map argument with default value and a given inner
* type.
*
* @param name is the name of the argument as used for error messages and in
* case the arguments are given as a map.
* @param innerType is the inner type of the map. All map entries are forced
* to be of this type.
* @param defaultValue is the default value to be used in case this argument
* is not supplied.
* @return a new Argument instance.
*/
static Argument Map(std::string name, const RttiType &innerType,
const Variant::mapType &defaultValue);
/**
* Makes sure the given variant is in the requested format and returns true
* if the variant was valid. Logs any error to the given logger instance.
* In case the validation was not successful, but the Argument instance was
* given an default value, the variant is set to that default value. If no
* default value was given, the variant is set to a valid value of the
* requested type.
*
* @param var is the variant that should be verified and transformed to
* match the argument specification.
* @param logger is the logger instance to which errors should be written.
* @return true if the given variant was valid, false otherwise.
*/
bool validate(Variant &var, Logger &logger);
};
/**
* The Arguments class represents a list of Argument instances and allows to
* either compare an array or a map of Variant instances against this argument
* list.
*/
class Arguments {
private:
/**
* List storing all arguments this instance consists of.
*/
std::vector<Argument> arguments;
/**
* Map containing all used argument names.
*/
std::unordered_map<std::string, size_t> names;
public:
/**
* Constructor of the Arguments class from a list of Argument instances.
*
* @param arguments is a list of Argument instances with which the Arguments
* instance should be initialized.
*/
Arguments(std::initializer_list<Argument> arguments);
/**
* Checks whether the content of the given variant array matches the
* argument list stored in this Arguments instance. Any ommited default
* arguments are added to the array.
*
* @param arr is the variant array that should be validated. The array is
* extended by all missing default values. The resulting array is ensured to
* be of the correct length and all entries to be of the correct type, even
* if validation errors occured (to facilitate graceful degradation).
* @param logger is the logger instance to which error messages or warnings
* will be written.
* @return true if the operation was successful, false if an error occured.
*/
bool validateArray(Variant::arrayType &arr, Logger &logger);
/**
* Checks whether the content of the given variant map matches the
* argument list stored in this Arguments instance. Any ommited default
* arguments are added to the map.
*
* @param map is the variant map that should be validated. The map is
* extended by all missing default values. The resulting map is ensured to
* be of the correct length and all entries to be of the correct type, even
* if validation errors occured (to facilitate graceful degradation).
* @param logger is the logger instance to which error messages or warnings
* will be written.
* @param ignoreUnknown if set to true, unknown map entries are ignored
* (a note is issued). This behaviour can be usefull if forward
* compatibility must be achieved (such as for XML based formats).
* @return true if the operation was successful, false if an error occured.
*/
bool validateMap(Variant::mapType &map, Logger &logger,
bool ignoreUnknown = false);
};
}
#endif /* _OUSIA_ARGUMENT_HPP_ */
|