Variant.inl 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * This source file is part of RmlUi, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://github.com/mikke89/RmlUi
  5. *
  6. * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
  7. * Copyright (c) 2019-2023 The RmlUi Team, and contributors
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. *
  27. */
  28. namespace Rml {
  29. inline Variant::Type Variant::GetType() const
  30. {
  31. return type;
  32. }
  33. template <typename T, typename>
  34. Variant::Variant(T&& t)
  35. {
  36. Set(std::forward<T>(t));
  37. }
  38. template <typename T, typename>
  39. Variant& Variant::operator=(T&& t)
  40. {
  41. Clear();
  42. Set(std::forward<T>(t));
  43. return *this;
  44. }
  45. template <typename T, typename std::enable_if_t<!std::is_enum<T>::value, int>>
  46. bool Variant::GetInto(T& value) const
  47. {
  48. switch (type)
  49. {
  50. case BOOL: return TypeConverter<bool, T>::Convert(*reinterpret_cast<const bool*>(data), value);
  51. case BYTE: return TypeConverter<byte, T>::Convert(*reinterpret_cast<const byte*>(data), value);
  52. case CHAR: return TypeConverter<char, T>::Convert(*reinterpret_cast<const char*>(data), value);
  53. case FLOAT: return TypeConverter<float, T>::Convert(*reinterpret_cast<const float*>(data), value);
  54. case DOUBLE: return TypeConverter<double, T>::Convert(*reinterpret_cast<const double*>(data), value);
  55. case INT: return TypeConverter<int, T>::Convert(*reinterpret_cast<const int*>(data), value);
  56. case INT64: return TypeConverter<int64_t, T>::Convert(*reinterpret_cast<const int64_t*>(data), value);
  57. case UINT: return TypeConverter<unsigned int, T>::Convert(*reinterpret_cast<const unsigned int*>(data), value);
  58. case UINT64: return TypeConverter<uint64_t, T>::Convert(*reinterpret_cast<const uint64_t*>(data), value);
  59. case STRING: return TypeConverter<String, T>::Convert(*reinterpret_cast<const String*>(data), value);
  60. case VECTOR2: return TypeConverter<Vector2f, T>::Convert(*reinterpret_cast<const Vector2f*>(data), value);
  61. case VECTOR3: return TypeConverter<Vector3f, T>::Convert(*reinterpret_cast<const Vector3f*>(data), value);
  62. case VECTOR4: return TypeConverter<Vector4f, T>::Convert(*reinterpret_cast<const Vector4f*>(data), value);
  63. case COLOURF: return TypeConverter<Colourf, T>::Convert(*reinterpret_cast<const Colourf*>(data), value);
  64. case COLOURB: return TypeConverter<Colourb, T>::Convert(*reinterpret_cast<const Colourb*>(data), value);
  65. case SCRIPTINTERFACE: return TypeConverter<ScriptInterface*, T>::Convert(*reinterpret_cast<ScriptInterface* const*>(data), value);
  66. case VOIDPTR: return TypeConverter<void*, T>::Convert(*reinterpret_cast<void* const*>(data), value);
  67. case TRANSFORMPTR: return TypeConverter<TransformPtr, T>::Convert(*reinterpret_cast<const TransformPtr*>(data), value);
  68. case TRANSITIONLIST: return TypeConverter<TransitionList, T>::Convert(*reinterpret_cast<const TransitionList*>(data), value);
  69. case ANIMATIONLIST: return TypeConverter<AnimationList, T>::Convert(*reinterpret_cast<const AnimationList*>(data), value);
  70. case DECORATORSPTR: return TypeConverter<DecoratorsPtr, T>::Convert(*reinterpret_cast<const DecoratorsPtr*>(data), value);
  71. case FILTERSPTR: return TypeConverter<FiltersPtr, T>::Convert(*reinterpret_cast<const FiltersPtr*>(data), value);
  72. case FONTEFFECTSPTR: return TypeConverter<FontEffectsPtr, T>::Convert(*reinterpret_cast<const FontEffectsPtr*>(data), value);
  73. case COLORSTOPLIST: return TypeConverter<ColorStopList, T>::Convert(*(ColorStopList*)data, value); break;
  74. case BOXSHADOWLIST: return TypeConverter<BoxShadowList, T>::Convert(*reinterpret_cast<const BoxShadowList*>(data), value);
  75. case NONE: break;
  76. }
  77. return false;
  78. }
  79. template <typename T, typename std::enable_if_t<std::is_enum<T>::value, int>>
  80. bool Variant::GetInto(T& value) const
  81. {
  82. static_assert(sizeof(T) <= sizeof(int64_t), "Enum underlying type exceeds maximum supported integer type size");
  83. int64_t stored_value = 0;
  84. if (GetInto(stored_value))
  85. {
  86. value = static_cast<T>(stored_value);
  87. return true;
  88. }
  89. return false;
  90. }
  91. template <typename T>
  92. T Variant::Get(T default_value) const
  93. {
  94. GetInto(default_value);
  95. return default_value;
  96. }
  97. template <typename T>
  98. const T& Variant::GetReference() const
  99. {
  100. return *reinterpret_cast<const T*>(&data);
  101. }
  102. template <typename T, typename>
  103. void Variant::Set(const T value)
  104. {
  105. static_assert(sizeof(T) <= sizeof(int64_t), "Enum underlying type exceeds maximum supported integer type size");
  106. type = INT64;
  107. *(reinterpret_cast<int64_t*>(data)) = static_cast<int64_t>(value);
  108. }
  109. } // namespace Rml