BsAny.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsPrerequisitesUtil.h"
  5. #include "BsDebug.h"
  6. #include <algorithm>
  7. #include <typeinfo>
  8. namespace BansheeEngine
  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(const Any& other)
  46. :mData(other.mData != nullptr ? other.mData->clone() : nullptr)
  47. { }
  48. ~Any()
  49. {
  50. if (mData != nullptr)
  51. bs_delete(mData);
  52. }
  53. /** Swaps the contents of this object with another. */
  54. Any& swap(Any& rhs)
  55. {
  56. std::swap(mData, rhs.mData);
  57. return *this;
  58. }
  59. template <typename ValueType>
  60. Any& operator= (const ValueType& rhs)
  61. {
  62. Any(rhs).swap(*this);
  63. return *this;
  64. }
  65. Any& operator= (const Any& rhs)
  66. {
  67. Any(rhs).swap(*this);
  68. return *this;
  69. }
  70. /** Returns true if no type is set. */
  71. bool empty() const
  72. {
  73. return mData == nullptr;
  74. }
  75. private:
  76. template <typename ValueType>
  77. friend ValueType* any_cast(Any*);
  78. template <typename ValueType>
  79. friend ValueType* any_cast_unsafe(Any*);
  80. DataBase* mData;
  81. };
  82. /**
  83. * Returns a pointer to the internal data of the specified type.
  84. *
  85. * @note Will return null if cast fails.
  86. */
  87. template <typename ValueType>
  88. ValueType* any_cast(Any* operand)
  89. {
  90. if (operand != nullptr)
  91. return &static_cast<Any::Data<ValueType>*>(operand->mData)->value;
  92. else
  93. return nullptr;
  94. }
  95. /**
  96. * Returns a const pointer to the internal data of the specified type.
  97. *
  98. * @note Will return null if cast fails.
  99. */
  100. template <typename ValueType>
  101. const ValueType* any_cast(const Any* operand)
  102. {
  103. return any_cast<ValueType>(const_cast<Any*>(operand));
  104. }
  105. /**
  106. * Returns a copy of the internal data of the specified type.
  107. *
  108. * @note Throws an exception if cast fails.
  109. */
  110. template <typename ValueType>
  111. ValueType any_cast(const Any& operand)
  112. {
  113. return *any_cast<ValueType>(const_cast<Any*>(&operand));
  114. }
  115. /**
  116. * Returns a copy of the internal data of the specified type.
  117. *
  118. * @note Throws an exception if cast fails.
  119. */
  120. template <typename ValueType>
  121. ValueType any_cast(Any& operand)
  122. {
  123. return *any_cast<ValueType>(&operand);
  124. }
  125. /**
  126. * Returns a reference to the internal data of the specified type.
  127. *
  128. * @note Throws an exception if cast fails.
  129. */
  130. template <typename ValueType>
  131. const ValueType& any_cast_ref(const Any & operand)
  132. {
  133. return *any_cast<ValueType>(const_cast<Any*>(&operand));
  134. }
  135. /**
  136. * Returns a reference to the internal data of the specified type.
  137. *
  138. * @note Throws an exception if cast fails.
  139. */
  140. template <typename ValueType>
  141. ValueType& any_cast_ref(Any& operand)
  142. {
  143. return *any_cast<ValueType>(&operand);
  144. }
  145. /** Casts a type without performing any kind of checks. */
  146. template <typename ValueType>
  147. ValueType* any_cast_unsafe(Any* operand)
  148. {
  149. return &static_cast<Any::Data<ValueType>*>(operand->mData)->value;
  150. }
  151. /** Casts a type without performing any kind of checks. */
  152. template <typename ValueType>
  153. const ValueType* any_cast_unsafe(const Any* operand)
  154. {
  155. return any_cast_unsafe<ValueType>(const_cast<Any*>(operand));
  156. }
  157. /** @} */
  158. }