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 <forward_list>
24#include <deque>
25#include <array>
26#include <set>
27#include <map>
28#include <unordered_set>
29#include <unordered_map>
30#include <queue>
31#include <stack>
32#include <memory>
33#include <optional>
34#include <utility>
35#include <iterator>
36#include <type_traits>
37#include "cclassdescriptor.h"
38#include "simutil.h"
39#include "globals.h"
40
41namespace omnetpp {
42
43namespace internal {
44
45// --- Type traits ---
46
47template<typename T, typename = void>
48struct is_printable : std::false_type {};
49template<typename T>
50struct is_printable<T, std::void_t<decltype(std::declval<std::ostream&>() << std::declval<const T&>())>> : std::true_type {};
51
52template<typename T, typename = void>
53struct is_extractable : std::false_type {};
54template<typename T>
55struct is_extractable<T, std::void_t<decltype(std::declval<std::istream&>() >> std::declval<T&>())>> : std::true_type {};
56
57// standard library containers supported by cStdContainerDescriptor
58template<typename T> struct is_std_sequence : std::false_type {}; // elements are accessed by index
59template<typename E, typename A> struct is_std_sequence<std::vector<E,A>> : std::true_type {};
60template<typename E, typename A> struct is_std_sequence<std::list<E,A>> : std::true_type {};
61template<typename E, typename A> struct is_std_sequence<std::forward_list<E,A>> : std::true_type {};
62template<typename E, typename A> struct is_std_sequence<std::deque<E,A>> : std::true_type {};
63template<typename E, size_t N> struct is_std_sequence<std::array<E,N>> : std::true_type {};
64
65template<typename T> struct is_std_set : std::false_type {}; // elements are read-only
66template<typename E, typename C, typename A> struct is_std_set<std::set<E,C,A>> : std::true_type {};
67template<typename E, typename C, typename A> struct is_std_set<std::multiset<E,C,A>> : std::true_type {};
68template<typename E, typename H, typename Q, typename A> struct is_std_set<std::unordered_set<E,H,Q,A>> : std::true_type {};
69template<typename E, typename H, typename Q, typename A> struct is_std_set<std::unordered_multiset<E,H,Q,A>> : std::true_type {};
70
71template<typename T> struct is_std_map : std::false_type {}; // elements are the mapped values, labeled with the keys
72template<typename K, typename V, typename C, typename A> struct is_std_map<std::map<K,V,C,A>> : std::true_type {};
73template<typename K, typename V, typename C, typename A> struct is_std_map<std::multimap<K,V,C,A>> : std::true_type {};
74template<typename K, typename V, typename H, typename Q, typename A> struct is_std_map<std::unordered_map<K,V,H,Q,A>> : std::true_type {};
75template<typename K, typename V, typename H, typename Q, typename A> struct is_std_map<std::unordered_multimap<K,V,H,Q,A>> : std::true_type {};
76
77template<typename T> struct is_std_adaptor : std::false_type {}; // container adaptors: their underlying container is displayed, read-only
78template<typename E, typename C> struct is_std_adaptor<std::queue<E,C>> : std::true_type {};
79template<typename E, typename C> struct is_std_adaptor<std::stack<E,C>> : std::true_type {};
80template<typename E, typename C, typename P> struct is_std_adaptor<std::priority_queue<E,C,P>> : std::true_type {};
81
82// wrappers of a single (optional) value, supported by cStdWrapperDescriptor
83template<typename T> struct is_std_optional : std::false_type {};
84template<typename E> struct is_std_optional<std::optional<E>> : std::true_type {};
85
86template<typename T> struct is_std_smart_pointer : std::false_type {};
87template<typename E, typename D> struct is_std_smart_pointer<std::unique_ptr<E,D>> : std::true_type {};
88template<typename E> struct is_std_smart_pointer<std::shared_ptr<E>> : std::true_type {};
89
90template<typename W, bool isOptional = is_std_optional<W>::value>
91struct wrapped_type { using type = typename W::element_type; };
92template<typename W>
93struct wrapped_type<W, true> { using type = typename W::value_type; };
94
95// gives access to the underlying container (protected member "c") of a container adaptor
96template<typename A>
97struct AdaptorAccess : A {
98 static typename A::container_type *getContainer(A *adaptor) { return &(adaptor->*(&AdaptorAccess::c)); }
99};
100
101template<typename T, bool isAdaptor = is_std_adaptor<T>::value>
102struct underlying_container { using type = T; };
103template<typename T>
104struct underlying_container<T, true> { using type = typename T::container_type; };
105
106template<typename T> struct is_std_pair : std::false_type {};
107template<typename F, typename S> struct is_std_pair<std::pair<F,S>> : std::true_type {};
108
109template<typename C, bool isMap = is_std_map<C>::value>
110struct container_element { using type = typename C::value_type; };
111template<typename C>
112struct container_element<C, true> { using type = typename C::mapped_type; };
113
114template<typename C, typename = void>
115struct has_size : std::false_type {};
116template<typename C>
117struct has_size<C, std::void_t<decltype(std::declval<const C&>().size())>> : std::true_type {};
118
119template<typename C, typename = void>
120struct has_resize : std::false_type {};
121template<typename C>
122struct has_resize<C, std::void_t<decltype(std::declval<C&>().resize(0))>> : std::true_type {};
123
124// Returns the type name for T. Note: it must be unique, as descriptors are
125// registered and looked up by name.
126template<typename T>
127std::string getTypeName() {
128 return opp_typename(typeid(T));
129}
130
137class SIM_API cDynamicDescriptor : public cClassDescriptor
138{
139 public:
140 cDynamicDescriptor(const char *className, const char *baseClassName = nullptr);
141 virtual ~cDynamicDescriptor() {}
142
143 virtual const char **getPropertyNames() const override;
144 virtual const char *getProperty(const char *propertyName) const override;
145 virtual int getFieldCount() const override;
146 virtual const char *getFieldName(int field) const override;
147 virtual unsigned int getFieldTypeFlags(int field) const override;
148 virtual const char *getFieldTypeString(int field) const override;
149 virtual const char **getFieldPropertyNames(int field) const override;
150 virtual const char *getFieldProperty(int field, const char *propertyName) const override;
151 virtual int getFieldArraySize(any_ptr object, int field) const override;
152 virtual void setFieldArraySize(any_ptr object, int field, int size) const override;
153 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override;
154 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override;
155 virtual cValue getFieldValue(any_ptr object, int field, int i) const override;
156 virtual void setFieldValue(any_ptr object, int field, int i, const cValue& value) const override;
157 virtual const char *getFieldStructName(int field) const override;
158 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override;
159 virtual void setFieldStructValuePointer(any_ptr object, int field, int i, any_ptr ptr) const override;
160};
161
168template<typename T>
169class cPrimitiveTypeDescriptor : public cDynamicDescriptor
170{
171 public:
172 cPrimitiveTypeDescriptor(const char *typeName) : cDynamicDescriptor(typeName) {}
173
174 virtual std::string getValueAsString(any_ptr object) const override {
175 T *p = object.get<T>();
176 if constexpr (std::is_same_v<T, char> || std::is_same_v<T, signed char>) {
177 std::ostringstream os;
178 os << "'" << ((unsigned char)*p < 32 ? ' ' : (char)*p) << "' (" << (int)*p << ")";
179 return os.str();
180 }
181 else if constexpr (std::is_same_v<T, unsigned char>) {
182 std::ostringstream os;
183 os << "'" << (*p < ' ' ? ' ' : (char)*p) << "' (" << (unsigned)*p << ")";
184 return os.str();
185 }
186 else if constexpr (std::is_same_v<T, std::string>) {
187 std::ostringstream os;
188 os << "\"" << *p << "\"";
189 return os.str();
190 }
191 else if constexpr (is_printable<T>::value) {
192 std::ostringstream os;
193 os << *p;
194 return os.str();
195 }
196 return UNPRINTABLE;
197 }
198
199 virtual void setValueAsString(any_ptr object, const char *value) const override {
200 T *p = object.get<T>();
201 if constexpr (std::is_same_v<T, char> || std::is_same_v<T, signed char>) {
202 if (value[0] == '\'')
203 *p = value[1];
204 else
205 *p = (char)atoi(value);
206 }
207 else if constexpr (std::is_same_v<T, unsigned char>) {
208 if (value[0] == '\'')
209 *p = value[1];
210 else
211 *p = (unsigned char)atoi(value);
212 }
213 else if constexpr (std::is_same_v<T, std::string>) {
214 size_t len = strlen(value);
215 if (len >= 2 && value[0] == '"' && value[len-1] == '"')
216 *p = std::string(value + 1, len - 2);
217 else
218 *p = value;
219 }
220 else if constexpr (is_extractable<T>::value) {
221 std::istringstream is(value);
222 is >> *p;
223 }
224 else {
226 }
227 }
228};
229
239template<typename E>
241{
242 private:
243 using T = std::remove_cv_t<std::remove_pointer_t<E>>; // type of the value (the pointee for pointers)
244 static constexpr bool isCObject = std::is_base_of_v<cObject, T>;
245
246 // returns the address of the value; nullptr for null pointers
247 static T *getValuePointer(const E& e) {
248 if constexpr (std::is_pointer_v<E>)
249 return const_cast<T*>(e);
250 else
251 return const_cast<T*>(&e);
252 }
253
254 static any_ptr toAny(T *p) {
255 if constexpr (isCObject)
256 return toAnyPtr(static_cast<const cObject*>(p));
257 else
258 return any_ptr(p);
259 }
260
261 static cClassDescriptor *getDescriptor(T *p) {
262 if constexpr (isCObject)
263 return p->getDescriptor();
264 else
265 return cClassDescriptor::getDescriptorFor(getTypeName().c_str());
266 }
267
268 public:
269 static const std::string& getTypeName() {
270 static const std::string typeName = internal::getTypeName<T>();
271 return typeName;
272 }
273
274 static unsigned int getTypeFlags() {
275 unsigned int flags = 0;
276 if constexpr (std::is_pointer_v<E>)
278 if constexpr (isCObject)
280 else {
281 cClassDescriptor *desc = cClassDescriptor::getDescriptorFor(getTypeName().c_str());
282 if (desc && desc->getFieldCount() > 0)
284 }
285 return flags;
286 }
287
288 static std::string getValueAsString(const E& e) {
289 T *p = getValuePointer(e);
290 if (!p)
291 return "nullptr";
292 if (cClassDescriptor *desc = getDescriptor(p))
293 return desc->getValueAsString(toAny(p));
294 if constexpr (!isCObject && is_printable<T>::value) {
295 std::ostringstream os;
296 os << *p;
297 return os.str();
298 }
300 }
301
302 // returns false if not possible (no value or no way to parse it)
303 static bool setValueAsString(E& e, const char *value) {
304 T *p = getValuePointer(e);
305 if (!p)
306 return false;
307 if (cClassDescriptor *desc = getDescriptor(p)) {
308 desc->setValueAsString(toAny(p), value);
309 return true;
310 }
311 if constexpr (!isCObject && is_extractable<T>::value) {
312 std::istringstream is(value);
313 is >> *p;
314 return true;
315 }
316 return false;
317 }
318
319 static any_ptr getStructValuePointer(const E& e) {
320 T *p = getValuePointer(e);
321 return p ? toAny(p) : any_ptr(nullptr);
322 }
323};
324
339template<typename T>
340class cStdContainerDescriptor : public cDynamicDescriptor
341{
342 private:
343 static constexpr bool isAdaptor = is_std_adaptor<T>::value;
344 using C = typename underlying_container<T>::type; // the container whose elements are shown
345 static constexpr bool isMap = is_std_map<C>::value;
346 static constexpr bool isReadOnly = is_std_set<C>::value || isAdaptor;
347 using E = typename container_element<C>::type; // mapped_type for maps, otherwise value_type
348
349 // true for std::vector<bool>, whose elements are not addressable: operator[]
350 // and iterators return a proxy object instead of a reference
351 static constexpr bool hasProxyElements = !std::is_reference_v<typename C::reference>;
352
353 static int getSize(const C *c) {
354 if constexpr (has_size<C>::value)
355 return (int)c->size();
356 else
357 return (int)std::distance(c->begin(), c->end()); // e.g. std::forward_list
358 }
359
360 template<typename Iterator>
361 static auto& getElement(Iterator it) {
362 if constexpr (isMap)
363 return it->second;
364 else
365 return *it;
366 }
367
368 static C *getContainer(any_ptr object) {
369 if constexpr (isAdaptor)
370 return AdaptorAccess<T>::getContainer(object.get<T>());
371 else
372 return object.get<T>();
373 }
374
375 // returns the iterator to the ith element, or end() if i is out of range
376 static auto getIterator(C *c, int i) {
377 return (i >= 0 && i < getSize(c)) ? std::next(c->begin(), i) : c->end();
378 }
379
380 public:
381 cStdContainerDescriptor(const char *typeName) : cDynamicDescriptor(typeName) {}
382
383 virtual std::string getValueAsString(any_ptr object) const override {
384 C *c = getContainer(object);
385 if (c->begin() == c->end())
386 return "empty";
387 return "size=" + std::to_string(getSize(c));
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 ? ValueAccess<E>::getTypeName().c_str() : nullptr; }
393 virtual const char *getFieldStructName(int field) const override { return field == 0 ? ValueAccess<E>::getTypeName().c_str() : nullptr; }
394 virtual unsigned int getFieldTypeFlags(int field) const override { return field == 0 ? FD_ISARRAY | ValueAccess<E>::getTypeFlags() : 0; }
395
396 virtual int getFieldArraySize(any_ptr object, int field) const override {
397 return field == 0 ? getSize(getContainer(object)) : 0;
398 }
399
400 virtual void setFieldArraySize(any_ptr object, int field, int size) const override {
401 if constexpr (has_resize<C>::value && std::is_default_constructible_v<E> && !isAdaptor) {
402 if (field == 0) {
403 getContainer(object)->resize(size);
404 return;
405 }
406 }
407 cDynamicDescriptor::setFieldArraySize(object, field, size);
408 }
409
410 virtual std::string getFieldArrayIndexString(any_ptr object, int field, int i) const override {
411 if constexpr (isMap) {
412 C *c = getContainer(object);
413 auto it = getIterator(c, i);
414 if (field != 0 || it == c->end())
415 return "";
416 return ValueAccess<typename C::key_type>::getValueAsString(it->first) + " => ";
417 }
418 else if constexpr (is_std_set<C>::value)
419 return ""; // set elements have no meaningful index
420 else
421 return cDynamicDescriptor::getFieldArrayIndexString(object, field, i);
422 }
423
424 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override {
425 C *c = getContainer(object);
426 auto it = getIterator(c, i);
427 if (field != 0 || it == c->end())
428 return "";
429 if constexpr (hasProxyElements) {
430 E element = *it;
431 return ValueAccess<E>::getValueAsString(element);
432 }
433 else
434 return ValueAccess<E>::getValueAsString(getElement(it));
435 }
436
437 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override {
438 if constexpr (!isReadOnly) {
439 C *c = getContainer(object);
440 auto it = getIterator(c, i);
441 if (field == 0 && it != c->end()) {
442 bool done;
443 if constexpr (hasProxyElements) {
444 E element = *it;
445 done = ValueAccess<E>::setValueAsString(element, value);
446 if (done)
447 *it = element;
448 }
449 else
450 done = ValueAccess<E>::setValueAsString(getElement(it), value);
451 if (done)
452 return;
453 }
454 }
455 cDynamicDescriptor::setFieldValueAsString(object, field, i, value);
456 }
457
458 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override {
459 C *c = getContainer(object);
460 auto it = getIterator(c, i);
461 if (field != 0 || it == c->end())
462 return any_ptr(nullptr);
463 if constexpr (hasProxyElements)
464 return any_ptr(nullptr); // elements are not addressable (nor compound)
465 else
466 return ValueAccess<E>::getStructValuePointer(getElement(it));
467 }
468};
469
479template<typename W>
480class cStdWrapperDescriptor : public cDynamicDescriptor
481{
482 private:
483 static constexpr bool isOptional = is_std_optional<W>::value;
484 using V = typename wrapped_type<W>::type;
485 using Access = ValueAccess<V*>;
486
487 // returns the pointer to the contained value or pointee, or nullptr if there is none
488 static V *getPointer(any_ptr object) {
489 W *w = object.get<W>();
490 if constexpr (isOptional)
491 return w->has_value() ? &**w : nullptr;
492 else
493 return w->get();
494 }
495
496 static const char *getNoneString() { return isOptional ? "empty" : "nullptr"; }
497
498 public:
499 cStdWrapperDescriptor(const char *typeName) : cDynamicDescriptor(typeName) {}
500
501 virtual std::string getValueAsString(any_ptr object) const override {
502 V *p = getPointer(object);
503 return p ? Access::getValueAsString(p) : getNoneString();
504 }
505
506 virtual int getFieldCount() const override { return 1; }
507 virtual const char *getFieldName(int field) const override { return field != 0 ? nullptr : isOptional ? "value" : "pointee"; }
508 virtual const char *getFieldTypeString(int field) const override { return field == 0 ? Access::getTypeName().c_str() : nullptr; }
509 virtual const char *getFieldStructName(int field) const override { return field == 0 ? Access::getTypeName().c_str() : nullptr; }
510
511 virtual unsigned int getFieldTypeFlags(int field) const override {
512 if (field != 0)
513 return 0;
514 unsigned int flags = Access::getTypeFlags();
515 return isOptional ? flags & ~FD_ISPOINTER : flags;
516 }
517
518 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override {
519 if (field != 0)
520 return "";
521 V *p = getPointer(object);
522 return p ? Access::getValueAsString(p) : getNoneString();
523 }
524
525 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override {
526 V *p = field == 0 ? getPointer(object) : nullptr;
527 if (!p || !Access::setValueAsString(p, value))
528 cDynamicDescriptor::setFieldValueAsString(object, field, i, value);
529 }
530
531 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override {
532 V *p = field == 0 ? getPointer(object) : nullptr;
533 return p ? Access::getStructValuePointer(p) : any_ptr(nullptr);
534 }
535};
536
542template<typename F, typename S>
543class cStdPairDescriptor : public cDynamicDescriptor
544{
545 public:
546 cStdPairDescriptor(const char *typeName) : cDynamicDescriptor(typeName) {}
547
548 virtual std::string getValueAsString(any_ptr object) const override {
549 auto *p = object.get<std::pair<F,S>>();
550 return ValueAccess<F>::getValueAsString(p->first) + " => " + ValueAccess<S>::getValueAsString(p->second);
551 }
552
553 virtual int getFieldCount() const override { return 2; }
554
555 virtual const char *getFieldName(int field) const override {
556 switch (field) { case 0: return "first"; case 1: return "second"; default: return nullptr; }
557 }
558
559 virtual const char *getFieldTypeString(int field) const override {
560 switch (field) {
561 case 0: return ValueAccess<F>::getTypeName().c_str();
562 case 1: return ValueAccess<S>::getTypeName().c_str();
563 default: return nullptr;
564 }
565 }
566
567 virtual const char *getFieldStructName(int field) const override { return getFieldTypeString(field); }
568
569 virtual unsigned int getFieldTypeFlags(int field) const override {
570 switch (field) {
571 case 0: return ValueAccess<F>::getTypeFlags();
572 case 1: return ValueAccess<S>::getTypeFlags();
573 default: return 0;
574 }
575 }
576
577 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override {
578 auto *p = object.get<std::pair<F,S>>();
579 switch (field) {
580 case 0: return ValueAccess<F>::getValueAsString(p->first);
581 case 1: return ValueAccess<S>::getValueAsString(p->second);
582 default: return "";
583 }
584 }
585
586 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override {
587 auto *p = object.get<std::pair<F,S>>();
588 bool done = false;
589 if (field == 0)
590 done = ValueAccess<F>::setValueAsString(const_cast<F&>(p->first), value);
591 else if (field == 1)
592 done = ValueAccess<S>::setValueAsString(p->second, value);
593 if (!done)
594 cDynamicDescriptor::setFieldValueAsString(object, field, i, value);
595 }
596
597 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override {
598 auto *p = object.get<std::pair<F,S>>();
599 switch (field) {
600 case 0: return ValueAccess<F>::getStructValuePointer(p->first);
601 case 1: return ValueAccess<S>::getStructValuePointer(p->second);
602 default: return any_ptr(nullptr);
603 }
604 }
605};
606
607} // namespace internal
608
609
624template<typename T>
625cClassDescriptor *ensureDescriptor();
626
627namespace internal {
628
629// ensures the descriptor for a container element or pair member type (for pointers, the pointee type)
630template<typename E>
631void ensureValueDescriptor()
632{
633 ensureDescriptor<std::remove_pointer_t<E>>();
634}
635
636} // namespace internal
637
638template<typename T>
639cClassDescriptor *ensureDescriptor()
640{
641 // any_ptr strips const, so descriptors must be created for the unqualified type
642 if constexpr (!std::is_same_v<T, std::remove_cv_t<T>>)
643 return ensureDescriptor<std::remove_cv_t<T>>();
644 else {
645 static std::string typeNameStr = internal::getTypeName<T>();
646 const char *typeName = typeNameStr.c_str();
648 if (desc)
649 return desc;
650
651 if constexpr (std::is_base_of_v<cObject, T>) {
652 return nullptr;
653 }
654 else if constexpr (internal::is_std_sequence<T>::value || internal::is_std_set<T>::value || internal::is_std_adaptor<T>::value) {
655 internal::ensureValueDescriptor<typename T::value_type>();
656 desc = new internal::cStdContainerDescriptor<T>(typeName);
657 }
658 else if constexpr (internal::is_std_map<T>::value) {
659 internal::ensureValueDescriptor<typename T::key_type>();
660 internal::ensureValueDescriptor<typename T::mapped_type>();
661 desc = new internal::cStdContainerDescriptor<T>(typeName);
662 }
663 else if constexpr (internal::is_std_optional<T>::value || internal::is_std_smart_pointer<T>::value) {
664 internal::ensureValueDescriptor<typename internal::wrapped_type<T>::type>();
665 desc = new internal::cStdWrapperDescriptor<T>(typeName);
666 }
667 else if constexpr (internal::is_std_pair<T>::value) {
668 internal::ensureValueDescriptor<typename T::first_type>();
669 internal::ensureValueDescriptor<typename T::second_type>();
671 }
672 else {
673 desc = new internal::cPrimitiveTypeDescriptor<T>(typeName);
674 }
675 internal::classDescriptors.getInstance()->add(desc);
676 return desc;
677 }
678}
679
680} // namespace omnetpp
681
682#endif
A type-safe equivalent of the void* pointer.
Definition any_ptr.h:63
Abstract base class for class descriptors.
Definition cclassdescriptor.h:40
static cClassDescriptor * getDescriptorFor(const char *classname)
virtual int getFieldCount() const =0
virtual std::string getFieldArrayIndexString(any_ptr object, int field, int arrayIndex) const
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 void setValueAsString(any_ptr object, const char *value) const
@ 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
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
Operations on a single value of type E (a container element or a pair member) for the descriptors of ...
Definition cdynamicdescriptor.h:241
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:170
virtual void setValueAsString(any_ptr object, const char *value) const override
Definition cdynamicdescriptor.h:199
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:174
Descriptor for standard library containers and container adaptors. Pretends to have a single "element...
Definition cdynamicdescriptor.h:341
virtual unsigned int getFieldTypeFlags(int field) const override
Definition cdynamicdescriptor.h:394
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:458
virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override
Definition cdynamicdescriptor.h:437
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:424
virtual int getFieldArraySize(any_ptr object, int field) const override
Definition cdynamicdescriptor.h:396
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 getFieldArrayIndexString(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:410
virtual void setFieldArraySize(any_ptr object, int field, int size) const override
Definition cdynamicdescriptor.h:400
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:383
Descriptor for std::pair<F,S>. Has two fields: "first" and "second".
Definition cdynamicdescriptor.h:544
virtual unsigned int getFieldTypeFlags(int field) const override
Definition cdynamicdescriptor.h:569
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:597
virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override
Definition cdynamicdescriptor.h:586
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:577
virtual const char * getFieldTypeString(int field) const override
Definition cdynamicdescriptor.h:559
virtual const char * getFieldStructName(int field) const override
Definition cdynamicdescriptor.h:567
virtual int getFieldCount() const override
Definition cdynamicdescriptor.h:553
virtual const char * getFieldName(int field) const override
Definition cdynamicdescriptor.h:555
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:548
Descriptor for std::optional, std::unique_ptr and std::shared_ptr. Its value is the value of the cont...
Definition cdynamicdescriptor.h:481
virtual unsigned int getFieldTypeFlags(int field) const override
Definition cdynamicdescriptor.h:511
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:531
virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override
Definition cdynamicdescriptor.h:525
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
Definition cdynamicdescriptor.h:518
virtual const char * getFieldTypeString(int field) const override
Definition cdynamicdescriptor.h:508
virtual const char * getFieldStructName(int field) const override
Definition cdynamicdescriptor.h:509
virtual int getFieldCount() const override
Definition cdynamicdescriptor.h:506
virtual const char * getFieldName(int field) const override
Definition cdynamicdescriptor.h:507
virtual std::string getValueAsString(any_ptr object) const override
Definition cdynamicdescriptor.h:501
SIM_API const char * opp_typename(const std::type_info &t)
Returns the name of a C++ type, correcting the quirks of various compilers.