CFx SDK Documentation 2024 SP0
Loading...
Searching...
No Matches
RxValue.h
Go to the documentation of this file.
1
2// Copyright (C) 2002-2022, Open Design Alliance (the "Alliance").
3// All rights reserved.
4//
5// This software and its documentation and related materials are owned by
6// the Alliance. The software may only be incorporated into application
7// programs owned by members of the Alliance, subject to a signed
8// Membership Agreement and Supplemental Software License Agreement with the
9// Alliance. The structure and organization of this software are the valuable
10// trade secrets of the Alliance and its suppliers. The software is also
11// protected by copyright law and international treaty provisions. Application
12// programs incorporating this software must include the following statement
13// with their copyright notices:
14//
15// This application incorporates Open Design Alliance software pursuant to a license
16// agreement with Open Design Alliance.
17// Open Design Alliance Copyright (C) 2002-2022 by Open Design Alliance.
18// All rights reserved.
19//
20// By use of this software, its documentation or related materials, you
21// acknowledge and accept the above terms.
23
24#ifndef _ODRXVALUE_INCLUDED_
25#define _ODRXVALUE_INCLUDED_
26
27#include "RxValueType.h"
28#include "RxMember.h"
29#include "StringArray.h"
30#include "IntArray.h"
31#include "Ge/GeDoubleArray.h"
32#include "StaticRxObject.h"
33#include "CmColorBase.h"
34#include "DbHandle.h"
35
44template<typename ValueType> ValueType* rxvalue_cast(OdRxValue* value) throw();
45
56template<typename ValueType> ValueType * rxenum_cast(OdRxValue * value) throw();
57
67template<typename ValueType> const ValueType * rxvalue_cast(const OdRxValue * value) throw();
68
79template<typename ValueType> const ValueType * rxenum_cast(const OdRxValue * value) throw();
80
81#include "TD_PackPush.h"
82
89{
90public:
94 OdRxValue() throw() : m_type(OdRxValueType::Desc<void>::value())
95 {
96 memset(&m_value, 0, sizeof(m_value));
97 }
98
105 OdRxValue(const OdRxValue& rhs) throw() : m_type(rhs.m_type)
106 {
107 init(rhs, false);
108 }
109
119 OdRxValue(const OdRxValueType& type, const OdRxValue& value) throw() : m_type(type)
120 {
121 init(value, false);
122 }
123
129 const OdRxValue& operator=(const OdRxValue& rhs) throw()
130 {
131 if (this == &rhs)
132 return *this;
133 if (type() != rhs.type())
134 {
135 if (!type().isBlittable())
136 type().nonBlittable()->destruct(valuePtr());
137 if (!isInlined() && rhs.isInlined())
138 deallocate(m_value.m_ptr);
139#ifdef _MSC_VER
140#pragma push_macro("new")
141#undef new
142#endif
143 ::new ((OdRxValueStorage*)this) OdRxValue(rhs, !isInlined() && !rhs.isInlined());
144#ifdef _MSC_VER
145#pragma pop_macro("new")
146#endif
147 return *this;
148 }
149 bool blittable = rhs.type().isBlittable();
150 bool inlined = rhs.isInlined();
151 if (blittable && inlined)
152 {
153 memcpy(this, &rhs, sizeof(OdRxValue));
154 return *this;
155 }
156 /*
157 inlined,non-blittable
158 non-inlined, non-blittable
159 non-inlined, blittable
160 */
161 if (inlined)
162 type().nonBlittable()->assign(inlineValuePtr(), rhs.inlineValuePtr());
163 else
164 setNonInlineValue(rhs.nonInlineValuePtr(), blittable, true, true);
165 return *this;
166 }
167
171 ~OdRxValue() throw()
172 {
173 //if the type is non-blittable then we must call destructor
174 if (!type().isBlittable())
175 type().nonBlittable()->destruct(valuePtr());
176 //finally free memory if necessary
177 if (!isInlined())
178 deallocate(m_value.m_ptr);
179 }
180
187 const OdRxValueType& type() const throw()
188 {
189 return m_type;
190 }
191
198 bool isEmpty() const throw() { return *this == empty(); }
199
206 static const OdRxValue& empty() throw();
207
215 bool isVaries() const throw() { return *this == varies(); }
216
223 static const OdRxValue& varies() throw();
224
236 OdString toString(OdRxValueType::StringFormat format = OdRxValueType::kStringFormatGlobal) const throw()
237 {
238 return m_type.toString(valuePtr(), format);
239 }
240
249 bool operator==(const OdRxValue& value) const throw()
250 {
251 if (type() != value.type())
252 return false;
253 return type().equalTo(valuePtr(), value.valuePtr());
254 }
255
264 bool operator!=(const OdRxValue& value) const throw()
265 {
266 return !(operator == (value));
267 }
268
277 const OdAnsiString typePath() const
278 {
279 return m_type.typePath(*this);
280 }
281
288 template <typename ValueType>
289 OdRxValue(const ValueType& value) throw()
291 {
292 //this should have been specialized otherwise
293 ODA_ASSERT(m_type.isBlittable());
294 initBlittable<sizeof(ValueType) <= 24>(&value, sizeof(ValueType));
295 }
296
306 template<typename ValueType>
307 friend ValueType* rxvalue_cast(OdRxValue* value) throw()
308 {
309 return value && OdRxValueType::Desc<ValueType>::value() == value->type() ? (ValueType*)(value->valuePtr__<sizeof(ValueType) <= 24>()) : 0;
310 }
311
321 template<typename ValueType>
322 friend ValueType * rxenum_cast(OdRxValue * value) throw()
323 {
324 ODA_ASSERT(value == NULL || value->isVaries() || value->type().isEnum());
325 return value &&
326 value->type().isEnum() &&
327 OdRxValueType::Desc<ValueType>::value() == value->type().enumeration()->getAt(0).type() ? (ValueType*)(value->valuePtr__<sizeof(ValueType) <= 24>()) : 0;
328 }
329
338 template<typename ValueType>
339 OdRxValue& operator=(const ValueType & rhs) throw()
340 {
341 *this = OdRxValue(rhs);
342 return *this;
343 }
344
354 template<typename ValueType>
355 friend inline const ValueType * rxvalue_cast(const OdRxValue * value) throw()
356 {
357 return rxvalue_cast<ValueType>(const_cast<OdRxValue*>(value));
358 }
359
369 template<typename ValueType>
370 friend inline const ValueType * rxenum_cast(const OdRxValue * value) throw()
371 {
372 return rxenum_cast<ValueType>(const_cast<OdRxValue*>(value));
373 }
374
383 static const OdRxValue* unbox(const OdRxObject* pO) throw();
384
393 static OdRxValue* unbox(OdRxObject* pO) throw();
394
402 const OdRxEnumTag* getEnumTag() const throw();
403
413 size_t serializeOut(void* pBytes, size_t& maxBytesToWrite) const;
414
424 size_t serializeIn(const void* pBytes, size_t maxBytesToRead);
425
432 template<typename ValueType>
433 void operator << (const ValueType &val)
434 {
435 *this = val;
436 }
437
448 template<typename ValueType>
449 bool operator >> (ValueType &val) const
450 {
452 {
453 const ValueType *pVal = rxvalue_cast<ValueType>(this);
454 if (pVal)
455 {
456 val = *pVal;
457 return true;
458 }
459 }
460 else
461 {
462 OdRxValue subVal;
463 if (m_type.toValueType(OdRxValueType::Desc<ValueType>::value(), *this, subVal) ||
464 OdRxValueType::Desc<ValueType>::value().fromValueType(*this, subVal))
465 {
466 const ValueType *pVal = rxvalue_cast<ValueType>(&subVal);
467 if (pVal)
468 {
469 val = *pVal;
470 return true;
471 }
472 }
473 }
474 return false;
475 }
476
477 //DOM-IGNORE-BEGIN
478#ifdef _MSC_VER
479#pragma region private
480#endif
481private:
482 bool isInlined() const
483 {
484 return type().size() <= sizeof(m_value);
485 }
486 const void* nonInlineValuePtr() const { return m_value.m_ptr; }
487 void* nonInlineValuePtr() { return m_value.m_ptr; }
488 const void* inlineValuePtr() const { return &m_value; }
489 void* inlineValuePtr() { return &m_value; }
490 const void* valuePtr() const
491 {
492 if (isInlined())
493 return inlineValuePtr();
494 else
495 return nonInlineValuePtr();
496 }
497 template <bool Inlined>
498 void* valuePtr__();
499 template <bool Inlined>
500 void initBlittable(const void* value, size_t size);
501
502 template<typename T, bool inlined>
503 class InitNonBlittable
504 {
505 public:
506 static void init(OdRxValue& rxValue, const T& value);
507 };
508 template<typename T>
509 class InitNonBlittable<T, true>
510 {
511 public:
512 static void init(OdRxValue& rxValue, const T& value);
513 };
514 template<typename T>
515 class InitNonBlittable<T, false>
516 {
517 public:
518 static void init(OdRxValue& rxValue, const T& value);
519 };
520
521 template <typename T>
522 void initNonBlittable(const T& value)
523 {
524 InitNonBlittable<T, sizeof(value) <= sizeof(m_value) >::init(*this, value);
525 }
526
527 void init(const OdRxValue& rhs, bool realloc)
528 {
529 bool blittable = type().isBlittable();
530 bool inlined = isInlined();
531 if (blittable && inlined)
532 {
533 memcpy(&m_value, &rhs.m_value, sizeof(m_value));
534 return;
535 }
536 /*
537 inlined,non-blittable
538 non-inlined, non-blittable
539 non-inlined, blittable
540 */
541 if (inlined)
542 type().nonBlittable()->construct(inlineValuePtr(), rhs.inlineValuePtr());
543 else
544 setNonInlineValue(rhs.nonInlineValuePtr(), blittable, false, realloc);
545 }
546 void setNonInlineValue(const void* value, bool blittable, bool assignment, bool realloc)
547 {
548 ODA_ASSERT(blittable == type().isBlittable());
549 ODA_ASSERT(!isInlined());
550 unsigned int newSize = type().size();
551 realloc = realloc || assignment;
552 if (realloc)
553 {
554 size_t oldsize = *(((size_t*)m_value.m_ptr) - 1);
555 if (oldsize != newSize)
556 {
557 m_value.m_ptr = reallocate(newSize, m_value.m_ptr);
558 assignment = false;
559 }
560 }
561 else
562 m_value.m_ptr = allocate(newSize);
563
564 if (blittable)
565 memcpy(nonInlineValuePtr(), value, newSize);
566 else if (assignment)
567 type().nonBlittable()->assign(nonInlineValuePtr(), value);
568 else
569 type().nonBlittable()->construct(nonInlineValuePtr(), value);
570 }
571 OdRxValue(const OdRxValue& rhs, bool realloc)
572 :m_type(rhs.m_type)
573 {
574 init(rhs, realloc);
575 }
576 const OdRxValueType& m_type;
577#if (OD_SIZEOF_PTR == 4)
578 OdInt32 padding;
579#endif
580 union InlineStorage
581 {
582 double m_point[3];
583 void* m_ptr;
584 char m_int8;
585 short m_int16;
586 int m_int32;
587 OdInt64 m_int64;
588 float m_real32;
589 double m_real64;
590 } m_value;
591 void* allocate(size_t size) const;
592 void* reallocate(size_t size, void* p) const;
593 void deallocate(void* p) const;
594};
595#ifdef _MSC_VER
596#pragma endregion private
597#endif
598//DOM-IGNORE-END
599
608template <class T> OdRxValue createOdRxValue() { T val; return OdRxValue(val); }
609
610ODA_ASSUME(sizeof(OdRxValue) == 32); //each OdRxValue instance is 32 bytes long (on both 32 and 64 bit)
611
612//DOM-IGNORE-BEGIN
616template<>
617inline const void* rxvalue_cast<void>(const OdRxValue * value) throw()
618{
619 return value ? value->valuePtr() : 0;
620}
621
622template<>
623inline void* OdRxValue::valuePtr__<true>()
624{
625 ODA_ASSERT(isInlined());
626 return inlineValuePtr();
627}
628
632template <>
633inline void* OdRxValue::valuePtr__<false>()
634{
635 ODA_ASSERT(!isInlined());
636 return nonInlineValuePtr();
637}
638
642template <>
643inline void OdRxValue::initBlittable<true>(const void* value, size_t size)
644{
645 ODA_ASSERT(type().isBlittable());
646 ODA_ASSERT(isInlined());
647 memcpy(inlineValuePtr(), value, size);
648}
649template <>
650inline void OdRxValue::initBlittable<false>(const void* value, size_t size)
651{
652 ODA_ASSERT(type().isBlittable());
653 ODA_ASSERT(!isInlined());
654 m_value.m_ptr = allocate(size);
655 memcpy(nonInlineValuePtr(), value, size);
656}
657
661template<typename T>
662inline void OdRxValue::InitNonBlittable< T, true>::init(OdRxValue& rxValue, const T& value)
663{
664 //call global placement new defined above so that we can call copy constructor
665 ::new ((OdRxValueStorage*)(rxValue.inlineValuePtr())) T(value);
666}
667
671template<typename T>
672inline void OdRxValue::InitNonBlittable< T, false>::init(OdRxValue& rxValue, const T& value)
673{
674 rxValue.setNonInlineValue(&value, false, false, false);
675}
676//DOM-IGNORE-END
677
678class OdRxBoxedValue;
679
684
690{
691public:
692 //DOM-IGNORE-BEGIN
694 //DOM-IGNORE-END
695
702 virtual const OdRxValue* value() const = 0;
703
710 virtual OdRxValue* value() = 0;
711
722
730
736 virtual void copyFrom(const OdRxObject* other) ODRX_OVERRIDE;
737
746 virtual bool isEqualTo(const OdRxObject * other) const ODRX_OVERRIDE;
747
757 virtual OdRx::Ordering comparedTo(const OdRxObject * other) const ODRX_OVERRIDE;
758};
759
765{
766 OdRxValue& m_value;
767public:
768 //DOM-IGNORE-BEGIN
770 //DOM-IGNORE-END
771
778
785 virtual const OdRxValue* value() const ODRX_OVERRIDE { return &m_value; }
786
793 virtual OdRxValue* value() ODRX_OVERRIDE { return &m_value; }
794};
795
796// Type declarations follow:
797//
798
799#define ODRX_DECLARE_VALUE_TYPE(type, attribute)\
800template<> struct OdRxValueType::Desc<type>\
801{\
802 attribute static const OdRxValueType& value() throw();\
803 attribute static void del();\
804};\
805template<> OdRxValue::OdRxValue(const type&) throw();
806
811
812
816
817
821
822
826
827
831
832
836
837
841
842
846
847
851
852
856
857
861
862
866
867
871
872
875ODRX_DECLARE_VALUE_TYPE(unsigned long long, FIRSTDLL_EXPORT)
876
877
881
882
885template<> struct OdRxValueType::Desc<const OdChar*>
886{
887 FIRSTDLL_EXPORT static const OdRxValueType& value() throw();
888 FIRSTDLL_EXPORT static void del();
889};
890template<> OdRxValue::OdRxValue(const OdChar* const &) throw();
891
896
901
906
911
916
921
926
931
936
941
946
951
956
961
966
971
972class OdRxClass;
973
977template<> struct OdRxValueType::Desc<OdRxClass*>
978{
979 FIRSTDLL_EXPORT static const OdRxValueType& value() throw();
980 FIRSTDLL_EXPORT static void del();
981};
982
983class OdAnsiString;
984
989
990class OdString;
991
996
1001
1006
1011
1016
1021
1025template<> struct OdRxValueType::Desc<const char*>
1026{
1027 FIRSTDLL_EXPORT static const OdRxValueType& value() throw();
1028 FIRSTDLL_EXPORT static void del();
1029};
1030template<> OdRxValue::OdRxValue(const char* const &) throw();
1031
1032#include "TD_PackPop.h"
1033#endif // _ODRXVALUE_INCLUDED_
#define ODA_ASSERT(exp)
Definition: DebugStuff.h:57
#define ODA_ASSUME(expr)
Definition: DebugStuff.h:180
true
Definition: DimVarDefs.h:2046
false
Definition: DimVarDefs.h:165
bool operator==(T left, const OdGiVariant::EnumType right)
Definition: GiVariant.h:397
int OdInt32
#define ODRX_ABSTRACT
#define ODRX_OVERRIDE
wchar_t OdChar
#define FIRSTDLL_EXPORT
Definition: RootExport.h:39
ValueType * rxvalue_cast(OdRxValue *value)
Definition: RxValue.h:307
OdRxValue createOdRxValue()
Definition: RxValue.h:608
OdSmartPtr< OdRxBoxedValue > OdRxBoxedValuePtr
Definition: RxValue.h:683
const void * rxvalue_cast< void >(const OdRxValue *value)
Definition: RxValue.h:617
#define ODRX_DECLARE_VALUE_TYPE(type, attribute)
Definition: RxValue.h:799
ValueType * rxenum_cast(OdRxValue *value)
Definition: RxValue.h:322
Definition: Int64.h:43
ODRX_DECLARE_MEMBERS(OdRxBoxedValue)
virtual OdRxValue * value()=0
virtual const OdRxValue * value() const =0
static OdRxBoxedValuePtr newBoxedValueOnHeap(const OdRxValue &value)
virtual OdRxObjectPtr clone() const ODRX_OVERRIDE
OdRxBoxedValueOnStack(OdRxValue &value)
ODRX_DECLARE_MEMBERS(OdRxBoxedValueOnStack)
virtual const OdRxValue * value() const ODRX_OVERRIDE
Definition: RxValue.h:785
virtual OdRxValue * value() ODRX_OVERRIDE
Definition: RxValue.h:793
const OdRxValueType & type() const
bool operator!=(const OdRxValue &value) const
Definition: RxValue.h:264
friend ValueType * rxvalue_cast(OdRxValue *value)
Definition: RxValue.h:307
OdRxValue(const OdRxValue &rhs)
Definition: RxValue.h:105
static const OdRxValue & empty()
bool operator==(const OdRxValue &value) const
Definition: RxValue.h:249
OdRxValue(const OdRxValueType &type, const OdRxValue &value)
Definition: RxValue.h:119
~OdRxValue()
Definition: RxValue.h:171
OdRxValue & operator=(const ValueType &rhs)
Definition: RxValue.h:339
friend const ValueType * rxenum_cast(const OdRxValue *value)
Definition: RxValue.h:370
static const OdRxValue * unbox(const OdRxObject *pO)
OdRxValue()
Definition: RxValue.h:94
const OdRxEnumTag * getEnumTag() const
const OdRxValueType & type() const
Definition: RxValue.h:187
friend ValueType * rxenum_cast(OdRxValue *value)
Definition: RxValue.h:322
bool isEmpty() const
Definition: RxValue.h:198
static const OdRxValue & varies()
const OdAnsiString typePath() const
Definition: RxValue.h:277
OdRxValue(const ValueType &value)
Definition: RxValue.h:289
friend const ValueType * rxvalue_cast(const OdRxValue *value)
Definition: RxValue.h:355
static OdRxValue * unbox(OdRxObject *pO)
const OdRxValue & operator=(const OdRxValue &rhs)
Definition: RxValue.h:129
virtual const IOdRxEnumeration * enumeration() const
Definition: RxValueType.h:263
GLsizeiptr size
Definition: gles2_ext.h:182
GLuint GLsizei GLsizei GLint GLenum * type
Definition: gles2_ext.h:274
GLint GLint GLint GLsizei GLsizei GLenum format
Definition: gles2_ext.h:111
GLsizei const GLfloat * value
Definition: gles2_ext.h:302
Definition: RxDefs.h:36
virtual const OdRxEnumTag & getAt(int index) const =0
static FIRSTDLL_EXPORT const OdRxValueType & value()
static FIRSTDLL_EXPORT const OdRxValueType & value()
static FIRSTDLL_EXPORT const OdRxValueType & value()
static const OdRxValueType & value()