Variant.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. #ifndef RMLUI_CORE_VARIANT_H
  29. #define RMLUI_CORE_VARIANT_H
  30. #include "Animation.h"
  31. #include "Header.h"
  32. #include "TypeConverter.h"
  33. #include "Types.h"
  34. namespace Rml {
  35. /**
  36. Variant is a container that can store a selection of basic types. The variant will store the
  37. value in the native form corresponding to the version of Set that was called.
  38. Get is templated to convert from the stored form to the requested form by using a TypeConverter.
  39. @author Lloyd Weehuizen
  40. */
  41. class RMLUICORE_API Variant {
  42. public:
  43. /// Type of data stored in the variant. We use size_t as base to avoid 'padding due to alignment specifier' warning.
  44. enum Type : size_t {
  45. NONE = '-',
  46. BOOL = 'B',
  47. BYTE = 'b',
  48. CHAR = 'c',
  49. FLOAT = 'f',
  50. DOUBLE = 'd',
  51. INT = 'i',
  52. INT64 = 'I',
  53. UINT = 'u',
  54. UINT64 = 'U',
  55. STRING = 's',
  56. VECTOR2 = '2',
  57. VECTOR3 = '3',
  58. VECTOR4 = '4',
  59. COLOURF = 'g',
  60. COLOURB = 'h',
  61. SCRIPTINTERFACE = 'p',
  62. TRANSFORMPTR = 't',
  63. TRANSITIONLIST = 'T',
  64. ANIMATIONLIST = 'A',
  65. DECORATORSPTR = 'D',
  66. FILTERSPTR = 'F',
  67. FONTEFFECTSPTR = 'E',
  68. BOXSHADOWLIST = 'S',
  69. VOIDPTR = '*',
  70. };
  71. Variant();
  72. Variant(const Variant&);
  73. Variant(Variant&&) noexcept;
  74. Variant& operator=(const Variant& copy);
  75. Variant& operator=(Variant&& other) noexcept;
  76. ~Variant();
  77. // Construct by variant type
  78. template <typename T, typename = std::enable_if_t<!std::is_same<Variant, std::decay_t<T>>::value>>
  79. explicit Variant(T&& t);
  80. // Assign by variant type
  81. template <typename T, typename = std::enable_if_t<!std::is_same<Variant, std::decay_t<T>>::value>>
  82. Variant& operator=(T&& t);
  83. void Clear();
  84. inline Type GetType() const;
  85. /// Templatised data accessor. TypeConverters will be used to attempt to convert from the internal representation to
  86. /// the requested representation.
  87. /// @param[in] default_value The value returned if the conversion failed.
  88. /// @return Data in the requested type.
  89. template <typename T>
  90. T Get(T default_value = T()) const;
  91. /// Templatised data accessor. TypeConverters will be used to attempt to convert from the internal representation to
  92. /// the requested representation.
  93. /// @param[out] value Data in the requested type.
  94. /// @return True if the value was converted and returned, false if no data was stored in the variant.
  95. template <typename T, typename std::enable_if_t<!std::is_enum<T>::value, int> = 0>
  96. bool GetInto(T& value) const;
  97. /// Enum overload for the data accessor, will convert any stored integral value to the requested enum type.
  98. template <typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
  99. bool GetInto(T& value) const;
  100. /// Returns a reference to the variant's underlying type.
  101. /// @warning: Undefined behavior if T does not represent the underlying type of the variant.
  102. template <typename T>
  103. const T& GetReference() const;
  104. bool operator==(const Variant& other) const;
  105. bool operator!=(const Variant& other) const { return !(*this == other); }
  106. private:
  107. /// Copy another variant's data to this variant.
  108. /// @warning Does not clear existing data.
  109. void Set(const Variant& copy);
  110. void Set(Variant&& other);
  111. void Set(const bool value);
  112. void Set(const byte value);
  113. void Set(const char value);
  114. void Set(const float value);
  115. void Set(const double value);
  116. void Set(const int value);
  117. void Set(const int64_t value);
  118. void Set(const unsigned int value);
  119. void Set(const uint64_t value);
  120. void Set(const char* value);
  121. void Set(void* value);
  122. void Set(const Vector2f value);
  123. void Set(const Vector3f value);
  124. void Set(const Vector4f value);
  125. void Set(const Colourf value);
  126. void Set(const Colourb value);
  127. void Set(ScriptInterface* value);
  128. void Set(const String& value);
  129. void Set(String&& value);
  130. void Set(const TransformPtr& value);
  131. void Set(TransformPtr&& value);
  132. void Set(const TransitionList& value);
  133. void Set(TransitionList&& value);
  134. void Set(const AnimationList& value);
  135. void Set(AnimationList&& value);
  136. void Set(const DecoratorsPtr& value);
  137. void Set(DecoratorsPtr&& value);
  138. void Set(const FiltersPtr& value);
  139. void Set(FiltersPtr&& value);
  140. void Set(const FontEffectsPtr& value);
  141. void Set(FontEffectsPtr&& value);
  142. void Set(const BoxShadowList& value);
  143. void Set(BoxShadowList&& value);
  144. template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
  145. void Set(const T value);
  146. static constexpr size_t LOCAL_DATA_SIZE = (sizeof(TransitionList) > sizeof(String) ? sizeof(TransitionList) : sizeof(String));
  147. Type type = NONE;
  148. alignas(TransitionList) char data[LOCAL_DATA_SIZE];
  149. };
  150. } // namespace Rml
  151. #include "Variant.inl"
  152. #endif