BsAny.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "Prerequisites/BsPrerequisitesUtil.h"
  5. #include "Debug/BsDebug.h"
  6. #include <algorithm>
  7. #include <typeinfo>
  8. namespace bs
  9. {
  10. /** @addtogroup General
  11. * @{
  12. */
  13. /** Class capable of storing any general type, and safely extracting the proper type from the internal data. */
  14. class Any
  15. {
  16. private:
  17. class DataBase
  18. {
  19. public:
  20. virtual ~DataBase()
  21. { }
  22. virtual DataBase* clone() const = 0;
  23. };
  24. template <typename ValueType>
  25. class Data : public DataBase
  26. {
  27. public:
  28. Data(const ValueType& value)
  29. :value(value)
  30. { }
  31. virtual DataBase* clone() const override
  32. {
  33. return new Data(value);
  34. }
  35. ValueType value;
  36. };
  37. public:
  38. Any()
  39. :mData(nullptr)
  40. { }
  41. template <typename ValueType>
  42. Any(const ValueType& value)
  43. :mData(bs_new<Data<ValueType>>(value))
  44. { }
  45. Any(std::nullptr_t)
  46. :mData(nullptr)
  47. { }
  48. Any(const Any& other)
  49. :mData(other.mData != nullptr ? other.mData->clone() : nullptr)
  50. { }
  51. ~Any()
  52. {
  53. if (mData != nullptr)
  54. bs_delete(mData);
  55. }
  56. /** Swaps the contents of this object with another. */
  57. Any& swap(Any& rhs)
  58. {
  59. std::swap(mData, rhs.mData);
  60. return *this;
  61. }
  62. template <typename ValueType>
  63. Any& operator= (const ValueType& rhs)
  64. {
  65. if(mData)
  66. bs_delete(mData);
  67. mData = bs_new<Data<ValueType>>(rhs);
  68. return *this;
  69. }
  70. Any& operator= (const Any& rhs)
  71. {
  72. if(mData)
  73. bs_delete(mData);
  74. mData = rhs.mData != nullptr ? rhs.mData->clone() : nullptr;
  75. return *this;
  76. }
  77. /** Returns true if no type is set. */
  78. bool empty() const
  79. {
  80. return mData == nullptr;
  81. }
  82. private:
  83. template <typename ValueType>
  84. friend ValueType* any_cast(Any*);
  85. template <typename ValueType>
  86. friend ValueType* any_cast_unsafe(Any*);
  87. DataBase* mData;
  88. };
  89. /**
  90. * Returns a pointer to the internal data of the specified type.
  91. *
  92. * @note Will return null if cast fails.
  93. */
  94. template <typename ValueType>
  95. ValueType* any_cast(Any* operand)
  96. {
  97. if (operand != nullptr)
  98. return &static_cast<Any::Data<ValueType>*>(operand->mData)->value;
  99. else
  100. return nullptr;
  101. }
  102. /**
  103. * Returns a const pointer to the internal data of the specified type.
  104. *
  105. * @note Will return null if cast fails.
  106. */
  107. template <typename ValueType>
  108. const ValueType* any_cast(const Any* operand)
  109. {
  110. return any_cast<ValueType>(const_cast<Any*>(operand));
  111. }
  112. /**
  113. * Returns a copy of the internal data of the specified type.
  114. *
  115. * @note Throws an exception if cast fails.
  116. */
  117. template <typename ValueType>
  118. ValueType any_cast(const Any& operand)
  119. {
  120. return *any_cast<ValueType>(const_cast<Any*>(&operand));
  121. }
  122. /**
  123. * Returns a copy of the internal data of the specified type.
  124. *
  125. * @note Throws an exception if cast fails.
  126. */
  127. template <typename ValueType>
  128. ValueType any_cast(Any& operand)
  129. {
  130. return *any_cast<ValueType>(&operand);
  131. }
  132. /**
  133. * Returns a reference to the internal data of the specified type.
  134. *
  135. * @note Throws an exception if cast fails.
  136. */
  137. template <typename ValueType>
  138. const ValueType& any_cast_ref(const Any & operand)
  139. {
  140. return *any_cast<ValueType>(const_cast<Any*>(&operand));
  141. }
  142. /**
  143. * Returns a reference to the internal data of the specified type.
  144. *
  145. * @note Throws an exception if cast fails.
  146. */
  147. template <typename ValueType>
  148. ValueType& any_cast_ref(Any& operand)
  149. {
  150. return *any_cast<ValueType>(&operand);
  151. }
  152. /** Casts a type without performing any kind of checks. */
  153. template <typename ValueType>
  154. ValueType* any_cast_unsafe(Any* operand)
  155. {
  156. return &static_cast<Any::Data<ValueType>*>(operand->mData)->value;
  157. }
  158. /** Casts a type without performing any kind of checks. */
  159. template <typename ValueType>
  160. const ValueType* any_cast_unsafe(const Any* operand)
  161. {
  162. return any_cast_unsafe<ValueType>(const_cast<Any*>(operand));
  163. }
  164. /** @} */
  165. }