Variant.h 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. /// \file
  4. #pragma once
  5. #include "../Container/HashMap.h"
  6. #include "../Container/Ptr.h"
  7. #include "../Math/Color.h"
  8. #include "../Math/Matrix3.h"
  9. #include "../Math/Matrix3x4.h"
  10. #include "../Math/Rect.h"
  11. #include "../Math/StringHash.h"
  12. #include <typeinfo>
  13. namespace Urho3D
  14. {
  15. /// Variant's supported types.
  16. enum VariantType
  17. {
  18. VAR_NONE = 0,
  19. VAR_INT,
  20. VAR_BOOL,
  21. VAR_FLOAT,
  22. VAR_VECTOR2,
  23. VAR_VECTOR3,
  24. VAR_VECTOR4,
  25. VAR_QUATERNION,
  26. VAR_COLOR,
  27. VAR_STRING,
  28. VAR_BUFFER,
  29. VAR_VOIDPTR,
  30. VAR_RESOURCEREF,
  31. VAR_RESOURCEREFLIST,
  32. VAR_VARIANTVECTOR,
  33. VAR_VARIANTMAP,
  34. VAR_INTRECT,
  35. VAR_INTVECTOR2,
  36. VAR_PTR,
  37. VAR_MATRIX3,
  38. VAR_MATRIX3X4,
  39. VAR_MATRIX4,
  40. VAR_DOUBLE,
  41. VAR_STRINGVECTOR,
  42. VAR_RECT,
  43. VAR_INTVECTOR3,
  44. VAR_INT64,
  45. // Add new types here
  46. VAR_CUSTOM_HEAP,
  47. VAR_CUSTOM_STACK,
  48. MAX_VAR_TYPES
  49. };
  50. class Variant;
  51. class VectorBuffer;
  52. /// Vector of variants.
  53. using VariantVector = Vector<Variant>;
  54. /// Vector of strings.
  55. using StringVector = Vector<String>;
  56. /// Map of variants.
  57. using VariantMap = HashMap<StringHash, Variant>;
  58. /// Typed resource reference.
  59. struct URHO3D_API ResourceRef
  60. {
  61. /// Construct.
  62. ResourceRef() = default;
  63. /// Construct with type only and empty id.
  64. explicit ResourceRef(StringHash type) :
  65. type_(type)
  66. {
  67. }
  68. /// Construct with type and resource name.
  69. ResourceRef(StringHash type, const String& name) :
  70. type_(type),
  71. name_(name)
  72. {
  73. }
  74. /// Construct with type and resource name.
  75. ResourceRef(const String& type, const String& name) :
  76. type_(type),
  77. name_(name)
  78. {
  79. }
  80. /// Construct with type and resource name.
  81. ResourceRef(const char* type, const char* name) :
  82. type_(type),
  83. name_(name)
  84. {
  85. }
  86. /// Construct from another ResourceRef.
  87. ResourceRef(const ResourceRef& rhs) = default;
  88. /// Object type.
  89. StringHash type_;
  90. /// Object name.
  91. String name_;
  92. /// Test for equality with another reference.
  93. bool operator ==(const ResourceRef& rhs) const { return type_ == rhs.type_ && name_ == rhs.name_; }
  94. /// Test for inequality with another reference.
  95. bool operator !=(const ResourceRef& rhs) const { return type_ != rhs.type_ || name_ != rhs.name_; }
  96. };
  97. /// %List of typed resource references.
  98. struct URHO3D_API ResourceRefList
  99. {
  100. /// Construct.
  101. ResourceRefList() = default;
  102. /// Construct with type only.
  103. explicit ResourceRefList(StringHash type) :
  104. type_(type)
  105. {
  106. }
  107. /// Construct with type and id list.
  108. ResourceRefList(StringHash type, const StringVector& names) :
  109. type_(type),
  110. names_(names)
  111. {
  112. }
  113. /// Object type.
  114. StringHash type_;
  115. /// List of object names.
  116. StringVector names_;
  117. /// Test for equality with another reference list.
  118. bool operator ==(const ResourceRefList& rhs) const { return type_ == rhs.type_ && names_ == rhs.names_; }
  119. /// Test for inequality with another reference list.
  120. bool operator !=(const ResourceRefList& rhs) const { return type_ != rhs.type_ || names_ != rhs.names_; }
  121. };
  122. /// Custom variant value. This type is not abstract to store it in the VariantValue by value.
  123. /// @nobindtemp
  124. class CustomVariantValue
  125. {
  126. // GetValuePtr expects that CustomVariantValue is always convertible to CustomVariantValueImpl<T>.
  127. template <class T> friend class CustomVariantValueImpl;
  128. private:
  129. /// Construct from type info.
  130. explicit CustomVariantValue(const std::type_info& typeInfo) : typeInfo_(typeInfo) {}
  131. public:
  132. /// Construct empty.
  133. CustomVariantValue() : typeInfo_(typeid(void)) { } // NOLINT(modernize-redundant-void-arg)
  134. /// Destruct.
  135. virtual ~CustomVariantValue() = default;
  136. /// Get the type info.
  137. const std::type_info& GetTypeInfo() const { return typeInfo_; }
  138. /// Return whether the specified type is stored.
  139. template <class T> bool IsType() const { return GetTypeInfo() == typeid(T); }
  140. /// Return pointer to value of the specified type. Return null pointer if type does not match.
  141. template <class T> T* GetValuePtr();
  142. /// Return const pointer to value of the specified type. Return null pointer if type does not match.
  143. template <class T> const T* GetValuePtr() const;
  144. /// Assign value.
  145. virtual bool Assign(const CustomVariantValue& rhs) { return false; }
  146. /// Clone.
  147. virtual CustomVariantValue* Clone() const { return nullptr; }
  148. /// Placement clone.
  149. virtual void Clone(void* dest) const { }
  150. /// Get size.
  151. virtual unsigned GetSize() const { return sizeof(CustomVariantValue); }
  152. /// Compare to another custom value.
  153. virtual bool Compare(const CustomVariantValue& rhs) const { (void)rhs; return false; }
  154. /// Compare to zero.
  155. virtual bool IsZero() const { return false; }
  156. /// Convert custom value to string.
  157. virtual String ToString() const { return String::EMPTY; }
  158. private:
  159. /// Type info.
  160. const std::type_info& typeInfo_;
  161. };
  162. /// Custom variant value type traits. Specialize the template to implement custom type behavior.
  163. template <class T> struct CustomVariantValueTraits
  164. {
  165. /// Compare types.
  166. static bool Compare(const T& lhs, const T& rhs) { (void)lhs, rhs; return false; }
  167. /// Check whether the value is zero.
  168. static bool IsZero(const T& value) { (void)value; return false; }
  169. /// Convert type to string.
  170. static String ToString(const T& value) { (void)value; return String::EMPTY; }
  171. };
  172. /// Custom variant value implementation.
  173. template <class T> class CustomVariantValueImpl final : public CustomVariantValue
  174. {
  175. public:
  176. /// This class name.
  177. using ClassName = CustomVariantValueImpl<T>;
  178. /// Type traits.
  179. using Traits = CustomVariantValueTraits<T>;
  180. /// Construct from value.
  181. explicit CustomVariantValueImpl(const T& value) : CustomVariantValue(typeid(T)), value_(value) {}
  182. /// Set value.
  183. void SetValue(const T& value) { value_ = value; }
  184. /// Get value.
  185. T& GetValue() { return value_; }
  186. /// Get const value.
  187. const T& GetValue() const { return value_; }
  188. /// Assign value.
  189. bool Assign(const CustomVariantValue& rhs) override
  190. {
  191. if (const T* rhsValue = rhs.GetValuePtr<T>())
  192. {
  193. SetValue(*rhsValue);
  194. return true;
  195. }
  196. return false;
  197. }
  198. /// Clone.
  199. CustomVariantValue* Clone() const override { return new ClassName(value_); }
  200. /// Placement clone.
  201. void Clone(void* dest) const override { new (dest) ClassName(value_); }
  202. /// Get size.
  203. unsigned GetSize() const override { return sizeof(ClassName); }
  204. /// Compare to another custom value.
  205. bool Compare(const CustomVariantValue& rhs) const override
  206. {
  207. const T* rhsValue = rhs.GetValuePtr<T>();
  208. return rhsValue && Traits::Compare(value_, *rhsValue);
  209. }
  210. /// Compare to zero.
  211. bool IsZero() const override { return Traits::IsZero(value_);}
  212. /// Convert custom value to string.
  213. String ToString() const override { return Traits::ToString(value_); }
  214. private:
  215. /// Value.
  216. T value_;
  217. };
  218. /// Make custom variant value.
  219. template <typename T> CustomVariantValueImpl<T> MakeCustomValue(const T& value) { return CustomVariantValueImpl<T>(value); }
  220. /// Size of variant value. 16 bytes on 32-bit platform, 32 bytes on 64-bit platform.
  221. static const unsigned VARIANT_VALUE_SIZE = sizeof(void*) * 4;
  222. /// Union for the possible variant values. Objects exceeding the VARIANT_VALUE_SIZE are allocated on the heap.
  223. union VariantValue
  224. {
  225. byte storage_[VARIANT_VALUE_SIZE];
  226. int int_;
  227. bool bool_;
  228. float float_;
  229. double double_;
  230. long long int64_;
  231. void* voidPtr_;
  232. WeakPtr<RefCounted> weakPtr_;
  233. Vector2 vector2_;
  234. Vector3 vector3_;
  235. Vector4 vector4_;
  236. Rect rect_;
  237. IntVector2 intVector2_;
  238. IntVector3 intVector3_;
  239. IntRect intRect_;
  240. Matrix3* matrix3_;
  241. Matrix3x4* matrix3x4_;
  242. Matrix4* matrix4_;
  243. Quaternion quaternion_;
  244. Color color_;
  245. String string_;
  246. StringVector stringVector_;
  247. VariantVector variantVector_;
  248. VariantMap variantMap_;
  249. Vector<byte> buffer_;
  250. ResourceRef resourceRef_;
  251. ResourceRefList resourceRefList_;
  252. CustomVariantValue* customValueHeap_;
  253. CustomVariantValue customValueStack_;
  254. #ifdef _MSC_VER
  255. #pragma warning(push)
  256. #pragma warning(disable:26495)
  257. #endif
  258. /// Construct uninitialized.
  259. VariantValue() { } // NOLINT(modernize-use-equals-default)
  260. #ifdef _MSC_VER
  261. #pragma warning(pop)
  262. #endif
  263. /// Non-copyable.
  264. VariantValue(const VariantValue& value) = delete;
  265. /// Destruct.
  266. ~VariantValue() { } // NOLINT(modernize-use-equals-default)
  267. };
  268. static_assert(sizeof(VariantValue) == VARIANT_VALUE_SIZE, "Unexpected size of VariantValue");
  269. /// Variable that supports a fixed set of types.
  270. class URHO3D_API Variant
  271. {
  272. public:
  273. /// Construct empty.
  274. Variant() = default;
  275. /// Construct from integer.
  276. Variant(int value) // NOLINT(google-explicit-constructor)
  277. {
  278. *this = value;
  279. }
  280. /// Construct from 64 bit integer.
  281. Variant(long long value) // NOLINT(google-explicit-constructor)
  282. {
  283. *this = value;
  284. }
  285. /// Construct from unsigned integer.
  286. Variant(unsigned value) // NOLINT(google-explicit-constructor)
  287. {
  288. *this = value;
  289. }
  290. // c32 not bound because in AngelScript c32 just alias for u32 and c32 conflicts with u32
  291. /// Construct from Unicode code point.
  292. /// @nobind
  293. Variant(c32 value) // NOLINT(google-explicit-constructor)
  294. {
  295. *this = value;
  296. }
  297. /// Construct from unsigned integer.
  298. Variant(unsigned long long value) // NOLINT(google-explicit-constructor)
  299. {
  300. *this = value;
  301. }
  302. /// Construct from a string hash (convert to integer).
  303. Variant(const StringHash& value) // NOLINT(google-explicit-constructor)
  304. {
  305. *this = value;
  306. }
  307. /// Construct from a bool.
  308. Variant(bool value) // NOLINT(google-explicit-constructor)
  309. {
  310. *this = value;
  311. }
  312. /// Construct from a float.
  313. Variant(float value) // NOLINT(google-explicit-constructor)
  314. {
  315. *this = value;
  316. }
  317. /// Construct from a double.
  318. Variant(double value) // NOLINT(google-explicit-constructor)
  319. {
  320. *this = value;
  321. }
  322. /// Construct from a Vector2.
  323. Variant(const Vector2& value) // NOLINT(google-explicit-constructor)
  324. {
  325. *this = value;
  326. }
  327. /// Construct from a Vector3.
  328. Variant(const Vector3& value) // NOLINT(google-explicit-constructor)
  329. {
  330. *this = value;
  331. }
  332. /// Construct from a Vector4.
  333. Variant(const Vector4& value) // NOLINT(google-explicit-constructor)
  334. {
  335. *this = value;
  336. }
  337. /// Construct from a quaternion.
  338. Variant(const Quaternion& value) // NOLINT(google-explicit-constructor)
  339. {
  340. *this = value;
  341. }
  342. /// Construct from a color.
  343. Variant(const Color& value) // NOLINT(google-explicit-constructor)
  344. {
  345. *this = value;
  346. }
  347. /// Construct from a string.
  348. Variant(const String& value) // NOLINT(google-explicit-constructor)
  349. {
  350. *this = value;
  351. }
  352. /// Construct from a C string.
  353. Variant(const char* value) // NOLINT(google-explicit-constructor)
  354. {
  355. *this = value;
  356. }
  357. /// Construct from a buffer.
  358. Variant(const Vector<byte>& value) // NOLINT(google-explicit-constructor)
  359. {
  360. *this = value;
  361. }
  362. /// Construct from a %VectorBuffer and store as a buffer.
  363. Variant(const VectorBuffer& value) // NOLINT(google-explicit-constructor)
  364. {
  365. *this = value;
  366. }
  367. /// Construct from a pointer.
  368. Variant(void* value) // NOLINT(google-explicit-constructor)
  369. {
  370. *this = value;
  371. }
  372. /// Construct from a resource reference.
  373. Variant(const ResourceRef& value) // NOLINT(google-explicit-constructor)
  374. {
  375. *this = value;
  376. }
  377. /// Construct from a resource reference list.
  378. Variant(const ResourceRefList& value) // NOLINT(google-explicit-constructor)
  379. {
  380. *this = value;
  381. }
  382. /// Construct from a variant vector.
  383. Variant(const VariantVector& value) // NOLINT(google-explicit-constructor)
  384. {
  385. *this = value;
  386. }
  387. /// Construct from a variant map.
  388. Variant(const VariantMap& value) // NOLINT(google-explicit-constructor)
  389. {
  390. *this = value;
  391. }
  392. /// Construct from a string vector.
  393. Variant(const StringVector& value) // NOLINT(google-explicit-constructor)
  394. {
  395. *this = value;
  396. }
  397. /// Construct from a rect.
  398. Variant(const Rect& value) // NOLINT(google-explicit-constructor)
  399. {
  400. *this = value;
  401. }
  402. /// Construct from an integer rect.
  403. Variant(const IntRect& value) // NOLINT(google-explicit-constructor)
  404. {
  405. *this = value;
  406. }
  407. /// Construct from an IntVector2.
  408. Variant(const IntVector2& value) // NOLINT(google-explicit-constructor)
  409. {
  410. *this = value;
  411. }
  412. /// Construct from an IntVector3.
  413. Variant(const IntVector3& value) // NOLINT(google-explicit-constructor)
  414. {
  415. *this = value;
  416. }
  417. /// Construct from a RefCounted pointer. The object will be stored internally in a WeakPtr so that its expiration can be detected safely.
  418. Variant(RefCounted* value) // NOLINT(google-explicit-constructor)
  419. {
  420. *this = value;
  421. }
  422. /// Construct from a Matrix3.
  423. Variant(const Matrix3& value) // NOLINT(google-explicit-constructor)
  424. {
  425. *this = value;
  426. }
  427. /// Construct from a Matrix3x4.
  428. Variant(const Matrix3x4& value) // NOLINT(google-explicit-constructor)
  429. {
  430. *this = value;
  431. }
  432. /// Construct from a Matrix4.
  433. Variant(const Matrix4& value) // NOLINT(google-explicit-constructor)
  434. {
  435. *this = value;
  436. }
  437. /// Construct from custom value.
  438. template <class T>
  439. Variant(const CustomVariantValueImpl<T>& value) // NOLINT(google-explicit-constructor)
  440. {
  441. *this = value;
  442. }
  443. /// Construct from type and value.
  444. Variant(const String& type, const String& value)
  445. {
  446. FromString(type, value);
  447. }
  448. /// Construct from type and value.
  449. Variant(VariantType type, const String& value)
  450. {
  451. FromString(type, value);
  452. }
  453. /// Construct from type and value.
  454. Variant(const char* type, const char* value)
  455. {
  456. FromString(type, value);
  457. }
  458. /// Construct from type and value.
  459. Variant(VariantType type, const char* value)
  460. {
  461. FromString(type, value);
  462. }
  463. /// Copy-construct from another variant.
  464. Variant(const Variant& value)
  465. {
  466. *this = value;
  467. }
  468. /// Destruct.
  469. ~Variant()
  470. {
  471. SetType(VAR_NONE);
  472. }
  473. /// Reset to empty.
  474. void Clear()
  475. {
  476. SetType(VAR_NONE);
  477. }
  478. /// Assign from another variant.
  479. Variant& operator =(const Variant& rhs);
  480. /// Assign from an integer.
  481. Variant& operator =(int rhs)
  482. {
  483. SetType(VAR_INT);
  484. value_.int_ = rhs;
  485. return *this;
  486. }
  487. /// Assign from 64 bit integer.
  488. Variant& operator =(long long rhs)
  489. {
  490. SetType(VAR_INT64);
  491. value_.int64_ = rhs;
  492. return *this;
  493. }
  494. /// Assign from unsigned 64 bit integer.
  495. Variant& operator =(unsigned long long rhs)
  496. {
  497. SetType(VAR_INT64);
  498. value_.int64_ = static_cast<long long>(rhs);
  499. return *this;
  500. }
  501. /// Assign from an unsigned integer.
  502. Variant& operator =(unsigned rhs)
  503. {
  504. SetType(VAR_INT);
  505. value_.int_ = (int)rhs;
  506. return *this;
  507. }
  508. /// Assign from an Unicode code point.
  509. /// @nobind
  510. Variant& operator =(c32 rhs)
  511. {
  512. SetType(VAR_INT);
  513. value_.int_ = (int)rhs;
  514. return *this;
  515. }
  516. /// Assign from a StringHash (convert to integer).
  517. Variant& operator =(const StringHash& rhs)
  518. {
  519. SetType(VAR_INT);
  520. value_.int_ = (int)rhs.Value();
  521. return *this;
  522. }
  523. /// Assign from a bool.
  524. Variant& operator =(bool rhs)
  525. {
  526. SetType(VAR_BOOL);
  527. value_.bool_ = rhs;
  528. return *this;
  529. }
  530. /// Assign from a float.
  531. Variant& operator =(float rhs)
  532. {
  533. SetType(VAR_FLOAT);
  534. value_.float_ = rhs;
  535. return *this;
  536. }
  537. /// Assign from a double.
  538. Variant& operator =(double rhs)
  539. {
  540. SetType(VAR_DOUBLE);
  541. value_.double_ = rhs;
  542. return *this;
  543. }
  544. /// Assign from a Vector2.
  545. Variant& operator =(const Vector2& rhs)
  546. {
  547. SetType(VAR_VECTOR2);
  548. value_.vector2_ = rhs;
  549. return *this;
  550. }
  551. /// Assign from a Vector3.
  552. Variant& operator =(const Vector3& rhs)
  553. {
  554. SetType(VAR_VECTOR3);
  555. value_.vector3_ = rhs;
  556. return *this;
  557. }
  558. /// Assign from a Vector4.
  559. Variant& operator =(const Vector4& rhs)
  560. {
  561. SetType(VAR_VECTOR4);
  562. value_.vector4_ = rhs;
  563. return *this;
  564. }
  565. /// Assign from a quaternion.
  566. Variant& operator =(const Quaternion& rhs)
  567. {
  568. SetType(VAR_QUATERNION);
  569. value_.quaternion_ = rhs;
  570. return *this;
  571. }
  572. /// Assign from a color.
  573. Variant& operator =(const Color& rhs)
  574. {
  575. SetType(VAR_COLOR);
  576. value_.color_ = rhs;
  577. return *this;
  578. }
  579. /// Assign from a string.
  580. Variant& operator =(const String& rhs)
  581. {
  582. SetType(VAR_STRING);
  583. value_.string_ = rhs;
  584. return *this;
  585. }
  586. /// Assign from a C string.
  587. Variant& operator =(const char* rhs)
  588. {
  589. SetType(VAR_STRING);
  590. value_.string_ = rhs;
  591. return *this;
  592. }
  593. /// Assign from a buffer.
  594. Variant& operator =(const Vector<byte>& rhs)
  595. {
  596. SetType(VAR_BUFFER);
  597. value_.buffer_ = rhs;
  598. return *this;
  599. }
  600. /// Assign from a %VectorBuffer and store as a buffer.
  601. Variant& operator =(const VectorBuffer& rhs);
  602. /// Assign from a void pointer.
  603. Variant& operator =(void* rhs)
  604. {
  605. SetType(VAR_VOIDPTR);
  606. value_.voidPtr_ = rhs;
  607. return *this;
  608. }
  609. /// Assign from a resource reference.
  610. Variant& operator =(const ResourceRef& rhs)
  611. {
  612. SetType(VAR_RESOURCEREF);
  613. value_.resourceRef_ = rhs;
  614. return *this;
  615. }
  616. /// Assign from a resource reference list.
  617. Variant& operator =(const ResourceRefList& rhs)
  618. {
  619. SetType(VAR_RESOURCEREFLIST);
  620. value_.resourceRefList_ = rhs;
  621. return *this;
  622. }
  623. /// Assign from a variant vector.
  624. Variant& operator =(const VariantVector& rhs)
  625. {
  626. SetType(VAR_VARIANTVECTOR);
  627. value_.variantVector_ = rhs;
  628. return *this;
  629. }
  630. /// Assign from a string vector.
  631. Variant& operator =(const StringVector& rhs)
  632. {
  633. SetType(VAR_STRINGVECTOR);
  634. value_.stringVector_ = rhs;
  635. return *this;
  636. }
  637. /// Assign from a variant map.
  638. Variant& operator =(const VariantMap& rhs)
  639. {
  640. SetType(VAR_VARIANTMAP);
  641. value_.variantMap_ = rhs;
  642. return *this;
  643. }
  644. /// Assign from a rect.
  645. Variant& operator =(const Rect& rhs)
  646. {
  647. SetType(VAR_RECT);
  648. value_.rect_ = rhs;
  649. return *this;
  650. }
  651. /// Assign from an integer rect.
  652. Variant& operator =(const IntRect& rhs)
  653. {
  654. SetType(VAR_INTRECT);
  655. value_.intRect_ = rhs;
  656. return *this;
  657. }
  658. /// Assign from an IntVector2.
  659. Variant& operator =(const IntVector2& rhs)
  660. {
  661. SetType(VAR_INTVECTOR2);
  662. value_.intVector2_ = rhs;
  663. return *this;
  664. }
  665. /// Assign from an IntVector3.
  666. Variant& operator =(const IntVector3& rhs)
  667. {
  668. SetType(VAR_INTVECTOR3);
  669. value_.intVector3_ = rhs;
  670. return *this;
  671. }
  672. /// Assign from a RefCounted pointer. The object will be stored internally in a WeakPtr so that its expiration can be detected safely.
  673. Variant& operator =(RefCounted* rhs)
  674. {
  675. SetType(VAR_PTR);
  676. value_.weakPtr_ = rhs;
  677. return *this;
  678. }
  679. /// Assign from a Matrix3.
  680. Variant& operator =(const Matrix3& rhs)
  681. {
  682. SetType(VAR_MATRIX3);
  683. *value_.matrix3_ = rhs;
  684. return *this;
  685. }
  686. /// Assign from a Matrix3x4.
  687. Variant& operator =(const Matrix3x4& rhs)
  688. {
  689. SetType(VAR_MATRIX3X4);
  690. *value_.matrix3x4_ = rhs;
  691. return *this;
  692. }
  693. /// Assign from a Matrix4.
  694. Variant& operator =(const Matrix4& rhs)
  695. {
  696. SetType(VAR_MATRIX4);
  697. *value_.matrix4_ = rhs;
  698. return *this;
  699. }
  700. /// Assign from custom value.
  701. template <class T>
  702. Variant& operator =(const CustomVariantValueImpl<T>& value)
  703. {
  704. SetCustomVariantValue(value);
  705. return *this;
  706. }
  707. /// Test for equality with another variant.
  708. bool operator ==(const Variant& rhs) const;
  709. /// Test for equality with an integer. To return true, both the type and value must match.
  710. bool operator ==(int rhs) const { return type_ == VAR_INT ? value_.int_ == rhs : false; }
  711. /// Test for equality with an unsigned integer. To return true, both the type and value must match.
  712. bool operator ==(unsigned rhs) const { return type_ == VAR_INT ? value_.int_ == static_cast<int>(rhs) : false; }
  713. /// Test for equality with an Unicode code point. To return true, both the type and value must match.
  714. /// @nobind
  715. bool operator ==(c32 rhs) const { return type_ == VAR_INT ? value_.int_ == static_cast<int>(rhs) : false; }
  716. /// Test for equality with an 64 bit integer. To return true, both the type and value must match.
  717. bool operator ==(long long rhs) const { return type_ == VAR_INT64 ? value_.int64_ == rhs : false; }
  718. /// Test for equality with an unsigned 64 bit integer. To return true, both the type and value must match.
  719. bool operator ==(unsigned long long rhs) const { return type_ == VAR_INT64 ? value_.int64_ == static_cast<long long>(rhs) : false; }
  720. /// Test for equality with a bool. To return true, both the type and value must match.
  721. bool operator ==(bool rhs) const { return type_ == VAR_BOOL ? value_.bool_ == rhs : false; }
  722. /// Test for equality with a float. To return true, both the type and value must match.
  723. bool operator ==(float rhs) const { return type_ == VAR_FLOAT ? value_.float_ == rhs : false; }
  724. /// Test for equality with a double. To return true, both the type and value must match.
  725. bool operator ==(double rhs) const { return type_ == VAR_DOUBLE ? value_.double_ == rhs : false; }
  726. /// Test for equality with a Vector2. To return true, both the type and value must match.
  727. bool operator ==(const Vector2& rhs) const
  728. {
  729. return type_ == VAR_VECTOR2 ? value_.vector2_ == rhs : false;
  730. }
  731. /// Test for equality with a Vector3. To return true, both the type and value must match.
  732. bool operator ==(const Vector3& rhs) const
  733. {
  734. return type_ == VAR_VECTOR3 ? value_.vector3_ == rhs : false;
  735. }
  736. /// Test for equality with a Vector4. To return true, both the type and value must match.
  737. bool operator ==(const Vector4& rhs) const
  738. {
  739. return type_ == VAR_VECTOR4 ? value_.vector4_ == rhs : false;
  740. }
  741. /// Test for equality with a quaternion. To return true, both the type and value must match.
  742. bool operator ==(const Quaternion& rhs) const
  743. {
  744. return type_ == VAR_QUATERNION ? value_.quaternion_ == rhs : false;
  745. }
  746. /// Test for equality with a color. To return true, both the type and value must match.
  747. bool operator ==(const Color& rhs) const
  748. {
  749. return type_ == VAR_COLOR ? value_.color_ == rhs : false;
  750. }
  751. /// Test for equality with a string. To return true, both the type and value must match.
  752. bool operator ==(const String& rhs) const
  753. {
  754. return type_ == VAR_STRING ? value_.string_ == rhs : false;
  755. }
  756. /// Test for equality with a buffer. To return true, both the type and value must match.
  757. bool operator ==(const Vector<byte>& rhs) const;
  758. /// Test for equality with a %VectorBuffer. To return true, both the type and value must match.
  759. bool operator ==(const VectorBuffer& rhs) const;
  760. /// Test for equality with a void pointer. To return true, both the type and value must match, with the exception that a RefCounted pointer is also allowed.
  761. bool operator ==(void* rhs) const
  762. {
  763. if (type_ == VAR_VOIDPTR)
  764. return value_.voidPtr_ == rhs;
  765. else if (type_ == VAR_PTR)
  766. return value_.weakPtr_ == rhs;
  767. else
  768. return false;
  769. }
  770. /// Test for equality with a resource reference. To return true, both the type and value must match.
  771. bool operator ==(const ResourceRef& rhs) const
  772. {
  773. return type_ == VAR_RESOURCEREF ? value_.resourceRef_ == rhs : false;
  774. }
  775. /// Test for equality with a resource reference list. To return true, both the type and value must match.
  776. bool operator ==(const ResourceRefList& rhs) const
  777. {
  778. return type_ == VAR_RESOURCEREFLIST ? value_.resourceRefList_ == rhs : false;
  779. }
  780. /// Test for equality with a variant vector. To return true, both the type and value must match.
  781. bool operator ==(const VariantVector& rhs) const
  782. {
  783. return type_ == VAR_VARIANTVECTOR ? value_.variantVector_ == rhs : false;
  784. }
  785. /// Test for equality with a string vector. To return true, both the type and value must match.
  786. bool operator ==(const StringVector& rhs) const
  787. {
  788. return type_ == VAR_STRINGVECTOR ? value_.stringVector_ == rhs : false;
  789. }
  790. /// Test for equality with a variant map. To return true, both the type and value must match.
  791. bool operator ==(const VariantMap& rhs) const
  792. {
  793. return type_ == VAR_VARIANTMAP ? value_.variantMap_ == rhs : false;
  794. }
  795. /// Test for equality with a rect. To return true, both the type and value must match.
  796. bool operator ==(const Rect& rhs) const
  797. {
  798. return type_ == VAR_RECT ? value_.rect_ == rhs : false;
  799. }
  800. /// Test for equality with an integer rect. To return true, both the type and value must match.
  801. bool operator ==(const IntRect& rhs) const
  802. {
  803. return type_ == VAR_INTRECT ? value_.intRect_ == rhs : false;
  804. }
  805. /// Test for equality with an IntVector2. To return true, both the type and value must match.
  806. bool operator ==(const IntVector2& rhs) const
  807. {
  808. return type_ == VAR_INTVECTOR2 ? value_.intVector2_ == rhs : false;
  809. }
  810. /// Test for equality with an IntVector3. To return true, both the type and value must match.
  811. bool operator ==(const IntVector3& rhs) const
  812. {
  813. return type_ == VAR_INTVECTOR3 ? value_.intVector3_ == rhs : false;
  814. }
  815. /// Test for equality with a StringHash. To return true, both the type and value must match.
  816. bool operator ==(const StringHash& rhs) const { return type_ == VAR_INT ? static_cast<hash32>(value_.int_) == rhs.Value() : false; }
  817. /// Test for equality with a RefCounted pointer. To return true, both the type and value must match, with the exception that void pointer is also allowed.
  818. bool operator ==(RefCounted* rhs) const
  819. {
  820. if (type_ == VAR_PTR)
  821. return value_.weakPtr_ == rhs;
  822. else if (type_ == VAR_VOIDPTR)
  823. return value_.voidPtr_ == rhs;
  824. else
  825. return false;
  826. }
  827. /// Test for equality with a Matrix3. To return true, both the type and value must match.
  828. bool operator ==(const Matrix3& rhs) const
  829. {
  830. return type_ == VAR_MATRIX3 ? *value_.matrix3_ == rhs : false;
  831. }
  832. /// Test for equality with a Matrix3x4. To return true, both the type and value must match.
  833. bool operator ==(const Matrix3x4& rhs) const
  834. {
  835. return type_ == VAR_MATRIX3X4 ? *value_.matrix3x4_ == rhs : false;
  836. }
  837. /// Test for equality with a Matrix4. To return true, both the type and value must match.
  838. bool operator ==(const Matrix4& rhs) const
  839. {
  840. return type_ == VAR_MATRIX4 ? *value_.matrix4_ == rhs : false;
  841. }
  842. /// Test for inequality with another variant.
  843. bool operator !=(const Variant& rhs) const { return !(*this == rhs); }
  844. /// Test for inequality with an integer.
  845. bool operator !=(int rhs) const { return !(*this == rhs); }
  846. /// Test for inequality with an unsigned integer.
  847. bool operator !=(unsigned rhs) const { return !(*this == rhs); }
  848. /// Test for inequality with an Unicode code point.
  849. bool operator !=(c32 rhs) const { return !(*this == rhs); }
  850. /// Test for inequality with an 64 bit integer.
  851. bool operator !=(long long rhs) const { return !(*this == rhs); }
  852. /// Test for inequality with an unsigned 64 bit integer.
  853. bool operator !=(unsigned long long rhs) const { return !(*this == rhs); }
  854. /// Test for inequality with a bool.
  855. bool operator !=(bool rhs) const { return !(*this == rhs); }
  856. /// Test for inequality with a float.
  857. bool operator !=(float rhs) const { return !(*this == rhs); }
  858. /// Test for inequality with a double.
  859. bool operator !=(double rhs) const { return !(*this == rhs); }
  860. /// Test for inequality with a Vector2.
  861. bool operator !=(const Vector2& rhs) const { return !(*this == rhs); }
  862. /// Test for inequality with a Vector3.
  863. bool operator !=(const Vector3& rhs) const { return !(*this == rhs); }
  864. /// Test for inequality with an Vector4.
  865. bool operator !=(const Vector4& rhs) const { return !(*this == rhs); }
  866. /// Test for inequality with a Quaternion.
  867. bool operator !=(const Quaternion& rhs) const { return !(*this == rhs); }
  868. /// Test for inequality with a string.
  869. bool operator !=(const String& rhs) const { return !(*this == rhs); }
  870. /// Test for inequality with a buffer.
  871. bool operator !=(const Vector<byte>& rhs) const { return !(*this == rhs); }
  872. /// Test for inequality with a %VectorBuffer.
  873. bool operator !=(const VectorBuffer& rhs) const { return !(*this == rhs); }
  874. /// Test for inequality with a pointer.
  875. bool operator !=(void* rhs) const { return !(*this == rhs); }
  876. /// Test for inequality with a resource reference.
  877. bool operator !=(const ResourceRef& rhs) const { return !(*this == rhs); }
  878. /// Test for inequality with a resource reference list.
  879. bool operator !=(const ResourceRefList& rhs) const { return !(*this == rhs); }
  880. /// Test for inequality with a variant vector.
  881. bool operator !=(const VariantVector& rhs) const { return !(*this == rhs); }
  882. /// Test for inequality with a string vector.
  883. bool operator !=(const StringVector& rhs) const { return !(*this == rhs); }
  884. /// Test for inequality with a variant map.
  885. bool operator !=(const VariantMap& rhs) const { return !(*this == rhs); }
  886. /// Test for inequality with a rect.
  887. bool operator !=(const Rect& rhs) const { return !(*this == rhs); }
  888. /// Test for inequality with an integer rect.
  889. bool operator !=(const IntRect& rhs) const { return !(*this == rhs); }
  890. /// Test for inequality with an IntVector2.
  891. bool operator !=(const IntVector2& rhs) const { return !(*this == rhs); }
  892. /// Test for inequality with an IntVector3.
  893. bool operator !=(const IntVector3& rhs) const { return !(*this == rhs); }
  894. /// Test for inequality with a StringHash.
  895. bool operator !=(const StringHash& rhs) const { return !(*this == rhs); }
  896. /// Test for inequality with a RefCounted pointer.
  897. bool operator !=(RefCounted* rhs) const { return !(*this == rhs); }
  898. /// Test for inequality with a Matrix3.
  899. bool operator !=(const Matrix3& rhs) const { return !(*this == rhs); }
  900. /// Test for inequality with a Matrix3x4.
  901. bool operator !=(const Matrix3x4& rhs) const { return !(*this == rhs); }
  902. /// Test for inequality with a Matrix4.
  903. bool operator !=(const Matrix4& rhs) const { return !(*this == rhs); }
  904. /// Set from typename and value strings. Pointers will be set to null, and VariantBuffer or VariantMap types are not supported.
  905. void FromString(const String& type, const String& value);
  906. /// Set from typename and value strings. Pointers will be set to null, and VariantBuffer or VariantMap types are not supported.
  907. void FromString(const char* type, const char* value);
  908. /// Set from type and value string. Pointers will be set to null, and VariantBuffer or VariantMap types are not supported.
  909. void FromString(VariantType type, const String& value);
  910. /// Set from type and value string. Pointers will be set to null, and VariantBuffer or VariantMap types are not supported.
  911. void FromString(VariantType type, const char* value);
  912. /// Set buffer type from a memory area.
  913. void SetBuffer(const void* data, unsigned size);
  914. /// Set custom value.
  915. void SetCustomVariantValue(const CustomVariantValue& value);
  916. /// Set custom value.
  917. template <class T> void SetCustom(const T& value) { SetCustomVariantValue(MakeCustomValue<T>(value)); }
  918. /// Return int or zero on type mismatch. Floats and doubles are converted.
  919. i32 GetI32() const
  920. {
  921. if (type_ == VAR_INT)
  922. return value_.int_;
  923. else if (type_ == VAR_FLOAT)
  924. return static_cast<i32>(value_.float_);
  925. else if (type_ == VAR_DOUBLE)
  926. return static_cast<i32>(value_.double_);
  927. else
  928. return 0;
  929. }
  930. /// Return 64 bit int or zero on type mismatch. Floats and doubles are converted.
  931. i64 GetI64() const
  932. {
  933. if (type_ == VAR_INT64)
  934. return value_.int64_;
  935. else if (type_ == VAR_INT)
  936. return value_.int_;
  937. else if (type_ == VAR_FLOAT)
  938. return static_cast<i64>(value_.float_);
  939. else if (type_ == VAR_DOUBLE)
  940. return static_cast<i64>(value_.double_);
  941. else
  942. return 0;
  943. }
  944. /// Return unsigned 64 bit int or zero on type mismatch. Floats and doubles are converted.
  945. u64 GetU64() const
  946. {
  947. if (type_ == VAR_INT64)
  948. return static_cast<u64>(value_.int64_);
  949. else if (type_ == VAR_INT)
  950. return static_cast<u64>(value_.int_);
  951. else if (type_ == VAR_FLOAT)
  952. return static_cast<u64>(value_.float_);
  953. else if (type_ == VAR_DOUBLE)
  954. return static_cast<u64>(value_.double_);
  955. else
  956. return 0;
  957. }
  958. /// Return unsigned int or zero on type mismatch. Floats and doubles are converted.
  959. u32 GetU32() const
  960. {
  961. if (type_ == VAR_INT)
  962. return static_cast<u32>(value_.int_);
  963. else if (type_ == VAR_FLOAT)
  964. return static_cast<u32>(value_.float_);
  965. else if (type_ == VAR_DOUBLE)
  966. return static_cast<u32>(value_.double_);
  967. else
  968. return 0;
  969. }
  970. /// Return Unicode code point or zero on type mismatch.
  971. c32 GetC32() const
  972. {
  973. if (type_ == VAR_INT)
  974. return static_cast<c32>(value_.int_);
  975. else
  976. return 0;
  977. }
  978. /// Return StringHash or zero on type mismatch.
  979. StringHash GetStringHash() const { return StringHash(GetU32()); }
  980. /// Return bool or false on type mismatch.
  981. bool GetBool() const { return type_ == VAR_BOOL ? value_.bool_ : false; }
  982. /// Return float or zero on type mismatch. Ints and doubles are converted.
  983. float GetFloat() const
  984. {
  985. if (type_ == VAR_FLOAT)
  986. return value_.float_;
  987. else if (type_ == VAR_DOUBLE)
  988. return static_cast<float>(value_.double_);
  989. else if (type_ == VAR_INT)
  990. return static_cast<float>(value_.int_);
  991. else if (type_ == VAR_INT64)
  992. return static_cast<float>(value_.int64_);
  993. else
  994. return 0.0f;
  995. }
  996. /// Return double or zero on type mismatch. Ints and floats are converted.
  997. double GetDouble() const
  998. {
  999. if (type_ == VAR_DOUBLE)
  1000. return value_.double_;
  1001. else if (type_ == VAR_FLOAT)
  1002. return value_.float_;
  1003. else if (type_ == VAR_INT)
  1004. return static_cast<double>(value_.int_);
  1005. else if (type_ == VAR_INT64)
  1006. return static_cast<double>(value_.int64_);
  1007. else
  1008. return 0.0;
  1009. }
  1010. /// Return Vector2 or zero on type mismatch.
  1011. const Vector2& GetVector2() const { return type_ == VAR_VECTOR2 ? value_.vector2_ : Vector2::ZERO; }
  1012. /// Return Vector3 or zero on type mismatch.
  1013. const Vector3& GetVector3() const { return type_ == VAR_VECTOR3 ? value_.vector3_ : Vector3::ZERO; }
  1014. /// Return Vector4 or zero on type mismatch.
  1015. const Vector4& GetVector4() const { return type_ == VAR_VECTOR4 ? value_.vector4_ : Vector4::ZERO; }
  1016. /// Return quaternion or identity on type mismatch.
  1017. const Quaternion& GetQuaternion() const
  1018. {
  1019. return type_ == VAR_QUATERNION ? value_.quaternion_ : Quaternion::IDENTITY;
  1020. }
  1021. /// Return color or default on type mismatch. Vector4 is aliased to Color if necessary.
  1022. const Color& GetColor() const { return (type_ == VAR_COLOR || type_ == VAR_VECTOR4) ? value_.color_ : Color::WHITE; }
  1023. /// Return string or empty on type mismatch.
  1024. const String& GetString() const { return type_ == VAR_STRING ? value_.string_ : String::EMPTY; }
  1025. /// Return buffer or empty on type mismatch.
  1026. const Vector<byte>& GetBuffer() const
  1027. {
  1028. return type_ == VAR_BUFFER ? value_.buffer_ : emptyBuffer;
  1029. }
  1030. /// Return %VectorBuffer containing the buffer or empty on type mismatch.
  1031. VectorBuffer GetVectorBuffer() const;
  1032. /// Return void pointer or null on type mismatch. RefCounted pointer will be converted.
  1033. void* GetVoidPtr() const
  1034. {
  1035. if (type_ == VAR_VOIDPTR)
  1036. return value_.voidPtr_;
  1037. else if (type_ == VAR_PTR)
  1038. return value_.weakPtr_;
  1039. else
  1040. return nullptr;
  1041. }
  1042. /// Return a resource reference or empty on type mismatch.
  1043. const ResourceRef& GetResourceRef() const
  1044. {
  1045. return type_ == VAR_RESOURCEREF ? value_.resourceRef_ : emptyResourceRef;
  1046. }
  1047. /// Return a resource reference list or empty on type mismatch.
  1048. const ResourceRefList& GetResourceRefList() const
  1049. {
  1050. return type_ == VAR_RESOURCEREFLIST ? value_.resourceRefList_ : emptyResourceRefList;
  1051. }
  1052. /// Return a variant vector or empty on type mismatch.
  1053. const VariantVector& GetVariantVector() const
  1054. {
  1055. return type_ == VAR_VARIANTVECTOR ? value_.variantVector_ : emptyVariantVector;
  1056. }
  1057. /// Return a string vector or empty on type mismatch.
  1058. const StringVector& GetStringVector() const
  1059. {
  1060. return type_ == VAR_STRINGVECTOR ? value_.stringVector_ : emptyStringVector;
  1061. }
  1062. /// Return a variant map or empty on type mismatch.
  1063. const VariantMap& GetVariantMap() const
  1064. {
  1065. return type_ == VAR_VARIANTMAP ? value_.variantMap_ : emptyVariantMap;
  1066. }
  1067. /// Return a rect or empty on type mismatch.
  1068. const Rect& GetRect() const { return type_ == VAR_RECT ? value_.rect_ : Rect::ZERO; }
  1069. /// Return an integer rect or empty on type mismatch.
  1070. const IntRect& GetIntRect() const { return type_ == VAR_INTRECT ? value_.intRect_ : IntRect::ZERO; }
  1071. /// Return an IntVector2 or empty on type mismatch.
  1072. const IntVector2& GetIntVector2() const
  1073. {
  1074. return type_ == VAR_INTVECTOR2 ? value_.intVector2_ : IntVector2::ZERO;
  1075. }
  1076. /// Return an IntVector3 or empty on type mismatch.
  1077. const IntVector3& GetIntVector3() const
  1078. {
  1079. return type_ == VAR_INTVECTOR3 ? value_.intVector3_ : IntVector3::ZERO;
  1080. }
  1081. /// Return a RefCounted pointer or null on type mismatch. Will return null if holding a void pointer, as it can not be safely verified that the object is a RefCounted.
  1082. RefCounted* GetPtr() const
  1083. {
  1084. return type_ == VAR_PTR ? value_.weakPtr_ : nullptr;
  1085. }
  1086. /// Return a Matrix3 or identity on type mismatch.
  1087. const Matrix3& GetMatrix3() const
  1088. {
  1089. return type_ == VAR_MATRIX3 ? *value_.matrix3_ : Matrix3::IDENTITY;
  1090. }
  1091. /// Return a Matrix3x4 or identity on type mismatch.
  1092. const Matrix3x4& GetMatrix3x4() const
  1093. {
  1094. return type_ == VAR_MATRIX3X4 ? *value_.matrix3x4_ : Matrix3x4::IDENTITY;
  1095. }
  1096. /// Return a Matrix4 or identity on type mismatch.
  1097. const Matrix4& GetMatrix4() const
  1098. {
  1099. return type_ == VAR_MATRIX4 ? *value_.matrix4_ : Matrix4::IDENTITY;
  1100. }
  1101. /// Return pointer to custom variant value.
  1102. CustomVariantValue* GetCustomVariantValuePtr()
  1103. {
  1104. return const_cast<CustomVariantValue*>(const_cast<const Variant*>(this)->GetCustomVariantValuePtr());
  1105. }
  1106. /// Return const pointer to custom variant value.
  1107. const CustomVariantValue* GetCustomVariantValuePtr() const
  1108. {
  1109. if (type_ == VAR_CUSTOM_HEAP)
  1110. return value_.customValueHeap_;
  1111. else if (type_ == VAR_CUSTOM_STACK)
  1112. return &value_.customValueStack_;
  1113. else
  1114. return nullptr;
  1115. }
  1116. /// Return custom variant value or default-constructed on type mismatch.
  1117. template <class T> T GetCustom() const
  1118. {
  1119. if (const CustomVariantValue* value = GetCustomVariantValuePtr())
  1120. {
  1121. if (value->IsType<T>())
  1122. return *value->GetValuePtr<T>();
  1123. }
  1124. return T();
  1125. }
  1126. /// Return true if specified custom type is stored in the variant.
  1127. template <class T> bool IsCustomType() const
  1128. {
  1129. if (const CustomVariantValue* custom = GetCustomVariantValuePtr())
  1130. return custom->IsType<T>();
  1131. else
  1132. return false;
  1133. }
  1134. /// Return value's type.
  1135. /// @property
  1136. VariantType GetType() const { return type_; }
  1137. /// Return value's type name.
  1138. /// @property
  1139. String GetTypeName() const;
  1140. /// Convert value to string. Pointers are returned as null, and VariantBuffer or VariantMap are not supported and return empty.
  1141. String ToString() const;
  1142. /// Return true when the variant value is considered zero according to its actual type.
  1143. /// @property
  1144. bool IsZero() const;
  1145. /// Return true when the variant is empty (i.e. not initialized yet).
  1146. /// @property
  1147. bool IsEmpty() const { return type_ == VAR_NONE; }
  1148. /// Return true when the variant stores custom type.
  1149. bool IsCustom() const { return type_ == VAR_CUSTOM_HEAP || type_ == VAR_CUSTOM_STACK; }
  1150. /// Return the value, template version.
  1151. template <class T> T Get() const;
  1152. /// Return a pointer to a modifiable buffer or null on type mismatch.
  1153. Vector<byte>* GetBufferPtr()
  1154. {
  1155. return type_ == VAR_BUFFER ? &value_.buffer_ : nullptr;
  1156. }
  1157. /// Return a pointer to a modifiable variant vector or null on type mismatch.
  1158. VariantVector* GetVariantVectorPtr() { return type_ == VAR_VARIANTVECTOR ? &value_.variantVector_ : nullptr; }
  1159. /// Return a pointer to a modifiable string vector or null on type mismatch.
  1160. StringVector* GetStringVectorPtr() { return type_ == VAR_STRINGVECTOR ? &value_.stringVector_ : nullptr; }
  1161. /// Return a pointer to a modifiable variant map or null on type mismatch.
  1162. VariantMap* GetVariantMapPtr() { return type_ == VAR_VARIANTMAP ? &value_.variantMap_ : nullptr; }
  1163. /// Return a pointer to a modifiable custom variant value or null on type mismatch.
  1164. template <class T> T* GetCustomPtr()
  1165. {
  1166. if (CustomVariantValue* value = GetCustomVariantValuePtr())
  1167. {
  1168. if (value->IsType<T>())
  1169. return value->GetValuePtr<T>();
  1170. }
  1171. return nullptr;
  1172. }
  1173. /// Return name for variant type.
  1174. static String GetTypeName(VariantType type);
  1175. /// Return variant type from type name.
  1176. static VariantType GetTypeFromName(const String& typeName);
  1177. /// Return variant type from type name.
  1178. static VariantType GetTypeFromName(const char* typeName);
  1179. /// Empty variant.
  1180. static const Variant EMPTY;
  1181. /// Empty buffer.
  1182. static const Vector<byte> emptyBuffer;
  1183. /// Empty resource reference.
  1184. static const ResourceRef emptyResourceRef;
  1185. /// Empty resource reference list.
  1186. static const ResourceRefList emptyResourceRefList;
  1187. /// Empty variant map.
  1188. static const VariantMap emptyVariantMap;
  1189. /// Empty variant vector.
  1190. static const VariantVector emptyVariantVector;
  1191. /// Empty string vector.
  1192. static const StringVector emptyStringVector;
  1193. private:
  1194. /// Set new type and allocate/deallocate memory as necessary.
  1195. void SetType(VariantType newType);
  1196. /// Variant type.
  1197. VariantType type_ = VAR_NONE;
  1198. /// Variant value.
  1199. VariantValue value_;
  1200. };
  1201. /// Return variant type from type.
  1202. template <typename T> VariantType GetVariantType();
  1203. // Return variant type from concrete types
  1204. template <> inline VariantType GetVariantType<int>() { return VAR_INT; }
  1205. template <> inline VariantType GetVariantType<unsigned>() { return VAR_INT; }
  1206. template <> inline VariantType GetVariantType<c32>() { return VAR_INT; }
  1207. template <> inline VariantType GetVariantType<long long>() { return VAR_INT64; }
  1208. template <> inline VariantType GetVariantType<unsigned long long>() { return VAR_INT64; }
  1209. template <> inline VariantType GetVariantType<bool>() { return VAR_BOOL; }
  1210. template <> inline VariantType GetVariantType<float>() { return VAR_FLOAT; }
  1211. template <> inline VariantType GetVariantType<double>() { return VAR_DOUBLE; }
  1212. template <> inline VariantType GetVariantType<Vector2>() { return VAR_VECTOR2; }
  1213. template <> inline VariantType GetVariantType<Vector3>() { return VAR_VECTOR3; }
  1214. template <> inline VariantType GetVariantType<Vector4>() { return VAR_VECTOR4; }
  1215. template <> inline VariantType GetVariantType<Quaternion>() { return VAR_QUATERNION; }
  1216. template <> inline VariantType GetVariantType<Color>() { return VAR_COLOR; }
  1217. template <> inline VariantType GetVariantType<String>() { return VAR_STRING; }
  1218. template <> inline VariantType GetVariantType<StringHash>() { return VAR_INT; }
  1219. template <> inline VariantType GetVariantType<Vector<byte>>() { return VAR_BUFFER; }
  1220. template <> inline VariantType GetVariantType<ResourceRef>() { return VAR_RESOURCEREF; }
  1221. template <> inline VariantType GetVariantType<ResourceRefList>() { return VAR_RESOURCEREFLIST; }
  1222. template <> inline VariantType GetVariantType<VariantVector>() { return VAR_VARIANTVECTOR; }
  1223. template <> inline VariantType GetVariantType<StringVector>() { return VAR_STRINGVECTOR; }
  1224. template <> inline VariantType GetVariantType<VariantMap>() { return VAR_VARIANTMAP; }
  1225. template <> inline VariantType GetVariantType<Rect>() { return VAR_RECT; }
  1226. template <> inline VariantType GetVariantType<IntRect>() { return VAR_INTRECT; }
  1227. template <> inline VariantType GetVariantType<IntVector2>() { return VAR_INTVECTOR2; }
  1228. template <> inline VariantType GetVariantType<IntVector3>() { return VAR_INTVECTOR3; }
  1229. template <> inline VariantType GetVariantType<Matrix3>() { return VAR_MATRIX3; }
  1230. template <> inline VariantType GetVariantType<Matrix3x4>() { return VAR_MATRIX3X4; }
  1231. template <> inline VariantType GetVariantType<Matrix4>() { return VAR_MATRIX4; }
  1232. // Specializations of Variant::Get<T>
  1233. template <> URHO3D_API int Variant::Get<int>() const;
  1234. template <> URHO3D_API unsigned Variant::Get<unsigned>() const;
  1235. template <> URHO3D_API c32 Variant::Get<c32>() const;
  1236. template <> URHO3D_API long long Variant::Get<long long>() const;
  1237. template <> URHO3D_API unsigned long long Variant::Get<unsigned long long>() const;
  1238. template <> URHO3D_API StringHash Variant::Get<StringHash>() const;
  1239. template <> URHO3D_API bool Variant::Get<bool>() const;
  1240. template <> URHO3D_API float Variant::Get<float>() const;
  1241. template <> URHO3D_API double Variant::Get<double>() const;
  1242. template <> URHO3D_API const Vector2& Variant::Get<const Vector2&>() const;
  1243. template <> URHO3D_API const Vector3& Variant::Get<const Vector3&>() const;
  1244. template <> URHO3D_API const Vector4& Variant::Get<const Vector4&>() const;
  1245. template <> URHO3D_API const Quaternion& Variant::Get<const Quaternion&>() const;
  1246. template <> URHO3D_API const Color& Variant::Get<const Color&>() const;
  1247. template <> URHO3D_API const String& Variant::Get<const String&>() const;
  1248. template <> URHO3D_API const Rect& Variant::Get<const Rect&>() const;
  1249. template <> URHO3D_API const IntRect& Variant::Get<const IntRect&>() const;
  1250. template <> URHO3D_API const IntVector2& Variant::Get<const IntVector2&>() const;
  1251. template <> URHO3D_API const IntVector3& Variant::Get<const IntVector3&>() const;
  1252. template <> URHO3D_API const Vector<byte>& Variant::Get<const Vector<byte>&>() const;
  1253. template <> URHO3D_API void* Variant::Get<void*>() const;
  1254. template <> URHO3D_API RefCounted* Variant::Get<RefCounted*>() const;
  1255. template <> URHO3D_API const Matrix3& Variant::Get<const Matrix3&>() const;
  1256. template <> URHO3D_API const Matrix3x4& Variant::Get<const Matrix3x4&>() const;
  1257. template <> URHO3D_API const Matrix4& Variant::Get<const Matrix4&>() const;
  1258. template <> URHO3D_API ResourceRef Variant::Get<ResourceRef>() const;
  1259. template <> URHO3D_API ResourceRefList Variant::Get<ResourceRefList>() const;
  1260. template <> URHO3D_API VariantVector Variant::Get<VariantVector>() const;
  1261. template <> URHO3D_API StringVector Variant::Get<StringVector>() const;
  1262. template <> URHO3D_API VariantMap Variant::Get<VariantMap>() const;
  1263. template <> URHO3D_API Vector2 Variant::Get<Vector2>() const;
  1264. template <> URHO3D_API Vector3 Variant::Get<Vector3>() const;
  1265. template <> URHO3D_API Vector4 Variant::Get<Vector4>() const;
  1266. template <> URHO3D_API Quaternion Variant::Get<Quaternion>() const;
  1267. template <> URHO3D_API Color Variant::Get<Color>() const;
  1268. template <> URHO3D_API String Variant::Get<String>() const;
  1269. template <> URHO3D_API Rect Variant::Get<Rect>() const;
  1270. template <> URHO3D_API IntRect Variant::Get<IntRect>() const;
  1271. template <> URHO3D_API IntVector2 Variant::Get<IntVector2>() const;
  1272. template <> URHO3D_API IntVector3 Variant::Get<IntVector3>() const;
  1273. template <> URHO3D_API Vector<byte> Variant::Get<Vector<byte>>() const;
  1274. template <> URHO3D_API Matrix3 Variant::Get<Matrix3>() const;
  1275. template <> URHO3D_API Matrix3x4 Variant::Get<Matrix3x4>() const;
  1276. template <> URHO3D_API Matrix4 Variant::Get<Matrix4>() const;
  1277. // Implementations
  1278. template <class T> T* CustomVariantValue::GetValuePtr()
  1279. {
  1280. if (IsType<T>())
  1281. {
  1282. auto impl = static_cast<CustomVariantValueImpl<T>*>(this);
  1283. return &impl->GetValue();
  1284. }
  1285. return nullptr;
  1286. }
  1287. template <class T> const T* CustomVariantValue::GetValuePtr() const
  1288. {
  1289. if (IsType<T>())
  1290. {
  1291. auto impl = static_cast<const CustomVariantValueImpl<T>*>(this);
  1292. return &impl->GetValue();
  1293. }
  1294. return nullptr;
  1295. }
  1296. }