cdynamicdescriptor.h Source File¶

API: cdynamicdescriptor.h Source File
API
cdynamicdescriptor.h
1//==========================================================================
2// CDYNAMICDESCRIPTOR.H - part of
3// OMNeT++/OMNEST
4// Discrete System Simulation in C++
5//
6//==========================================================================
7
8/*--------------------------------------------------------------*
9 Copyright (C) 1992-2017 Andras Varga
10 Copyright (C) 2006-2017 OpenSim Ltd.
11
12 This file is distributed WITHOUT ANY WARRANTY. See the file
13 `license' for details on this and other legal matters.
14*--------------------------------------------------------------*/
15
16#ifndef __OMNETPP_CDYNAMICDESCRIPTOR_H
17#define __OMNETPP_CDYNAMICDESCRIPTOR_H
18
19#include <iostream>
20#include <sstream>
21#include <vector>
22#include <list>
23#include <set>
24#include <map>
25#include <unordered_map>
26#include <utility>
27#include <type_traits>
28#include "cclassdescriptor.h"
29#include "simutil.h"
30#include "globals.h"
31
32namespace omnetpp {
33
34namespace internal {
35
36// --- Type traits ---
37
38template<typename T, typename = void>
39struct is_printable : std::false_type {};
40template<typename T>
41struct is_printable<T, std::void_t<decltype(std::declval<std::ostream&>() << std::declval<const T&>())>> : std::true_type {};
42
43template<typename T, typename = void>
44struct is_extractable : std::false_type {};
45template<typename T>
46struct is_extractable<T, std::void_t<decltype(std::declval<std::istream&>() >> std::declval<T&>())>> : std::true_type {};
47
48template<typename T> struct is_std_vector : std::false_type {};
49template<typename E, typename A> struct is_std_vector<std::vector<E,A>> : std::true_type {};
50
51template<typename T> struct is_std_list : std::false_type {};
52template<typename E, typename A> struct is_std_list<std::list<E,A>> : std::true_type {};
53
54template<typename T> struct is_std_set : std::false_type {};
55template<typename E, typename C, typename A> struct is_std_set<std::set<E,C,A>> : std::true_type {};
56
57template<typename T> struct is_std_map : std::false_type {};
58template<typename K, typename V, typename C, typename A> struct is_std_map<std::map<K,V,C,A>> : std::true_type {};
59
60template<typename T> struct is_std_unordered_map : std::false_type {};
61template<typename K, typename V, typename H, typename E, typename A> struct is_std_unordered_map<std::unordered_map<K,V,H,E,A>> : std::true_type {};
62
63template<typename T> struct is_std_pair : std::false_type {};
64template<typename F, typename S> struct is_std_pair<std::pair<F,S>> : std::true_type {};
65
66// Returns a human-readable type name for T. For std::vector<E>, constructs
67// "std::vector<elemtype>" instead of relying on opp_typename which may lose
68// template parameters.
69template<typename T>
70std::string getTypeName() {
71 if constexpr (is_std_vector<T>::value) {
72 using E = typename T::value_type;
73 return std::string("std::vector<") + getTypeName<E>() + ">";
74 }
75 else if constexpr (is_std_list<T>::value) {
76 using E = typename T::value_type;
77 return std::string("std::list<") + getTypeName<E>() + ">";
78 }
79 else if constexpr (is_std_set<T>::value) {
80 using E = typename T::value_type;
81 return std::string("std::set<") + getTypeName<E>() + ">";
82 }
83 else if constexpr (is_std_map<T>::value) {
84 using K = typename T::key_type;
85 using V = typename T::mapped_type;
86 return std::string("std::map<") + getTypeName<K>() + "," + getTypeName<V>() + ">";
87 }
88 else if constexpr (is_std_unordered_map<T>::value) {
89 using K = typename T::key_type;
90 using V = typename T::mapped_type;
91 return std::string("std::unordered_map<") + getTypeName<K>() + "," + getTypeName<V>() + ">";
92 }
93 else if constexpr (is_std_pair<T>::value) {
94 using F = typename T::first_type;
95 using S = typename T::second_type;
96 return std::string("std::pair<") + getTypeName<F>() + "," + getTypeName<S>() + ">";
97 }
98 else {
99 return opp_typename(typeid(T));
100 }
101}
102
109class SIM_API cDynamicDescriptor : public cClassDescriptor
110{
111 public:
112 cDynamicDescriptor(const char *className, const char *baseClassName = nullptr);
113 virtual ~cDynamicDescriptor() {}
114
115 virtual const char **getPropertyNames() const override;
116 virtual const char *getProperty(const char *propertyName) const override;
117 virtual int getFieldCount() const override;
118 virtual const char *getFieldName(int field) const override;
119 virtual unsigned int getFieldTypeFlags(int field) const override;
120 virtual const char *getFieldTypeString(int field) const override;
121 virtual const char **getFieldPropertyNames(int field) const override;
122 virtual const char *getFieldProperty(int field, const char *propertyName) const override;
123 virtual int getFieldArraySize(any_ptr object, int field) const override;
124 virtual void setFieldArraySize(any_ptr object, int field, int size) const override;
125 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override;
126 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override;
127 virtual cValue getFieldValue(any_ptr object, int field, int i) const override;
128 virtual void setFieldValue(any_ptr object, int field, int i, const cValue& value) const override;
129 virtual const char *getFieldStructName(int field) const override;
130 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override;
131 virtual void setFieldStructValuePointer(any_ptr object, int field, int i, any_ptr ptr) const override;
132};
133
140template<typename T>
141class cPrimitiveTypeDescriptor : public cDynamicDescriptor
142{
143 public:
144 cPrimitiveTypeDescriptor(const char *typeName) : cDynamicDescriptor(typeName) {}
145
146 virtual std::string getValueAsString(any_ptr object) const override {
147 T *p = object.get<T>();
148 if constexpr (std::is_same_v<T, char> || std::is_same_v<T, signed char>) {
149 std::ostringstream os;
150 os << "'" << ((unsigned char)*p < 32 ? ' ' : (char)*p) << "' (" << (int)*p << ")";
151 return os.str();
152 }
153 else if constexpr (std::is_same_v<T, unsigned char>) {
154 std::ostringstream os;
155 os << "'" << (*p < ' ' ? ' ' : (char)*p) << "' (" << (unsigned)*p << ")";
156 return os.str();
157 }
158 else if constexpr (std::is_same_v<T, std::string>) {
159 std::ostringstream os;
160 os << "\"" << *p << "\"";
161 return os.str();
162 }
163 else if constexpr (is_printable<T>::value) {
164 std::ostringstream os;
165 os << *p;
166 return os.str();
167 }
168 return UNPRINTABLE;
169 }
170
171 virtual void setValueAsString(any_ptr object, const char *value) const override {
172 T *p = object.get<T>();
173 if constexpr (std::is_same_v<T, char> || std::is_same_v<T, signed char>) {
174 if (value[0] == '\'')
175 *p = value[1];
176 else
177 *p = (char)atoi(value);
178 }
179 else if constexpr (std::is_same_v<T, unsigned char>) {
180 if (value[0] == '\'')
181 *p = value[1];
182 else
183 *p = (unsigned char)atoi(value);
184 }
185 else if constexpr (std::is_same_v<T, std::string>) {
186 size_t len = strlen(value);
187 if (len >= 2 && value[0] == '"' && value[len-1] == '"')
188 *p = std::string(value + 1, len - 2);
189 else
190 *p = value;
191 }
192 else if constexpr (is_extractable<T>::value) {
193 std::istringstream is(value);
194 is >> *p;
195 }
196 else {
198 }
199 }
200};
201
208template<typename E>
209class cStdVectorDescriptor : public cDynamicDescriptor
210{
211 private:
212 std::string elemTypeName;
213 public:
214 cStdVectorDescriptor(const char *typeName)
215 : cDynamicDescriptor(typeName), elemTypeName(internal::getTypeName<std::remove_pointer_t<E>>()) {}
216
217 virtual std::string getValueAsString(any_ptr object) const override {
218 std::vector<E> *v = object.get<std::vector<E>>();
219 if (v->empty()) return "empty";
220 std::ostringstream os;
221 os << "size=" << v->size();
222 return os.str();
223 }
224
225 virtual int getFieldCount() const override { return 1; }
226
227 virtual const char *getFieldName(int field) const override {
228 return field == 0 ? "elements" : nullptr;
229 }
230
231 virtual unsigned int getFieldTypeFlags(int field) const override {
232 if (field != 0) return 0;
233 unsigned int flags = FD_ISARRAY;
234 if constexpr (std::is_pointer_v<E>) {
235 flags |= FD_ISPOINTER;
236 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>)
237 flags |= FD_ISCOMPOUND | FD_ISCOBJECT;
238 }
239 if (!(flags & FD_ISCOMPOUND)) {
240 cClassDescriptor *elemDesc = cClassDescriptor::getDescriptorFor(elemTypeName.c_str());
241 if (elemDesc) {
242 flags |= FD_ISCOMPOUND;
243 if (elemDesc->extendsCObject())
244 flags |= FD_ISCOBJECT;
245 }
246 }
247 return flags;
248 }
249
250 virtual const char *getFieldTypeString(int field) const override {
251 return field == 0 ? elemTypeName.c_str() : nullptr;
252 }
253
254 virtual int getFieldArraySize(any_ptr object, int field) const override {
255 if (field != 0) return 0;
256 std::vector<E> *v = object.get<std::vector<E>>();
257 return (int)v->size();
258 }
259
260 virtual void setFieldArraySize(any_ptr object, int field, int size) const override {
261 if (field != 0) { cDynamicDescriptor::setFieldArraySize(object, field, size); return; }
262 if constexpr (std::is_default_constructible_v<E>) {
263 std::vector<E> *v = object.get<std::vector<E>>();
264 v->resize(size);
265 }
266 else {
267 cDynamicDescriptor::setFieldArraySize(object, field, size);
268 }
269 }
270
271 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override {
272 if (field != 0) return "";
273 std::vector<E> *v = object.get<std::vector<E>>();
274 cClassDescriptor *elemDesc = cClassDescriptor::getDescriptorFor(elemTypeName.c_str());
275 if constexpr (std::is_pointer_v<E>) {
276 E ptr = (*v)[i];
277 if (!ptr) return "nullptr";
278 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>) {
279 cClassDescriptor *desc = static_cast<const cObject*>(ptr)->getDescriptor();
280 if (desc)
281 return desc->getValueAsString(toAnyPtr(static_cast<const cObject*>(ptr)));
282 }
283 else {
284 if (elemDesc)
285 return elemDesc->getValueAsString(any_ptr(ptr));
286 if constexpr (is_printable<std::remove_pointer_t<E>>::value) {
287 std::ostringstream os;
288 os << *ptr;
289 return os.str();
290 }
291 }
292 }
293 else {
294 if (elemDesc)
295 return elemDesc->getValueAsString(any_ptr(&(*v)[i]));
296 if constexpr (is_printable<E>::value) {
297 std::ostringstream os;
298 os << (*v)[i];
299 return os.str();
300 }
301 }
302 return UNPRINTABLE;
303 }
304
305 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override {
306 if (field != 0) { cDynamicDescriptor::setFieldValueAsString(object, field, i, value); return; }
307 std::vector<E> *v = object.get<std::vector<E>>();
308 cClassDescriptor *elemDesc = cClassDescriptor::getDescriptorFor(elemTypeName.c_str());
309 if constexpr (std::is_pointer_v<E>) {
310 E ptr = (*v)[i];
311 if (!ptr) return;
312 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>) {
313 cClassDescriptor *desc = static_cast<const cObject*>(ptr)->getDescriptor();
314 if (desc)
315 desc->setValueAsString(toAnyPtr(static_cast<const cObject*>(ptr)), value);
316 }
317 else {
318 if (elemDesc) {
319 elemDesc->setValueAsString(any_ptr(ptr), value);
320 return;
321 }
322 }
323 }
324 else {
325 if (elemDesc) {
326 elemDesc->setValueAsString(any_ptr(&(*v)[i]), value);
327 return;
328 }
329 if constexpr (is_extractable<E>::value) {
330 std::istringstream is(value);
331 is >> (*v)[i];
332 }
333 else {
334 cDynamicDescriptor::setFieldValueAsString(object, field, i, value);
335 }
336 }
337 }
338
339 virtual const char *getFieldStructName(int field) const override {
340 return field == 0 ? elemTypeName.c_str() : nullptr;
341 }
342
343 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override {
344 if (field != 0) return any_ptr(nullptr);
345 std::vector<E> *v = object.get<std::vector<E>>();
346 if constexpr (std::is_pointer_v<E>) {
347 E ptr = (*v)[i];
348 if (!ptr) return any_ptr(nullptr);
349 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>)
350 return toAnyPtr(static_cast<const cObject*>(ptr));
351 else
352 return any_ptr(ptr);
353 }
354 else {
355 return any_ptr(&(*v)[i]);
356 }
357 }
358};
359
366template<typename E>
367class cStdListDescriptor : public cDynamicDescriptor
368{
369 private:
370 std::string elemTypeName;
371
372 typename std::list<E>::iterator nthIt(std::list<E> *c, int i) const {
373 auto it = c->begin();
374 for (int k = 0; k < i && it != c->end(); k++) ++it;
375 return it;
376 }
377
378 public:
379 cStdListDescriptor(const char *typeName)
380 : cDynamicDescriptor(typeName), elemTypeName(internal::getTypeName<std::remove_pointer_t<E>>()) {}
381
382 virtual std::string getValueAsString(any_ptr object) const override {
383 auto *c = object.get<std::list<E>>();
384 if (c->empty()) return "empty";
385 std::ostringstream os;
386 os << "size=" << c->size();
387 return os.str();
388 }
389
390 virtual int getFieldCount() const override { return 1; }
391 virtual const char *getFieldName(int field) const override { return field == 0 ? "elements" : nullptr; }
392 virtual const char *getFieldTypeString(int field) const override { return field == 0 ? elemTypeName.c_str() : nullptr; }
393 virtual const char *getFieldStructName(int field) const override { return field == 0 ? elemTypeName.c_str() : nullptr; }
394
395 virtual unsigned int getFieldTypeFlags(int field) const override {
396 if (field != 0) return 0;
397 unsigned int flags = FD_ISARRAY;
398 if constexpr (std::is_pointer_v<E>) {
399 flags |= FD_ISPOINTER;
400 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>)
401 flags |= FD_ISCOMPOUND | FD_ISCOBJECT;
402 }
403 if (!(flags & FD_ISCOMPOUND)) {
404 cClassDescriptor *elemDesc = cClassDescriptor::getDescriptorFor(elemTypeName.c_str());
405 if (elemDesc) { flags |= FD_ISCOMPOUND; if (elemDesc->extendsCObject()) flags |= FD_ISCOBJECT; }
406 }
407 return flags;
408 }
409
410 virtual int getFieldArraySize(any_ptr object, int field) const override {
411 if (field != 0) return 0;
412 return (int)object.get<std::list<E>>()->size();
413 }
414
415 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override {
416 if (field != 0) return "";
417 auto *c = object.get<std::list<E>>();
418 auto it = nthIt(c, i);
419 if (it == c->end()) return "";
420 cClassDescriptor *elemDesc = cClassDescriptor::getDescriptorFor(elemTypeName.c_str());
421 if constexpr (std::is_pointer_v<E>) {
422 E ptr = *it;
423 if (!ptr) return "nullptr";
424 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>) {
425 cClassDescriptor *desc = static_cast<const cObject*>(ptr)->getDescriptor();
426 if (desc) return desc->getValueAsString(toAnyPtr(static_cast<const cObject*>(ptr)));
427 }
428 else {
429 if (elemDesc) return elemDesc->getValueAsString(any_ptr(ptr));
430 if constexpr (is_printable<std::remove_pointer_t<E>>::value) { std::ostringstream os; os << *ptr; return os.str(); }
431 }
432 }
433 else {
434 if (elemDesc) return elemDesc->getValueAsString(any_ptr(&(*it)));
435 if constexpr (is_printable<E>::value) { std::ostringstream os; os << *it; return os.str(); }
436 }
437 return UNPRINTABLE;
438 }
439
440 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override {
441 if (field != 0) { cDynamicDescriptor::setFieldValueAsString(object, field, i, value); return; }
442 auto *c = object.get<std::list<E>>();
443 auto it = nthIt(c, i);
444 if (it == c->end()) return;
445 cClassDescriptor *elemDesc = cClassDescriptor::getDescriptorFor(elemTypeName.c_str());
446 if constexpr (std::is_pointer_v<E>) {
447 E ptr = *it;
448 if (!ptr) return;
449 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>) {
450 cClassDescriptor *desc = static_cast<const cObject*>(ptr)->getDescriptor();
451 if (desc) desc->setValueAsString(toAnyPtr(static_cast<const cObject*>(ptr)), value);
452 }
453 else {
454 if (elemDesc) { elemDesc->setValueAsString(any_ptr(ptr), value); return; }
455 }
456 }
457 else {
458 if (elemDesc) { elemDesc->setValueAsString(any_ptr(&(*it)), value); return; }
459 if constexpr (is_extractable<E>::value) { std::istringstream is(value); is >> *it; }
460 else { cDynamicDescriptor::setFieldValueAsString(object, field, i, value); }
461 }
462 }
463
464 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override {
465 if (field != 0) return any_ptr(nullptr);
466 auto *c = object.get<std::list<E>>();
467 auto it = nthIt(c, i);
468 if (it == c->end()) return any_ptr(nullptr);
469 if constexpr (std::is_pointer_v<E>) {
470 E ptr = *it;
471 if (!ptr) return any_ptr(nullptr);
472 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>)
473 return toAnyPtr(static_cast<const cObject*>(ptr));
474 else
475 return any_ptr(ptr);
476 }
477 else {
478 return any_ptr(&(*it));
479 }
480 }
481};
482
489template<typename E>
490class cStdSetDescriptor : public cDynamicDescriptor
491{
492 private:
493 std::string elemTypeName;
494
495 typename std::set<E>::const_iterator nthIt(const std::set<E> *c, int i) const {
496 auto it = c->begin();
497 for (int k = 0; k < i && it != c->end(); k++) ++it;
498 return it;
499 }
500
501 public:
502 cStdSetDescriptor(const char *typeName)
503 : cDynamicDescriptor(typeName), elemTypeName(internal::getTypeName<std::remove_pointer_t<E>>()) {}
504
505 virtual std::string getValueAsString(any_ptr object) const override {
506 auto *c = object.get<std::set<E>>();
507 if (c->empty()) return "empty";
508 std::ostringstream os;
509 os << "size=" << c->size();
510 return os.str();
511 }
512
513 virtual int getFieldCount() const override { return 1; }
514 virtual const char *getFieldName(int field) const override { return field == 0 ? "elements" : nullptr; }
515 virtual const char *getFieldTypeString(int field) const override { return field == 0 ? elemTypeName.c_str() : nullptr; }
516 virtual const char *getFieldStructName(int field) const override { return field == 0 ? elemTypeName.c_str() : nullptr; }
517
518 virtual unsigned int getFieldTypeFlags(int field) const override {
519 if (field != 0) return 0;
520 unsigned int flags = FD_ISARRAY;
521 if constexpr (std::is_pointer_v<E>) {
522 flags |= FD_ISPOINTER;
523 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>)
524 flags |= FD_ISCOMPOUND | FD_ISCOBJECT;
525 }
526 if (!(flags & FD_ISCOMPOUND)) {
527 cClassDescriptor *elemDesc = cClassDescriptor::getDescriptorFor(elemTypeName.c_str());
528 if (elemDesc) {
529 flags |= FD_ISCOMPOUND;
530 if (elemDesc->extendsCObject())
531 flags |= FD_ISCOBJECT;
532 }
533 }
534 return flags;
535 }
536
537 virtual int getFieldArraySize(any_ptr object, int field) const override {
538 if (field != 0) return 0;
539 return (int)object.get<std::set<E>>()->size();
540 }
541
542 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override {
543 if (field != 0) return "";
544 auto *c = object.get<std::set<E>>();
545 auto it = nthIt(c, i);
546 if (it == c->end()) return "";
547 if constexpr (std::is_pointer_v<E>) {
548 E ptr = *it;
549 if (!ptr) return "nullptr";
550 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>) {
551 cClassDescriptor *desc = static_cast<const cObject*>(ptr)->getDescriptor();
552 if (desc) return desc->getValueAsString(toAnyPtr(static_cast<const cObject*>(ptr)));
553 }
554 else {
555 cClassDescriptor *elemDesc = cClassDescriptor::getDescriptorFor(elemTypeName.c_str());
556 if (elemDesc) return elemDesc->getValueAsString(any_ptr(ptr));
557 if constexpr (is_printable<std::remove_pointer_t<E>>::value) { std::ostringstream os; os << *ptr; return os.str(); }
558 }
559 }
560 else {
561 cClassDescriptor *elemDesc = cClassDescriptor::getDescriptorFor(elemTypeName.c_str());
562 if (elemDesc) return elemDesc->getValueAsString(any_ptr(const_cast<E*>(&(*it))));
563 if constexpr (is_printable<E>::value) { std::ostringstream os; os << *it; return os.str(); }
564 }
565 return UNPRINTABLE;
566 }
567
568 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override {
569 if (field != 0) return any_ptr(nullptr);
570 auto *c = object.get<std::set<E>>();
571 auto it = nthIt(c, i);
572 if (it == c->end()) return any_ptr(nullptr);
573 if constexpr (std::is_pointer_v<E>) {
574 E ptr = *it;
575 if (!ptr) return any_ptr(nullptr);
576 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<E>>)
577 return toAnyPtr(static_cast<const cObject*>(ptr));
578 else
579 return any_ptr(ptr);
580 }
581 else {
582 return any_ptr(const_cast<E*>(&(*it)));
583 }
584 }
585
586 virtual std::string getFieldArrayIndexString(any_ptr object, int field, int arrayIndex) const override {
587 return "";
588 }
589};
590
598template<typename MapType>
599class cStdMapDescriptor : public cDynamicDescriptor
600{
601 private:
602 using K = typename MapType::key_type;
603 using V = typename MapType::mapped_type;
604 std::string keyTypeName;
605 std::string valueTypeName;
606
607 typename MapType::iterator nthIt(MapType *m, int i) const {
608 auto it = m->begin();
609 for (int k = 0; k < i && it != m->end(); k++) ++it;
610 return it;
611 }
612
613 public:
614 cStdMapDescriptor(const char *typeName)
615 : cDynamicDescriptor(typeName),
616 keyTypeName(internal::getTypeName<std::remove_pointer_t<K>>()),
617 valueTypeName(internal::getTypeName<std::remove_pointer_t<V>>()) {}
618
619 virtual std::string getValueAsString(any_ptr object) const override {
620 auto *m = object.get<MapType>();
621 if (m->empty()) return "empty";
622 std::ostringstream os;
623 os << "size=" << m->size();
624 return os.str();
625 }
626
627 virtual int getFieldCount() const override { return 1; }
628 virtual const char *getFieldName(int field) const override { return field == 0 ? "elements" : nullptr; }
629 virtual const char *getFieldTypeString(int field) const override { return field == 0 ? valueTypeName.c_str() : nullptr; }
630 virtual const char *getFieldStructName(int field) const override { return field == 0 ? valueTypeName.c_str() : nullptr; }
631
632 virtual unsigned int getFieldTypeFlags(int field) const override {
633 if (field != 0) return 0;
634 unsigned int flags = FD_ISARRAY;
635 if constexpr (std::is_pointer_v<V>) {
636 flags |= FD_ISPOINTER;
637 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<V>>)
638 flags |= FD_ISCOMPOUND | FD_ISCOBJECT;
639 }
640 if (!(flags & FD_ISCOMPOUND)) {
641 cClassDescriptor *valDesc = cClassDescriptor::getDescriptorFor(valueTypeName.c_str());
642 if (valDesc) { flags |= FD_ISCOMPOUND; if (valDesc->extendsCObject()) flags |= FD_ISCOBJECT; }
643 }
644 return flags;
645 }
646
647 virtual int getFieldArraySize(any_ptr object, int field) const override {
648 if (field != 0) return 0;
649 return (int)object.get<MapType>()->size();
650 }
651
652 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override {
653 if (field != 0) return "";
654 auto *m = object.get<MapType>();
655 auto it = nthIt(m, i);
656 if (it == m->end()) return "";
657 if constexpr (std::is_pointer_v<V>) {
658 V vptr = it->second;
659 if (!vptr) return "nullptr";
660 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<V>>) {
661 cClassDescriptor *desc = static_cast<const cObject*>(vptr)->getDescriptor();
662 if (desc) return desc->getValueAsString(toAnyPtr(static_cast<const cObject*>(vptr)));
663 }
664 else {
665 cClassDescriptor *valDesc = cClassDescriptor::getDescriptorFor(valueTypeName.c_str());
666 if (valDesc) return valDesc->getValueAsString(any_ptr(vptr));
667 if constexpr (is_printable<std::remove_pointer_t<V>>::value) { std::ostringstream os; os << *vptr; return os.str(); }
668 }
669 }
670 else {
671 cClassDescriptor *valDesc = cClassDescriptor::getDescriptorFor(valueTypeName.c_str());
672 if (valDesc) return valDesc->getValueAsString(any_ptr(&it->second));
673 if constexpr (is_printable<V>::value) { std::ostringstream os; os << it->second; return os.str(); }
674 }
675 return UNPRINTABLE;
676 }
677
678 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override {
679 if (field != 0) { cDynamicDescriptor::setFieldValueAsString(object, field, i, value); return; }
680 auto *m = object.get<MapType>();
681 auto it = nthIt(m, i);
682 if (it == m->end()) return;
683 if constexpr (std::is_pointer_v<V>) {
684 V vptr = it->second;
685 if (!vptr) return;
686 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<V>>) {
687 cClassDescriptor *desc = static_cast<const cObject*>(vptr)->getDescriptor();
688 if (desc) desc->setValueAsString(toAnyPtr(static_cast<const cObject*>(vptr)), value);
689 }
690 else {
691 cClassDescriptor *valDesc = cClassDescriptor::getDescriptorFor(valueTypeName.c_str());
692 if (valDesc) { valDesc->setValueAsString(any_ptr(vptr), value); return; }
693 }
694 }
695 else {
696 cClassDescriptor *valDesc = cClassDescriptor::getDescriptorFor(valueTypeName.c_str());
697 if (valDesc) { valDesc->setValueAsString(any_ptr(&it->second), value); return; }
698 if constexpr (is_extractable<V>::value) { std::istringstream is(value); is >> it->second; }
699 else { cDynamicDescriptor::setFieldValueAsString(object, field, i, value); }
700 }
701 }
702
703 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override {
704 if (field != 0) return any_ptr(nullptr);
705 auto *m = object.get<MapType>();
706 auto it = nthIt(m, i);
707 if (it == m->end()) return any_ptr(nullptr);
708 if constexpr (std::is_pointer_v<V>) {
709 V vptr = it->second;
710 if (!vptr) return any_ptr(nullptr);
711 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<V>>)
712 return toAnyPtr(static_cast<const cObject*>(vptr));
713 else
714 return any_ptr(vptr);
715 }
716 else {
717 return any_ptr(&it->second);
718 }
719 }
720
721 virtual std::string getFieldArrayIndexString(any_ptr object, int field, int arrayIndex) const override {
722 if (field != 0) return "";
723 auto *m = object.get<MapType>();
724 auto it = nthIt(m, arrayIndex);
725 if (it == m->end()) return "";
726 std::ostringstream os;
727 if constexpr (std::is_pointer_v<K>) {
728 K kptr = it->first;
729 if (!kptr) os << "nullptr";
730 else if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<K>>) {
731 cClassDescriptor *desc = static_cast<const cObject*>(kptr)->getDescriptor();
732 if (desc) os << desc->getValueAsString(toAnyPtr(static_cast<const cObject*>(kptr)));
733 else os << UNPRINTABLE;
734 }
735 else {
736 cClassDescriptor *keyDesc = cClassDescriptor::getDescriptorFor(keyTypeName.c_str());
737 if (keyDesc) os << keyDesc->getValueAsString(any_ptr(kptr));
738 else if constexpr (is_printable<std::remove_pointer_t<K>>::value) os << *kptr;
739 else os << UNPRINTABLE;
740 }
741 }
742 else {
743 cClassDescriptor *keyDesc = cClassDescriptor::getDescriptorFor(keyTypeName.c_str());
744 if (keyDesc) os << keyDesc->getValueAsString(any_ptr(const_cast<K*>(&it->first)));
745 else if constexpr (is_printable<K>::value) os << it->first;
746 else os << UNPRINTABLE;
747 }
748 os << " => ";
749 return os.str();
750 }
751};
752
758template<typename F, typename S>
759class cStdPairDescriptor : public cDynamicDescriptor
760{
761 private:
762 std::string firstTypeName;
763 std::string secondTypeName;
764
765 public:
766 cStdPairDescriptor(const char *typeName)
767 : cDynamicDescriptor(typeName),
768 firstTypeName(internal::getTypeName<std::remove_pointer_t<F>>()),
769 secondTypeName(internal::getTypeName<std::remove_pointer_t<S>>()) {}
770
771 virtual std::string getValueAsString(any_ptr object) const override {
772 auto *p = object.get<std::pair<F,S>>();
773 std::ostringstream os;
774 // first
775 if constexpr (std::is_pointer_v<F>) {
776 F fptr = p->first;
777 if (!fptr) os << "nullptr";
778 else if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<F>>) {
779 cClassDescriptor *desc = static_cast<const cObject*>(fptr)->getDescriptor();
780 if (desc) os << desc->getValueAsString(toAnyPtr(static_cast<const cObject*>(fptr))); else os << UNPRINTABLE;
781 }
782 else {
783 cClassDescriptor *fDesc = cClassDescriptor::getDescriptorFor(firstTypeName.c_str());
784 if (fDesc) os << fDesc->getValueAsString(any_ptr(fptr));
785 else if constexpr (is_printable<std::remove_pointer_t<F>>::value) os << *fptr;
786 else os << UNPRINTABLE;
787 }
788 }
789 else {
790 cClassDescriptor *fDesc = cClassDescriptor::getDescriptorFor(firstTypeName.c_str());
791 if (fDesc) os << fDesc->getValueAsString(any_ptr(const_cast<F*>(&p->first)));
792 else if constexpr (is_printable<F>::value) os << p->first;
793 else os << UNPRINTABLE;
794 }
795 os << " => ";
796 // second
797 if constexpr (std::is_pointer_v<S>) {
798 S sptr = p->second;
799 if (!sptr) os << "nullptr";
800 else if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<S>>) {
801 cClassDescriptor *desc = static_cast<const cObject*>(sptr)->getDescriptor();
802 if (desc) os << desc->getValueAsString(toAnyPtr(static_cast<const cObject*>(sptr))); else os << UNPRINTABLE;
803 }
804 else {
805 cClassDescriptor *sDesc = cClassDescriptor::getDescriptorFor(secondTypeName.c_str());
806 if (sDesc) os << sDesc->getValueAsString(any_ptr(sptr));
807 else if constexpr (is_printable<std::remove_pointer_t<S>>::value) os << *sptr;
808 else os << UNPRINTABLE;
809 }
810 }
811 else {
812 cClassDescriptor *sDesc = cClassDescriptor::getDescriptorFor(secondTypeName.c_str());
813 if (sDesc) os << sDesc->getValueAsString(any_ptr(&p->second));
814 else if constexpr (is_printable<S>::value) os << p->second;
815 else os << UNPRINTABLE;
816 }
817 return os.str();
818 }
819
820 virtual int getFieldCount() const override { return 2; }
821
822 virtual const char *getFieldName(int field) const override {
823 switch (field) { case 0: return "first"; case 1: return "second"; default: return nullptr; }
824 }
825
826 virtual const char *getFieldTypeString(int field) const override {
827 switch (field) { case 0: return firstTypeName.c_str(); case 1: return secondTypeName.c_str(); default: return nullptr; }
828 }
829
830 virtual const char *getFieldStructName(int field) const override {
831 switch (field) { case 0: return firstTypeName.c_str(); case 1: return secondTypeName.c_str(); default: return nullptr; }
832 }
833
834 virtual unsigned int getFieldTypeFlags(int field) const override {
835 if (field != 0 && field != 1) return 0;
836 unsigned int flags = 0;
837 if (field == 0) {
838 if constexpr (std::is_pointer_v<F>) {
839 flags |= FD_ISPOINTER;
840 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<F>>)
841 flags |= FD_ISCOMPOUND | FD_ISCOBJECT;
842 }
843 }
844 else {
845 if constexpr (std::is_pointer_v<S>) {
846 flags |= FD_ISPOINTER;
847 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<S>>)
848 flags |= FD_ISCOMPOUND | FD_ISCOBJECT;
849 }
850 }
851 if (!(flags & FD_ISCOMPOUND)) {
852 const char *tn = (field == 0) ? firstTypeName.c_str() : secondTypeName.c_str();
854 if (d && d->getFieldCount() > 0) { flags |= FD_ISCOMPOUND; if (d->extendsCObject()) flags |= FD_ISCOBJECT; }
855 }
856 return flags;
857 }
858
859 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override {
860 auto *p = object.get<std::pair<F,S>>();
861 if (field == 0) {
862 if constexpr (std::is_pointer_v<F>) {
863 F fptr = p->first;
864 if (!fptr) return "nullptr";
865 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<F>>) {
866 cClassDescriptor *desc = static_cast<const cObject*>(fptr)->getDescriptor();
867 if (desc) return desc->getValueAsString(toAnyPtr(static_cast<const cObject*>(fptr)));
868 }
869 else {
870 cClassDescriptor *d = cClassDescriptor::getDescriptorFor(firstTypeName.c_str());
871 if (d) return d->getValueAsString(any_ptr(fptr));
872 if constexpr (is_printable<std::remove_pointer_t<F>>::value) { std::ostringstream os; os << *fptr; return os.str(); }
873 }
874 }
875 else {
876 cClassDescriptor *d = cClassDescriptor::getDescriptorFor(firstTypeName.c_str());
877 if (d) return d->getValueAsString(any_ptr(const_cast<F*>(&p->first)));
878 if constexpr (is_printable<F>::value) { std::ostringstream os; os << p->first; return os.str(); }
879 }
880 }
881 else if (field == 1) {
882 if constexpr (std::is_pointer_v<S>) {
883 S sptr = p->second;
884 if (!sptr) return "nullptr";
885 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<S>>) {
886 cClassDescriptor *desc = static_cast<const cObject*>(sptr)->getDescriptor();
887 if (desc) return desc->getValueAsString(toAnyPtr(static_cast<const cObject*>(sptr)));
888 }
889 else {
890 cClassDescriptor *d = cClassDescriptor::getDescriptorFor(secondTypeName.c_str());
891 if (d) return d->getValueAsString(any_ptr(sptr));
892 if constexpr (is_printable<std::remove_pointer_t<S>>::value) { std::ostringstream os; os << *sptr; return os.str(); }
893 }
894 }
895 else {
896 cClassDescriptor *d = cClassDescriptor::getDescriptorFor(secondTypeName.c_str());
897 if (d) return d->getValueAsString(any_ptr(&p->second));
898 if constexpr (is_printable<S>::value) { std::ostringstream os; os << p->second; return os.str(); }
899 }
900 }
901 return UNPRINTABLE;
902 }
903
904 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override {
905 auto *p = object.get<std::pair<F,S>>();
906 if (field == 0) {
907 if constexpr (std::is_pointer_v<F>) {
908 F fptr = p->first;
909 if (!fptr) return;
910 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<F>>) {
911 cClassDescriptor *desc = static_cast<const cObject*>(fptr)->getDescriptor();
912 if (desc) desc->setValueAsString(toAnyPtr(static_cast<const cObject*>(fptr)), value);
913 }
914 else {
915 cClassDescriptor *d = cClassDescriptor::getDescriptorFor(firstTypeName.c_str());
916 if (d) { d->setValueAsString(any_ptr(fptr), value); return; }
917 }
918 }
919 else {
920 cClassDescriptor *d = cClassDescriptor::getDescriptorFor(firstTypeName.c_str());
921 if (d) { d->setValueAsString(any_ptr(const_cast<F*>(&p->first)), value); return; }
922 if constexpr (is_extractable<F>::value) { std::istringstream is(value); is >> const_cast<F&>(p->first); return; }
923 }
924 }
925 else if (field == 1) {
926 if constexpr (std::is_pointer_v<S>) {
927 S sptr = p->second;
928 if (!sptr) return;
929 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<S>>) {
930 cClassDescriptor *desc = static_cast<const cObject*>(sptr)->getDescriptor();
931 if (desc) desc->setValueAsString(toAnyPtr(static_cast<const cObject*>(sptr)), value);
932 }
933 else {
934 cClassDescriptor *d = cClassDescriptor::getDescriptorFor(secondTypeName.c_str());
935 if (d) { d->setValueAsString(any_ptr(sptr), value); return; }
936 }
937 }
938 else {
939 cClassDescriptor *d = cClassDescriptor::getDescriptorFor(secondTypeName.c_str());
940 if (d) { d->setValueAsString(any_ptr(&p->second), value); return; }
941 if constexpr (is_extractable<S>::value) { std::istringstream is(value); is >> p->second; return; }
942 }
943 }
944 cDynamicDescriptor::setFieldValueAsString(object, field, i, value);
945 }
946
947 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override {
948 auto *p = object.get<std::pair<F,S>>();
949 if (field == 0) {
950 if constexpr (std::is_pointer_v<F>) {
951 F fptr = p->first;
952 if (!fptr) return any_ptr(nullptr);
953 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<F>>)
954 return toAnyPtr(static_cast<const cObject*>(fptr));
955 else
956 return any_ptr(fptr);
957 }
958 else {
959 return any_ptr(const_cast<F*>(&p->first));
960 }
961 }
962 if (field == 1) {
963 if constexpr (std::is_pointer_v<S>) {
964 S sptr = p->second;
965 if (!sptr) return any_ptr(nullptr);
966 if constexpr (std::is_base_of_v<cObject, std::remove_pointer_t<S>>)
967 return toAnyPtr(static_cast<const cObject*>(sptr));
968 else
969 return any_ptr(sptr);
970 }
971 else {
972 return any_ptr(&p->second);
973 }
974 }
975 return any_ptr(nullptr);
976 }
977};
978
979} // namespace internal
980
981
991template<typename T>
992cClassDescriptor *ensureDescriptor()
993{
994 static std::string typeNameStr = internal::getTypeName<T>();
995 const char *typeName = typeNameStr.c_str();
996 cClassDescriptor *desc = cClassDescriptor::getDescriptorFor(typeName);
997 if (desc)
998 return desc;
999
1000 if constexpr (internal::is_std_vector<T>::value) {
1001 using E = typename T::value_type;
1002 if constexpr (std::is_pointer_v<E>)
1003 ensureDescriptor<std::remove_pointer_t<E>>();
1004 else
1005 ensureDescriptor<E>();
1006 desc = new internal::cStdVectorDescriptor<E>(typeName);
1007 }
1008 else if constexpr (internal::is_std_list<T>::value) {
1009 using E = typename T::value_type;
1010 if constexpr (std::is_pointer_v<E>)
1011 ensureDescriptor<std::remove_pointer_t<E>>();
1012 else
1013 ensureDescriptor<E>();
1014 desc = new internal::cStdListDescriptor<E>(typeName);
1015 }
1016 else if constexpr (internal::is_std_set<T>::value) {
1017 using E = typename T::value_type;
1018 if constexpr (std::is_pointer_v<E>)
1019 ensureDescriptor<std::remove_pointer_t<E>>();
1020 else
1021 ensureDescriptor<E>();
1022 desc = new internal::cStdSetDescriptor<E>(typeName);
1023 }
1024 else if constexpr (internal::is_std_map<T>::value) {
1025 using K = typename T::key_type;
1026 using V = typename T::mapped_type;
1027 if constexpr (std::is_pointer_v<K>) ensureDescriptor<std::remove_pointer_t<K>>(); else ensureDescriptor<K>();
1028 if constexpr (std::is_pointer_v<V>) ensureDescriptor<std::remove_pointer_t<V>>(); else ensureDescriptor<V>();
1029 desc = new internal::cStdMapDescriptor<T>(typeName);
1030 }
1031 else if constexpr (internal::is_std_unordered_map<T>::value) {
1032 using K = typename T::key_type;
1033 using V = typename T::mapped_type;
1034 if constexpr (std::is_pointer_v<K>) ensureDescriptor<std::remove_pointer_t<K>>(); else ensureDescriptor<K>();
1035 if constexpr (std::is_pointer_v<V>) ensureDescriptor<std::remove_pointer_t<V>>(); else ensureDescriptor<V>();
1036 desc = new internal::cStdMapDescriptor<T>(typeName);
1037 }
1038 else if constexpr (internal::is_std_pair<T>::value) {
1039 using F = typename T::first_type;
1040 using S = typename T::second_type;
1041 if constexpr (std::is_pointer_v<F>) ensureDescriptor<std::remove_pointer_t<F>>(); else ensureDescriptor<F>();
1042 if constexpr (std::is_pointer_v<S>) ensureDescriptor<std::remove_pointer_t<S>>(); else ensureDescriptor<S>();
1043 desc = new internal::cStdPairDescriptor<F,S>(typeName);
1044 }
1045 else {
1046 desc = new internal::cPrimitiveTypeDescriptor<T>(typeName);
1047 }
1048 internal::classDescriptors.getInstance()->add(desc);
1049 return desc;
1050}
1051
1052} // namespace omnetpp
1053
1054#endif
A type-safe equivalent of the void* pointer.
Definition any_ptr.h:63
static cClassDescriptor * getDescriptorFor(const char *classname)
virtual int getFieldCount() const =0
@ FD_ISARRAY
field is an array: int a[]; int a[10];
Definition cclassdescriptor.h:44
@ FD_ISCOBJECT
if ISCOMPOUND: basic type (T) subclasses from cObject
Definition cclassdescriptor.h:47
@ FD_ISCOMPOUND
basic type (T) is struct or class: T a; T *a; T a[10]; T *a[]
Definition cclassdescriptor.h:45
@ FD_ISPOINTER
field is pointer or pointer array: T *a; T *a[]; T *a[10];
Definition cclassdescriptor.h:46
static constexpr const char * UNPRINTABLE
Returned by getValueAsString() and getFieldValueAsString() for types that have no text representation...
Definition cclassdescriptor.h:56
cClassDescriptor(const char *className, const char *baseClassName=nullptr)
virtual std::string getValueAsString(any_ptr object) const
Definition cclassdescriptor.h:170
virtual void setValueAsString(any_ptr object, const char *value) const
cObject is a lightweight class which serves as the root of the OMNeT++ class hierarchy....
Definition cobject.h:93
virtual cClassDescriptor * getDescriptor() const
A variant-like value class used during evaluating NED expressions.
Definition cvalue.h:48
virtual unsigned int getFieldTypeFlags(int field) const override
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
virtual int getFieldArraySize(any_ptr object, int field) const override
virtual const char ** getPropertyNames() const override
virtual const char * getFieldTypeString(int field) const override
virtual const char * getFieldStructName(int field) const override
virtual const char * getFieldProperty(int field, const char *propertyName) const override
virtual int getFieldCount() const override
virtual const char * getFieldName(int field) const override
virtual const char * getProperty(const char *propertyName) const override
virtual const char ** getFieldPropertyNames(int field) const override
virtual cValue getFieldValue(any_ptr object, int field, int i) const override
virtual void setFieldValue(any_ptr object, int field, int i, const cValue &value) const override
virtual void setFieldArraySize(any_ptr object, int field, int size) const override
virtual void setFieldStructValuePointer(any_ptr object, int field, int i, any_ptr ptr) const override
Descriptor for primitive/simple types that support operator<< and/or operator>>. Has no fields; provi...
Definition cdynamicdescriptor.h:142
virtual void setValueAsString(any_ptr object, const char *value) const override
Definition cdynamicdescriptor.h:171
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:146
Descriptor for std::list<E>. Pretends to have a single "elements[]" array field of type E....
Definition cdynamicdescriptor.h:368
virtual unsigned int getFieldTypeFlags(int field) const override
Definition cdynamicdescriptor.h:395
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:464
virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override
Definition cdynamicdescriptor.h:440
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:415
virtual int getFieldArraySize(any_ptr object, int field) const override
Definition cdynamicdescriptor.h:410
virtual const char * getFieldTypeString(int field) const override
Definition cdynamicdescriptor.h:392
virtual const char * getFieldStructName(int field) const override
Definition cdynamicdescriptor.h:393
virtual int getFieldCount() const override
Definition cdynamicdescriptor.h:390
virtual const char * getFieldName(int field) const override
Definition cdynamicdescriptor.h:391
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:382
Descriptor for std::map<K,V> and std::unordered_map<K,V>. Pretends to have a single "elements[]" arra...
Definition cdynamicdescriptor.h:600
virtual unsigned int getFieldTypeFlags(int field) const override
Definition cdynamicdescriptor.h:632
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:703
virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override
Definition cdynamicdescriptor.h:678
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:652
virtual int getFieldArraySize(any_ptr object, int field) const override
Definition cdynamicdescriptor.h:647
virtual const char * getFieldTypeString(int field) const override
Definition cdynamicdescriptor.h:629
virtual std::string getFieldArrayIndexString(any_ptr object, int field, int arrayIndex) const override
Definition cdynamicdescriptor.h:721
virtual const char * getFieldStructName(int field) const override
Definition cdynamicdescriptor.h:630
virtual int getFieldCount() const override
Definition cdynamicdescriptor.h:627
virtual const char * getFieldName(int field) const override
Definition cdynamicdescriptor.h:628
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:619
Descriptor for std::pair<F,S>. Has two fields: "first" and "second".
Definition cdynamicdescriptor.h:760
virtual unsigned int getFieldTypeFlags(int field) const override
Definition cdynamicdescriptor.h:834
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:947
virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override
Definition cdynamicdescriptor.h:904
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:859
virtual const char * getFieldTypeString(int field) const override
Definition cdynamicdescriptor.h:826
virtual const char * getFieldStructName(int field) const override
Definition cdynamicdescriptor.h:830
virtual int getFieldCount() const override
Definition cdynamicdescriptor.h:820
virtual const char * getFieldName(int field) const override
Definition cdynamicdescriptor.h:822
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:771
Descriptor for std::set<E>. Pretends to have a single "elements[]" array field of type E....
Definition cdynamicdescriptor.h:491
virtual unsigned int getFieldTypeFlags(int field) const override
Definition cdynamicdescriptor.h:518
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:568
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:542
virtual int getFieldArraySize(any_ptr object, int field) const override
Definition cdynamicdescriptor.h:537
virtual const char * getFieldTypeString(int field) const override
Definition cdynamicdescriptor.h:515
virtual std::string getFieldArrayIndexString(any_ptr object, int field, int arrayIndex) const override
Definition cdynamicdescriptor.h:586
virtual const char * getFieldStructName(int field) const override
Definition cdynamicdescriptor.h:516
virtual int getFieldCount() const override
Definition cdynamicdescriptor.h:513
virtual const char * getFieldName(int field) const override
Definition cdynamicdescriptor.h:514
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:505
virtual unsigned int getFieldTypeFlags(int field) const override
Definition cdynamicdescriptor.h:231
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:343
virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override
Definition cdynamicdescriptor.h:305
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:271
virtual int getFieldArraySize(any_ptr object, int field) const override
Definition cdynamicdescriptor.h:254
virtual const char * getFieldTypeString(int field) const override
Definition cdynamicdescriptor.h:250
virtual const char * getFieldStructName(int field) const override
Definition cdynamicdescriptor.h:339
virtual int getFieldCount() const override
Definition cdynamicdescriptor.h:225
virtual const char * getFieldName(int field) const override
Definition cdynamicdescriptor.h:227
virtual void setFieldArraySize(any_ptr object, int field, int size) const override
Definition cdynamicdescriptor.h:260
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:217
SIM_API const char * opp_typename(const std::type_info &t)
Returns the name of a C++ type, correcting the quirks of various compilers.