CFx SDK Documentation 2026 SP0
Loading...
Searching...
No Matches
RxValue.h
Go to the documentation of this file.
1
2// Copyright (C) 2002-2024, 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-2024 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#include "UInt64Array.h"
36#include "Int64Array.h"
37
46template<typename ValueType> ValueType* rxvalue_cast(OdRxValue* value) throw();
47
58template<typename ValueType> ValueType * rxenum_cast(OdRxValue * value) throw();
59
69template<typename ValueType> const ValueType * rxvalue_cast(const OdRxValue * value) throw();
70
81template<typename ValueType> const ValueType * rxenum_cast(const OdRxValue * value) throw();
82
83#include "TD_PackPush.h"
84
91{
92public:
96 OdRxValue() throw() : m_type(OdRxValueType::Desc<void>::value())
97 {
98 memset(&m_value, 0, sizeof(m_value));
99 }
100
107 OdRxValue(const OdRxValue& rhs) throw() : m_type(rhs.m_type)
108 {
109 init(rhs, false);
110 }
111
121 OdRxValue(const OdRxValueType& type, const OdRxValue& value) throw() : m_type(type)
122 {
123 init(value, false);
124 }
125
131 const OdRxValue& operator=(const OdRxValue& rhs) throw()
132 {
133 if (this == &rhs)
134 return *this;
135 if (type() != rhs.type())
136 {
137 if (!type().isBlittable())
138 type().nonBlittable()->destruct(valuePtr());
139 if (!isInlined() && rhs.isInlined())
140 deallocate(m_value.m_ptr);
141#ifdef _MSC_VER
142#pragma push_macro("new")
143#undef new
144#endif
145 ::new ((OdRxValueStorage*)this) OdRxValue(rhs, !isInlined() && !rhs.isInlined());
146#ifdef _MSC_VER
147#pragma pop_macro("new")
148#endif
149 return *this;
150 }
151 bool blittable = rhs.type().isBlittable();
152 bool inlined = rhs.isInlined();
153 if (blittable && inlined)
154 {
155 memcpy(this, &rhs, sizeof(OdRxValue));
156 return *this;
157 }
158 /*
159 inlined,non-blittable
160 non-inlined, non-blittable
161 non-inlined, blittable
162 */
163 if (inlined)
164 type().nonBlittable()->assign(inlineValuePtr(), rhs.inlineValuePtr());
165 else
166 setNonInlineValue(rhs.nonInlineValuePtr(), blittable, true, true);
167 return *this;
168 }
169
173 ~OdRxValue() throw()
174 {
175 //if the type is non-blittable then we must call destructor
176 if (!type().isBlittable())
177 type().nonBlittable()->destruct(valuePtr());
178 //finally free memory if necessary
179 if (!isInlined())
180 deallocate(m_value.m_ptr);
181 }
182
189 const OdRxValueType& type() const throw()
190 {
191 return m_type;
192 }
193
200 bool isEmpty() const throw() { return *this == empty(); }
201
208 static const OdRxValue& empty() throw();
209
217 bool isVaries() const throw() { return *this == varies(); }
218
225 static const OdRxValue& varies() throw();
226
238 OdString toString(OdRxValueType::StringFormat format = OdRxValueType::kStringFormatGlobal) const throw()
239 {
240 return m_type.toString(valuePtr(), format);
241 }
242
251 bool operator==(const OdRxValue& value) const throw()
252 {
253 if (type() != value.type())
254 return false;
255 return type().equalTo(valuePtr(), value.valuePtr());
256 }
257
266 bool operator!=(const OdRxValue& value) const throw()
267 {
268 return !(operator == (value));
269 }
270
279 const OdAnsiString typePath() const
280 {
281 return m_type.typePath(*this);
282 }
283
290 template <typename ValueType>
291 OdRxValue(const ValueType& value) throw()
293 {
294 //this should have been specialized otherwise
295 ODA_ASSERT(m_type.isBlittable());
296 initBlittable<sizeof(ValueType) <= 24>(&value, sizeof(ValueType));
297 }
298
308 template<typename ValueType>
309 friend ValueType* rxvalue_cast(OdRxValue* value) throw()
310 {
311 return value && OdRxValueType::Desc<ValueType>::value() == value->type() ? (ValueType*)(value->valuePtr__<sizeof(ValueType) <= 24>()) : 0;
312 }
313
323 template<typename ValueType>
324 friend ValueType * rxenum_cast(OdRxValue * value) throw()
325 {
326 ODA_ASSERT(value == NULL || value->isVaries() || value->type().isEnum());
327 return value &&
328 value->type().isEnum() &&
329 OdRxValueType::Desc<ValueType>::value() == value->type().enumeration()->getAt(0).type() ? (ValueType*)(value->valuePtr__<sizeof(ValueType) <= 24>()) : 0;
330 }
331
340 template<typename ValueType>
341 OdRxValue& operator=(const ValueType & rhs) throw()
342 {
343 *this = OdRxValue(rhs);
344 return *this;
345 }
346
356 template<typename ValueType>
357 friend inline const ValueType * rxvalue_cast(const OdRxValue * value) throw()
358 {
359 return rxvalue_cast<ValueType>(const_cast<OdRxValue*>(value));
360 }
361
371 template<typename ValueType>
372 friend inline const ValueType * rxenum_cast(const OdRxValue * value) throw()
373 {
374 return rxenum_cast<ValueType>(const_cast<OdRxValue*>(value));
375 }
376
385 static const OdRxValue* unbox(const OdRxObject* pO) throw();
386
395 static OdRxValue* unbox(OdRxObject* pO) throw();
396
404 const OdRxEnumTag* getEnumTag() const throw();
405
415 size_t serializeOut(void* pBytes, size_t& maxBytesToWrite) const;
416
426 size_t serializeIn(const void* pBytes, size_t maxBytesToRead);
427
434 template<typename ValueType>
435 void operator << (const ValueType &val)
436 {
437 *this = val;
438 }
439
450 template<typename ValueType>
451 bool operator >> (ValueType &val) const
452 {
454 {
455 const ValueType *pVal = rxvalue_cast<ValueType>(this);
456 if (pVal)
457 {
458 val = *pVal;
459 return true;
460 }
461 }
462 else
463 {
464 OdRxValue subVal;
465 if (m_type.toValueType(OdRxValueType::Desc<ValueType>::value(), *this, subVal) ||
466 OdRxValueType::Desc<ValueType>::value().fromValueType(*this, subVal))
467 {
468 const ValueType *pVal = rxvalue_cast<ValueType>(&subVal);
469 if (pVal)
470 {
471 val = *pVal;
472 return true;
473 }
474 }
475 }
476 return false;
477 }
478
479 //DOM-IGNORE-BEGIN
480#ifdef _MSC_VER
481#pragma region private
482#endif
483private:
484 bool isInlined() const
485 {
486 return type().size() <= sizeof(m_value);
487 }
488 const void* nonInlineValuePtr() const { return m_value.m_ptr; }
489 void* nonInlineValuePtr() { return m_value.m_ptr; }
490 const void* inlineValuePtr() const { return &m_value; }
491 void* inlineValuePtr() { return &m_value; }
492 const void* valuePtr() const
493 {
494 if (isInlined())
495 return inlineValuePtr();
496 else
497 return nonInlineValuePtr();
498 }
499 template <bool Inlined>
500 void* valuePtr__();
501 template <bool Inlined>
502 void initBlittable(const void* value, size_t size);
503
504 template<typename T, bool inlined>
505 class InitNonBlittable
506 {
507 public:
508 static void init(OdRxValue& rxValue, const T& value);
509 };
510 template<typename T>
511 class InitNonBlittable<T, true>
512 {
513 public:
514 static void init(OdRxValue& rxValue, const T& value);
515 };
516 template<typename T>
517 class InitNonBlittable<T, false>
518 {
519 public:
520 static void init(OdRxValue& rxValue, const T& value);
521 };
522
523 template <typename T>
524 void initNonBlittable(const T& value)
525 {
526 InitNonBlittable<T, sizeof(value) <= sizeof(m_value) >::init(*this, value);
527 }
528
529 void init(const OdRxValue& rhs, bool realloc)
530 {
531 bool blittable = type().isBlittable();
532 bool inlined = isInlined();
533 if (blittable && inlined)
534 {
535 memcpy(&m_value, &rhs.m_value, sizeof(m_value));
536 return;
537 }
538 /*
539 inlined,non-blittable
540 non-inlined, non-blittable
541 non-inlined, blittable
542 */
543 if (inlined)
544 type().nonBlittable()->construct(inlineValuePtr(), rhs.inlineValuePtr());
545 else
546 setNonInlineValue(rhs.nonInlineValuePtr(), blittable, false, realloc);
547 }
548 void setNonInlineValue(const void* value, bool blittable, bool assignment, bool realloc)
549 {
550 ODA_ASSERT(blittable == type().isBlittable());
551 ODA_ASSERT(!isInlined());
552 unsigned int newSize = type().size();
553 realloc = realloc || assignment;
554 if (realloc)
555 {
556 size_t oldsize = *(((size_t*)m_value.m_ptr) - 1);
557 if (oldsize != newSize)
558 {
559 m_value.m_ptr = reallocate(newSize, m_value.m_ptr);
560 assignment = false;
561 }
562 }
563 else
564 m_value.m_ptr = allocate(newSize);
565
566 if (blittable)
567 memcpy(nonInlineValuePtr(), value, newSize);
568 else if (assignment)
569 type().nonBlittable()->assign(nonInlineValuePtr(), value);
570 else
571 type().nonBlittable()->construct(nonInlineValuePtr(), value);
572 }
573 OdRxValue(const OdRxValue& rhs, bool realloc)
574 :m_type(rhs.m_type)
575 {
576 init(rhs, realloc);
577 }
578 const OdRxValueType& m_type;
579#if (OD_SIZEOF_PTR == 4)
580 OdInt32 padding;
581#endif
582 union InlineStorage
583 {
584 double m_point[3];
585 void* m_ptr;
586 char m_int8;
587 short m_int16;
588 int m_int32;
589 OdInt64 m_int64;
590 float m_real32;
591 double m_real64;
592 } m_value;
593 void* allocate(size_t size) const;
594 void* reallocate(size_t size, void* p) const;
595 void deallocate(void* p) const;
596};
597#ifdef _MSC_VER
598#pragma endregion private
599#endif
600//DOM-IGNORE-END
601
610template <class T> OdRxValue createOdRxValue() { T val; return OdRxValue(val); }
611
612ODA_ASSUME(sizeof(OdRxValue) == 32); //each OdRxValue instance is 32 bytes long (on both 32 and 64 bit)
613
614//DOM-IGNORE-BEGIN
618template<>
619inline const void* rxvalue_cast<void>(const OdRxValue * value) throw()
620{
621 return value ? value->valuePtr() : 0;
622}
623
624template<>
625inline void* OdRxValue::valuePtr__<true>()
626{
627 ODA_ASSERT(isInlined());
628 return inlineValuePtr();
629}
630
634template <>
635inline void* OdRxValue::valuePtr__<false>()
636{
637 ODA_ASSERT(!isInlined());
638 return nonInlineValuePtr();
639}
640
644template <>
645inline void OdRxValue::initBlittable<true>(const void* value, size_t size)
646{
647 ODA_ASSERT(type().isBlittable());
648 ODA_ASSERT(isInlined());
649 memcpy(inlineValuePtr(), value, size);
650}
651template <>
652inline void OdRxValue::initBlittable<false>(const void* value, size_t size)
653{
654 ODA_ASSERT(type().isBlittable());
655 ODA_ASSERT(!isInlined());
656 m_value.m_ptr = allocate(size);
657 memcpy(nonInlineValuePtr(), value, size);
658}
659
663template<typename T>
664inline void OdRxValue::InitNonBlittable< T, true>::init(OdRxValue& rxValue, const T& value)
665{
666 //call global placement new defined above so that we can call copy constructor
667 ::new ((OdRxValueStorage*)(rxValue.inlineValuePtr())) T(value);
668}
669
673template<typename T>
674inline void OdRxValue::InitNonBlittable< T, false>::init(OdRxValue& rxValue, const T& value)
675{
676 rxValue.setNonInlineValue(&value, false, false, false);
677}
678//DOM-IGNORE-END
679
680class OdRxBoxedValue;
681
686
692{
693public:
694 //DOM-IGNORE-BEGIN
696 //DOM-IGNORE-END
697
704 virtual const OdRxValue* value() const = 0;
705
712 virtual OdRxValue* value() = 0;
713
724
732
738 virtual void copyFrom(const OdRxObject* other) ODRX_OVERRIDE;
739
748 virtual bool isEqualTo(const OdRxObject * other) const ODRX_OVERRIDE;
749
759 virtual OdRx::Ordering comparedTo(const OdRxObject * other) const ODRX_OVERRIDE;
760};
761
767{
768 OdRxValue& m_value;
769public:
770 //DOM-IGNORE-BEGIN
772 //DOM-IGNORE-END
773
780
787 virtual const OdRxValue* value() const ODRX_OVERRIDE { return &m_value; }
788
795 virtual OdRxValue* value() ODRX_OVERRIDE { return &m_value; }
796};
797
798// Type declarations follow:
799//
800
801#define ODRX_DECLARE_VALUE_TYPE(type, attribute)\
802template<> struct OdRxValueType::Desc<type>\
803{\
804 attribute static const OdRxValueType& value() throw();\
805 attribute static void del();\
806};\
807template<> OdRxValue::OdRxValue(const type&) throw();
808
813
814
818
819
823
824
828
829
833
834
838
839
843
844
848
849
853
854
858
859
863
864
868
869
873
874
877ODRX_DECLARE_VALUE_TYPE(unsigned long long, FIRSTDLL_EXPORT)
878
879
883
884
887template<> struct OdRxValueType::Desc<const OdChar*>
888{
889 FIRSTDLL_EXPORT static const OdRxValueType& value() throw();
890 FIRSTDLL_EXPORT static void del();
891};
892template<> OdRxValue::OdRxValue(const OdChar* const &) throw();
893
898
903
908
913
918
923
928
933
938
943
948
953
958
963
968
973
978
983
988
993
998
1003
1004class OdRxClass;
1005
1009template<> struct OdRxValueType::Desc<OdRxClass*>
1010{
1011 FIRSTDLL_EXPORT static const OdRxValueType& value() throw();
1012 FIRSTDLL_EXPORT static void del();
1013};
1014
1015class OdAnsiString;
1016
1021
1022class OdString;
1023
1028
1033
1038
1043
1048
1053
1057template<> struct OdRxValueType::Desc<const char*>
1058{
1059 FIRSTDLL_EXPORT static const OdRxValueType& value() throw();
1060 FIRSTDLL_EXPORT static void del();
1061};
1062template<> OdRxValue::OdRxValue(const char* const &) throw();
1063
1064#include "TD_PackPop.h"
1065#endif // _ODRXVALUE_INCLUDED_
#define ODA_ASSERT(exp)
Definition DebugStuff.h:57
#define ODA_ASSUME(expr)
Definition DebugStuff.h:180
true
false
Definition DimVarDefs.h:165
OdArray< double, OdMemoryAllocator< double > > OdGeDoubleArray
bool operator==(T left, const OdGiVariant::EnumType right)
Definition GiVariant.h:399
OdArray< OdInt64, OdMemoryAllocator< OdInt64 > > OdInt64Array
Definition Int64Array.h:34
OdArray< int, OdMemoryAllocator< int > > OdIntArray
Definition IntArray.h:35
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:309
OdRxValue createOdRxValue()
Definition RxValue.h:610
OdSmartPtr< OdRxBoxedValue > OdRxBoxedValuePtr
Definition RxValue.h:685
const void * rxvalue_cast< void >(const OdRxValue *value)
Definition RxValue.h:619
#define ODRX_DECLARE_VALUE_TYPE(type, attribute)
Definition RxValue.h:801
ValueType * rxenum_cast(OdRxValue *value)
Definition RxValue.h:324
OdArray< OdUInt64, OdMemoryAllocator< OdUInt64 > > OdUInt64Array
ODRX_DECLARE_MEMBERS(OdRxBoxedValue)
virtual OdRx::Ordering comparedTo(const OdRxObject *other) const ODRX_OVERRIDE
virtual OdRxValue * value()=0
virtual const OdRxValue * value() const =0
virtual bool isEqualTo(const OdRxObject *other) const ODRX_OVERRIDE
static OdRxBoxedValuePtr newBoxedValueOnHeap(const OdRxValue &value)
virtual OdRxObjectPtr clone() const ODRX_OVERRIDE
virtual void copyFrom(const OdRxObject *other) ODRX_OVERRIDE
OdRxBoxedValueOnStack(OdRxValue &value)
ODRX_DECLARE_MEMBERS(OdRxBoxedValueOnStack)
virtual const OdRxValue * value() const ODRX_OVERRIDE
Definition RxValue.h:787
virtual OdRxValue * value() ODRX_OVERRIDE
Definition RxValue.h:795
OdRxClass(OdRxClassImpl *)
bool operator!=(const OdRxValue &value) const
Definition RxValue.h:266
friend ValueType * rxvalue_cast(OdRxValue *value)
Definition RxValue.h:309
OdRxValue(const OdRxValue &rhs)
Definition RxValue.h:107
static const OdRxValue & empty()
bool operator==(const OdRxValue &value) const
Definition RxValue.h:251
OdRxValue(const OdRxValueType &type, const OdRxValue &value)
Definition RxValue.h:121
size_t serializeIn(const void *pBytes, size_t maxBytesToRead)
~OdRxValue()
Definition RxValue.h:173
OdRxValue & operator=(const ValueType &rhs)
Definition RxValue.h:341
friend const ValueType * rxenum_cast(const OdRxValue *value)
Definition RxValue.h:372
static const OdRxValue * unbox(const OdRxObject *pO)
OdRxValue()
Definition RxValue.h:96
OdString toString(OdRxValueType::StringFormat format=OdRxValueType::kStringFormatGlobal) const
Definition RxValue.h:238
bool isVaries() const
Definition RxValue.h:217
const OdRxEnumTag * getEnumTag() const
const OdRxValueType & type() const
Definition RxValue.h:189
friend ValueType * rxenum_cast(OdRxValue *value)
Definition RxValue.h:324
bool isEmpty() const
Definition RxValue.h:200
static const OdRxValue & varies()
const OdAnsiString typePath() const
Definition RxValue.h:279
OdRxValue(const ValueType &value)
Definition RxValue.h:291
friend const ValueType * rxvalue_cast(const OdRxValue *value)
Definition RxValue.h:357
static OdRxValue * unbox(OdRxObject *pO)
size_t serializeOut(void *pBytes, size_t &maxBytesToWrite) const
const OdRxValue & operator=(const OdRxValue &rhs)
Definition RxValue.h:131
OdRxValueType(const OdRxValueType &)=delete
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
static FIRSTDLL_EXPORT const OdRxValueType & value()
static FIRSTDLL_EXPORT void del()
static FIRSTDLL_EXPORT const OdRxValueType & value()
static FIRSTDLL_EXPORT void del()
static FIRSTDLL_EXPORT void del()
static FIRSTDLL_EXPORT const OdRxValueType & value()
static const OdRxValueType & value()