IdentifierBase.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * IdentifierBase.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. class IdentifierBase
  12. {
  13. protected:
  14. constexpr IdentifierBase():
  15. num(-1)
  16. {}
  17. explicit constexpr IdentifierBase(int32_t value):
  18. num(value)
  19. {}
  20. ~IdentifierBase() = default;
  21. public:
  22. int32_t num;
  23. constexpr int32_t getNum() const
  24. {
  25. return num;
  26. }
  27. constexpr void setNum(int32_t value)
  28. {
  29. num = value;
  30. }
  31. struct hash
  32. {
  33. size_t operator()(const IdentifierBase & id) const
  34. {
  35. return std::hash<int>()(id.num);
  36. }
  37. };
  38. constexpr void advance(int change)
  39. {
  40. num += change;
  41. }
  42. constexpr operator int32_t () const
  43. {
  44. return num;
  45. }
  46. friend std::ostream& operator<<(std::ostream& os, const IdentifierBase& dt)
  47. {
  48. return os << dt.num;
  49. }
  50. };
  51. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  52. // Note: use template to force different type, blocking any Identifier<A> <=> Identifier<B> comparisons
  53. template<typename FinalClass>
  54. class Identifier : public IdentifierBase
  55. {
  56. using BaseClass = IdentifierBase;
  57. public:
  58. constexpr Identifier()
  59. {}
  60. explicit constexpr Identifier(int32_t value):
  61. IdentifierBase(value)
  62. {}
  63. constexpr bool operator == (const Identifier & b) const { return BaseClass::num == b.num; }
  64. constexpr bool operator <= (const Identifier & b) const { return BaseClass::num <= b.num; }
  65. constexpr bool operator >= (const Identifier & b) const { return BaseClass::num >= b.num; }
  66. constexpr bool operator != (const Identifier & b) const { return BaseClass::num != b.num; }
  67. constexpr bool operator < (const Identifier & b) const { return BaseClass::num < b.num; }
  68. constexpr bool operator > (const Identifier & b) const { return BaseClass::num > b.num; }
  69. constexpr FinalClass & operator++()
  70. {
  71. ++BaseClass::num;
  72. return static_cast<FinalClass&>(*this);
  73. }
  74. constexpr FinalClass & operator--()
  75. {
  76. --BaseClass::num;
  77. return static_cast<FinalClass&>(*this);
  78. }
  79. constexpr FinalClass operator--(int)
  80. {
  81. FinalClass ret(num);
  82. --BaseClass::num;
  83. return ret;
  84. }
  85. constexpr FinalClass operator++(int)
  86. {
  87. FinalClass ret(num);
  88. ++BaseClass::num;
  89. return ret;
  90. }
  91. };
  92. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93. template<typename FinalClass, typename BaseClass>
  94. class IdentifierWithEnum : public BaseClass
  95. {
  96. using EnumType = typename BaseClass::Type;
  97. static_assert(std::is_same_v<std::underlying_type_t<EnumType>, int32_t>, "Entity Identifier must use int32_t");
  98. public:
  99. constexpr EnumType toEnum() const
  100. {
  101. return static_cast<EnumType>(BaseClass::num);
  102. }
  103. constexpr IdentifierWithEnum(const EnumType & enumValue)
  104. {
  105. BaseClass::num = static_cast<int32_t>(enumValue);
  106. }
  107. constexpr IdentifierWithEnum(int32_t _num = -1)
  108. {
  109. BaseClass::num = _num;
  110. }
  111. constexpr bool operator == (const EnumType & b) const { return BaseClass::num == static_cast<int32_t>(b); }
  112. constexpr bool operator <= (const EnumType & b) const { return BaseClass::num <= static_cast<int32_t>(b); }
  113. constexpr bool operator >= (const EnumType & b) const { return BaseClass::num >= static_cast<int32_t>(b); }
  114. constexpr bool operator != (const EnumType & b) const { return BaseClass::num != static_cast<int32_t>(b); }
  115. constexpr bool operator < (const EnumType & b) const { return BaseClass::num < static_cast<int32_t>(b); }
  116. constexpr bool operator > (const EnumType & b) const { return BaseClass::num > static_cast<int32_t>(b); }
  117. constexpr bool operator == (const IdentifierWithEnum & b) const { return BaseClass::num == b.num; }
  118. constexpr bool operator <= (const IdentifierWithEnum & b) const { return BaseClass::num <= b.num; }
  119. constexpr bool operator >= (const IdentifierWithEnum & b) const { return BaseClass::num >= b.num; }
  120. constexpr bool operator != (const IdentifierWithEnum & b) const { return BaseClass::num != b.num; }
  121. constexpr bool operator < (const IdentifierWithEnum & b) const { return BaseClass::num < b.num; }
  122. constexpr bool operator > (const IdentifierWithEnum & b) const { return BaseClass::num > b.num; }
  123. constexpr FinalClass & operator++()
  124. {
  125. ++BaseClass::num;
  126. return static_cast<FinalClass&>(*this);
  127. }
  128. constexpr FinalClass operator++(int)
  129. {
  130. FinalClass ret(BaseClass::num);
  131. ++BaseClass::num;
  132. return ret;
  133. }
  134. };
  135. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  136. template<typename FinalClass>
  137. class EntityIdentifier : public Identifier<FinalClass>
  138. {
  139. public:
  140. using Identifier<FinalClass>::Identifier;
  141. template <typename Handler>
  142. void serialize(Handler &h, const int version)
  143. {
  144. auto * finalClass = static_cast<FinalClass*>(this);
  145. std::string value;
  146. if (h.saving)
  147. value = FinalClass::encode(finalClass->num);
  148. h & value;
  149. if (!h.saving)
  150. finalClass->num = FinalClass::decode(value);
  151. }
  152. };
  153. template<typename FinalClass, typename BaseClass>
  154. class EntityIdentifierWithEnum : public IdentifierWithEnum<FinalClass, BaseClass>
  155. {
  156. public:
  157. using IdentifierWithEnum<FinalClass, BaseClass>::IdentifierWithEnum;
  158. template <typename Handler>
  159. void serialize(Handler &h, const int version)
  160. {
  161. auto * finalClass = static_cast<FinalClass*>(this);
  162. std::string value;
  163. if (h.saving)
  164. value = FinalClass::encode(finalClass->num);
  165. h & value;
  166. if (!h.saving)
  167. finalClass->num = FinalClass::decode(value);
  168. }
  169. };
  170. template<typename FinalClass>
  171. class StaticIdentifier : public Identifier<FinalClass>
  172. {
  173. public:
  174. using Identifier<FinalClass>::Identifier;
  175. template <typename Handler>
  176. void serialize(Handler &h, const int version)
  177. {
  178. auto * finalClass = static_cast<FinalClass*>(this);
  179. h & finalClass->num;
  180. }
  181. };
  182. template<typename FinalClass, typename BaseClass>
  183. class StaticIdentifierWithEnum : public IdentifierWithEnum<FinalClass, BaseClass>
  184. {
  185. public:
  186. using IdentifierWithEnum<FinalClass, BaseClass>::IdentifierWithEnum;
  187. template <typename Handler>
  188. void serialize(Handler &h, const int version)
  189. {
  190. auto * finalClass = static_cast<FinalClass*>(this);
  191. h & finalClass->num;
  192. }
  193. };
  194. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////