CFx SDK Documentation  2023 SP0
RxValue.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2018, 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 Teigha(R) software pursuant to a license
16 // agreement with Open Design Alliance.
17 // Teigha(R) Copyright (C) 2002-2018 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 
39 template<typename ValueType> ValueType* rxvalue_cast(OdRxValue* value) throw();
40 
44 template<typename ValueType> ValueType * rxenum_cast(OdRxValue * value) throw();
45 
49 template<typename ValueType> const ValueType * rxvalue_cast(const OdRxValue * value) throw();
50 
54 template<typename ValueType> const ValueType * rxenum_cast(const OdRxValue * value) throw();
55 
56 #include "TD_PackPush.h"
57 
64 {
65 public:
69  OdRxValue() throw() : m_type(OdRxValueType::Desc<void>::value())
70  {
71  memset(&m_value, 0, sizeof(m_value));
72  }
73 
77  OdRxValue(const OdRxValue& rhs) throw() : m_type(rhs.m_type)
78  {
79  init(rhs, false);
80  }
81 
86  OdRxValue(const OdRxValueType& type, const OdRxValue& value) throw() : m_type(type)
87  {
88  init(value, false);
89  }
90 
94  const OdRxValue& operator=(const OdRxValue& rhs) throw()
95  {
96  if (this == &rhs)
97  return *this;
98  if (type() != rhs.type())
99  {
100  if (!type().isBlittable())
101  type().nonBlittable()->destruct(valuePtr());
102  if (!isInlined() && rhs.isInlined())
103  deallocate(m_value.m_ptr);
104 #ifdef _MSC_VER
105 #pragma push_macro("new")
106 #undef new
107 #endif
108  ::new ((OdRxValueStorage*)this) OdRxValue(rhs, !isInlined() && !rhs.isInlined());
109 #ifdef _MSC_VER
110 #pragma pop_macro("new")
111 #endif
112  return *this;
113  }
114  bool blittable = rhs.type().isBlittable();
115  bool inlined = rhs.isInlined();
116  if (blittable && inlined)
117  {
118  memcpy(this, &rhs, sizeof(OdRxValue));
119  return *this;
120  }
121  /*
122  inlined,non-blittable
123  non-inlined, non-blittable
124  non-inlined, blittable
125  */
126  if (inlined)
127  type().nonBlittable()->assign(inlineValuePtr(), rhs.inlineValuePtr());
128  else
129  setNonInlineValue(rhs.nonInlineValuePtr(), blittable, true, true);
130  return *this;
131  }
132 
133  ~OdRxValue() throw()
134  {
135  //if the type is non-blittable then we must call destructor
136  if (!type().isBlittable())
137  type().nonBlittable()->destruct(valuePtr());
138  //finally free memory if necessary
139  if (!isInlined())
140  deallocate(m_value.m_ptr);
141  }
142 
146  const OdRxValueType& type() const throw()
147  {
148  return m_type;
149  }
150 
154  bool isEmpty() const throw() { return *this == empty(); }
155 
159  static const OdRxValue& empty() throw();
160 
164  bool isVaries() const throw() { return *this == varies(); }
165 
169  static const OdRxValue& varies() throw();
170 
174  OdString toString(OdRxValueType::StringFormat format = OdRxValueType::kStringFormatGlobal) const throw()
175  {
176  return m_type.toString(valuePtr(), format);
177  }
178 
182  bool operator==(const OdRxValue& value) const throw()
183  {
184  if (type() != value.type())
185  return false;
186  return type().equalTo(valuePtr(), value.valuePtr());
187  }
188 
192  bool operator!=(const OdRxValue& value) const throw()
193  {
194  return !(operator == (value));
195  }
196 
202  const OdAnsiString typePath() const
203  {
204  return m_type.typePath(*this);
205  }
206 
210  template <typename ValueType>
211  OdRxValue(const ValueType& value) throw()
213  {
214  //this should have been specialized otherwise
215  ODA_ASSERT(m_type.isBlittable());
216  initBlittable<sizeof(ValueType) <= 24>(&value, sizeof(ValueType));
217  }
218 
222  template<typename ValueType>
223  friend ValueType* rxvalue_cast(OdRxValue* value) throw()
224  {
225  return value && OdRxValueType::Desc<ValueType>::value() == value->type() ? (ValueType*)(value->valuePtr__<sizeof(ValueType) <= 24>()) : 0;
226  }
227 
231  template<typename ValueType>
232  friend ValueType * rxenum_cast(OdRxValue * value) throw()
233  {
234  ODA_ASSERT(value == NULL || value->isVaries() || value->type().isEnum());
235  return value &&
236  value->type().isEnum() &&
237  OdRxValueType::Desc<ValueType>::value() == value->type().enumeration()->getAt(0).type() ? (ValueType*)(value->valuePtr__<sizeof(ValueType) <= 24>()) : 0;
238  }
239 
243  template<typename ValueType>
244  OdRxValue& operator=(const ValueType & rhs) throw()
245  {
246  *this = OdRxValue(rhs);
247  return *this;
248  }
249 
253  template<typename ValueType>
254  friend inline const ValueType * rxvalue_cast(const OdRxValue * value) throw()
255  {
256  return rxvalue_cast<ValueType>(const_cast<OdRxValue*>(value));
257  }
258 
262  template<typename ValueType>
263  friend inline const ValueType * rxenum_cast(const OdRxValue * value) throw()
264  {
265  return rxenum_cast<ValueType>(const_cast<OdRxValue*>(value));
266  }
267 
271  static const OdRxValue* unbox(const OdRxObject* pO) throw();
272 
276  static OdRxValue* unbox(OdRxObject* pO) throw();
277 
281  const OdRxEnumTag* getEnumTag() const throw();
282 
286  size_t serializeOut(void* pBytes, size_t& maxBytesToWrite) const;
287 
291  size_t serializeIn(const void* pBytes, size_t maxBytesToRead);
292 
295  template<typename ValueType>
296  void operator << (const ValueType &val)
297  {
298  *this = val;
299  }
300 
305  template<typename ValueType>
306  bool operator >> (ValueType &val) const
307  {
309  {
310  const ValueType *pVal = rxvalue_cast<ValueType>(this);
311  if (pVal)
312  {
313  val = *pVal;
314  return true;
315  }
316  }
317  else
318  {
319  OdRxValue subVal;
320  if (m_type.toValueType(OdRxValueType::Desc<ValueType>::value(), *this, subVal) ||
321  OdRxValueType::Desc<ValueType>::value().fromValueType(*this, subVal))
322  {
323  const ValueType *pVal = rxvalue_cast<ValueType>(&subVal);
324  if (pVal)
325  {
326  val = *pVal;
327  return true;
328  }
329  }
330  }
331  return false;
332  }
333 
334  //DOM-IGNORE-BEGIN
335 #ifdef _MSC_VER
336 #pragma region private
337 #endif
338 private:
339  bool isInlined() const
340  {
341  return type().size() <= sizeof(m_value);
342  }
343  const void* nonInlineValuePtr() const { return m_value.m_ptr; }
344  void* nonInlineValuePtr() { return m_value.m_ptr; }
345  const void* inlineValuePtr() const { return &m_value; }
346  void* inlineValuePtr() { return &m_value; }
347  const void* valuePtr() const
348  {
349  if (isInlined())
350  return inlineValuePtr();
351  else
352  return nonInlineValuePtr();
353  }
354  template <bool Inlined>
355  void* valuePtr__();
356  template <bool Inlined>
357  void initBlittable(const void* value, size_t size);
358 
359  template<typename T, bool inlined>
360  class InitNonBlittable
361  {
362  public:
363  static void init(OdRxValue& rxValue, const T& value);
364  };
365  template<typename T>
366  class InitNonBlittable<T, true>
367  {
368  public:
369  static void init(OdRxValue& rxValue, const T& value);
370  };
371  template<typename T>
372  class InitNonBlittable<T, false>
373  {
374  public:
375  static void init(OdRxValue& rxValue, const T& value);
376  };
377 
378  template <typename T>
379  void initNonBlittable(const T& value)
380  {
381  InitNonBlittable<T, sizeof(value) <= sizeof(m_value) >::init(*this, value);
382  }
383 
384  void init(const OdRxValue& rhs, bool realloc)
385  {
386  bool blittable = type().isBlittable();
387  bool inlined = isInlined();
388  if (blittable && inlined)
389  {
390  memcpy(&m_value, &rhs.m_value, sizeof(m_value));
391  return;
392  }
393  /*
394  inlined,non-blittable
395  non-inlined, non-blittable
396  non-inlined, blittable
397  */
398  if (inlined)
399  type().nonBlittable()->construct(inlineValuePtr(), rhs.inlineValuePtr());
400  else
401  setNonInlineValue(rhs.nonInlineValuePtr(), blittable, false, realloc);
402  }
403  void setNonInlineValue(const void* value, bool blittable, bool assignment, bool realloc)
404  {
405  ODA_ASSERT(blittable == type().isBlittable());
406  ODA_ASSERT(!isInlined());
407  unsigned int newSize = type().size();
408  realloc = realloc || assignment;
409  if (realloc)
410  {
411  size_t oldsize = *(((size_t*)m_value.m_ptr) - 1);
412  if (oldsize != newSize)
413  {
414  m_value.m_ptr = reallocate(newSize, m_value.m_ptr);
415  assignment = false;
416  }
417  }
418  else
419  m_value.m_ptr = allocate(newSize);
420 
421  if (blittable)
422  memcpy(nonInlineValuePtr(), value, newSize);
423  else if (assignment)
424  type().nonBlittable()->assign(nonInlineValuePtr(), value);
425  else
426  type().nonBlittable()->construct(nonInlineValuePtr(), value);
427  }
428  OdRxValue(const OdRxValue& rhs, bool realloc)
429  :m_type(rhs.m_type)
430  {
431  init(rhs, realloc);
432  }
433  const OdRxValueType& m_type;
434 #if (OD_SIZEOF_PTR == 4)
435  OdInt32 padding;
436 #endif
437  union InlineStorage
438  {
439  double m_point[3];
440  void* m_ptr;
441  char m_int8;
442  short m_int16;
443  int m_int32;
444  OdInt64 m_int64;
445  float m_real32;
446  double m_real64;
447  } m_value;
448  void* allocate(size_t size) const;
449  void* reallocate(size_t size, void* p) const;
450  void deallocate(void* p) const;
451 };
452 #ifdef _MSC_VER
453 #pragma endregion private
454 #endif
455 //DOM-IGNORE-END
456 
461 template <class T> OdRxValue createOdRxValue() { T val; return OdRxValue(val); }
462 
463 ODA_ASSUME(sizeof(OdRxValue) == 32); //each OdRxValue instance is 32 bytes long (on both 32 and 64 bit)
464 
465 //DOM-IGNORE-BEGIN
469 template<>
470 inline const void* rxvalue_cast<void>(const OdRxValue * value) throw()
471 {
472  return value ? value->valuePtr() : 0;
473 }
474 
475 template<>
476 inline void* OdRxValue::valuePtr__<true>()
477 {
478  ODA_ASSERT(isInlined());
479  return inlineValuePtr();
480 }
481 
485 template <>
486 inline void* OdRxValue::valuePtr__<false>()
487 {
488  ODA_ASSERT(!isInlined());
489  return nonInlineValuePtr();
490 }
491 
495 template <>
496 inline void OdRxValue::initBlittable<true>(const void* value, size_t size)
497 {
498  ODA_ASSERT(type().isBlittable());
499  ODA_ASSERT(isInlined());
500  memcpy(inlineValuePtr(), value, size);
501 }
502 template <>
503 inline void OdRxValue::initBlittable<false>(const void* value, size_t size)
504 {
505  ODA_ASSERT(type().isBlittable());
506  ODA_ASSERT(!isInlined());
507  m_value.m_ptr = allocate(size);
508  memcpy(nonInlineValuePtr(), value, size);
509 }
510 
514 template<typename T>
515 inline void OdRxValue::InitNonBlittable< T, true>::init(OdRxValue& rxValue, const T& value)
516 {
517  //call global placement new defined above so that we can call copy constructor
518  ::new ((OdRxValueStorage*)(rxValue.inlineValuePtr())) T(value);
519 }
520 
524 template<typename T>
525 inline void OdRxValue::InitNonBlittable< T, false>::init(OdRxValue& rxValue, const T& value)
526 {
527  rxValue.setNonInlineValue(&value, false, false, false);
528 }
529 //DOM-IGNORE-END
530 
531 class OdRxBoxedValue;
533 
539 {
540 public:
542 
546  virtual const OdRxValue* value() const = 0;
547 
551  virtual OdRxValue* value() = 0;
552 
557 
562 
566  virtual void copyFrom(const OdRxObject* other) ODRX_OVERRIDE;
567 
571  virtual bool isEqualTo(const OdRxObject * other) const ODRX_OVERRIDE;
572 
576  virtual OdRx::Ordering comparedTo(const OdRxObject * other) const ODRX_OVERRIDE;
577 };
578 
584 {
585  OdRxValue& m_value;
586 public:
587  //DOM-IGNORE-BEGIN
589  //DOM-IGNORE-END
590 
595 
599  virtual const OdRxValue* value() const ODRX_OVERRIDE { return &m_value; }
600 
604  virtual OdRxValue* value() ODRX_OVERRIDE { return &m_value; }
605 };
606 
607 // Type declarations follow:
608 //
609 
610 #define ODRX_DECLARE_VALUE_TYPE(type, attribute)\
611 template<> struct OdRxValueType::Desc<type>\
612 {\
613  attribute static const OdRxValueType& value() throw();\
614  attribute static void del();\
615 };\
616 template<> OdRxValue::OdRxValue(const type&) throw();
617 
622 
623 
627 
628 
632 
633 
637 
638 
642 
643 
647 
648 
652 
653 
657 
658 
662 
663 
667 
668 
672 
673 
677 
678 
682 
683 
686 ODRX_DECLARE_VALUE_TYPE(unsigned long long, FIRSTDLL_EXPORT)
687 
688 
692 
693 
696 template<> struct OdRxValueType::Desc<const OdChar*>
697 {
698  FIRSTDLL_EXPORT static const OdRxValueType& value() throw();
699  FIRSTDLL_EXPORT static void del();
700 };
701 template<> OdRxValue::OdRxValue(const OdChar* const &) throw();
702 
707 
712 
717 
722 
727 
732 
737 
742 
747 
752 
757 
762 
767 
771 ODRX_DECLARE_VALUE_TYPE(OdArray<unsigned long long>, FIRSTDLL_EXPORT)
772 
777 
782 
783 class OdRxClass;
784 
788 template<> struct OdRxValueType::Desc<OdRxClass*>
789 {
790  FIRSTDLL_EXPORT static const OdRxValueType& value() throw();
791  FIRSTDLL_EXPORT static void del();
792 };
793 
794 class OdAnsiString;
799 class OdString;
804 
809 
814 
819 
824 
829 
830 
834 template<> struct OdRxValueType::Desc<const char*>
835 {
836  FIRSTDLL_EXPORT static const OdRxValueType& value() throw();
837  FIRSTDLL_EXPORT static void del();
838 };
839 template<> OdRxValue::OdRxValue(const char* const &) throw();
840 
841 #include "TD_PackPop.h"
842 #endif // _ODRXVALUE_INCLUDED_
#define ODA_ASSERT(exp)
Definition: DebugStuff.h:49
true
Definition: DimVarDefs.h:2046
false
Definition: DimVarDefs.h:165
#define NULL
Definition: GsProperties.h:177
int OdInt32
#define ODRX_ABSTRACT
#define ODRX_OVERRIDE
wchar_t OdChar
#define FIRSTDLL_EXPORT
Definition: RootExport.h:39
OdRxValue createOdRxValue()
Definition: RxValue.h:461
OdSmartPtr< OdRxBoxedValue > OdRxBoxedValuePtr
Definition: RxValue.h:531
ValueType * rxenum_cast(OdRxValue *value)
Definition: RxValue.h:232
ODA_ASSUME(sizeof(OdRxValue)==32)
#define ODRX_DECLARE_VALUE_TYPE(type, attribute)
Definition: RxValue.h:610
const void * rxvalue_cast< void >(const OdRxValue *value)
Definition: RxValue.h:470
ValueType * rxvalue_cast(OdRxValue *value)
Definition: RxValue.h:223
Definition: Int64.h:43
ODRX_DECLARE_MEMBERS(OdRxBoxedValue)
virtual OdRxValue * value()=0
static OdRxBoxedValuePtr newBoxedValueOnHeap(const OdRxValue &value)
virtual OdRxObjectPtr clone() const ODRX_OVERRIDE
virtual const OdRxValue * value() const =0
OdRxBoxedValueOnStack(OdRxValue &value)
virtual const OdRxValue * value() const ODRX_OVERRIDE
Definition: RxValue.h:599
ODRX_DECLARE_MEMBERS(OdRxBoxedValueOnStack)
virtual OdRxValue * value() ODRX_OVERRIDE
Definition: RxValue.h:604
const OdRxValueType & type() const
bool operator!=(const OdRxValue &value) const
Definition: RxValue.h:192
static OdRxValue * unbox(OdRxObject *pO)
OdRxValue(const OdRxValue &rhs)
Definition: RxValue.h:77
bool operator==(const OdRxValue &value) const
Definition: RxValue.h:182
friend const ValueType * rxvalue_cast(const OdRxValue *value)
Definition: RxValue.h:254
OdRxValue(const OdRxValueType &type, const OdRxValue &value)
Definition: RxValue.h:86
~OdRxValue()
Definition: RxValue.h:133
friend ValueType * rxenum_cast(OdRxValue *value)
Definition: RxValue.h:232
static const OdRxValue & varies()
const OdRxValue & operator=(const OdRxValue &rhs)
Definition: RxValue.h:94
OdRxValue()
Definition: RxValue.h:69
friend const ValueType * rxenum_cast(const OdRxValue *value)
Definition: RxValue.h:263
const OdRxValueType & type() const
Definition: RxValue.h:146
static const OdRxValue & empty()
OdRxValue & operator=(const ValueType &rhs)
Definition: RxValue.h:244
static const OdRxValue * unbox(const OdRxObject *pO)
const OdRxEnumTag * getEnumTag() const
bool isEmpty() const
Definition: RxValue.h:154
const OdAnsiString typePath() const
Definition: RxValue.h:202
OdRxValue(const ValueType &value)
Definition: RxValue.h:211
friend ValueType * rxvalue_cast(OdRxValue *value)
Definition: RxValue.h:223
virtual const IOdRxEnumeration * enumeration() const
Definition: RxValueType.h:183
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
bool operator==(const BlockRefPath &rA, const BlockRefPath &rB)
DOM.
bool operator>>(const OdRxValue &out, IfcActionSourceTypeEnum &in)
Definition: RxDefs.h:36
Ordering
Definition: RxObject.h:314
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()