data_msg_id.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/qt/qt_compare.h"
  9. #include "data/data_peer_id.h"
  10. #include "ui/text/text_entity.h"
  11. struct MsgId {
  12. constexpr MsgId() noexcept = default;
  13. constexpr MsgId(int64 value) noexcept : bare(value) {
  14. }
  15. friend inline constexpr auto operator<=>(MsgId, MsgId) = default;
  16. [[nodiscard]] constexpr explicit operator bool() const noexcept {
  17. return (bare != 0);
  18. }
  19. [[nodiscard]] constexpr bool operator!() const noexcept {
  20. return !bare;
  21. }
  22. [[nodiscard]] constexpr MsgId operator-() const noexcept {
  23. return -bare;
  24. }
  25. constexpr MsgId operator++() noexcept {
  26. return ++bare;
  27. }
  28. constexpr MsgId operator++(int) noexcept {
  29. return bare++;
  30. }
  31. constexpr MsgId operator--() noexcept {
  32. return --bare;
  33. }
  34. constexpr MsgId operator--(int) noexcept {
  35. return bare--;
  36. }
  37. int64 bare = 0;
  38. };
  39. Q_DECLARE_METATYPE(MsgId);
  40. [[nodiscard]] inline constexpr MsgId operator+(MsgId a, MsgId b) noexcept {
  41. return MsgId(a.bare + b.bare);
  42. }
  43. [[nodiscard]] inline constexpr MsgId operator-(MsgId a, MsgId b) noexcept {
  44. return MsgId(a.bare - b.bare);
  45. }
  46. using StoryId = int32;
  47. using BusinessShortcutId = int32;
  48. struct FullStoryId {
  49. PeerId peer = 0;
  50. StoryId story = 0;
  51. [[nodiscard]] bool valid() const {
  52. return peer != 0 && story != 0;
  53. }
  54. explicit operator bool() const {
  55. return valid();
  56. }
  57. friend inline auto operator<=>(FullStoryId, FullStoryId) = default;
  58. friend inline bool operator==(FullStoryId, FullStoryId) = default;
  59. };
  60. constexpr auto StartClientMsgId = MsgId(0x01 - (1LL << 58));
  61. constexpr auto ClientMsgIds = (1LL << 31);
  62. constexpr auto EndClientMsgId = MsgId(StartClientMsgId.bare + ClientMsgIds);
  63. constexpr auto StartStoryMsgId = MsgId(EndClientMsgId.bare + 1);
  64. constexpr auto ServerMaxStoryId = StoryId(1 << 30);
  65. constexpr auto StoryMsgIds = int64(ServerMaxStoryId);
  66. constexpr auto EndStoryMsgId = MsgId(StartStoryMsgId.bare + StoryMsgIds);
  67. constexpr auto ServerMaxMsgId = MsgId(1LL << 56);
  68. constexpr auto ScheduledMaxMsgId = MsgId(ServerMaxMsgId + (1LL << 32));
  69. constexpr auto ShortcutMaxMsgId = MsgId(ScheduledMaxMsgId + (1LL << 32));
  70. constexpr auto ShowAtUnreadMsgId = MsgId(0);
  71. constexpr auto SpecialMsgIdShift = EndStoryMsgId.bare;
  72. constexpr auto ShowAtTheEndMsgId = MsgId(SpecialMsgIdShift + 1);
  73. constexpr auto SwitchAtTopMsgId = MsgId(SpecialMsgIdShift + 2);
  74. constexpr auto ShowAndStartBotMsgId = MsgId(SpecialMsgIdShift + 4);
  75. constexpr auto ShowAndMaybeStartBotMsgId = MsgId(SpecialMsgIdShift + 5);
  76. constexpr auto ShowForChooseMessagesMsgId = MsgId(SpecialMsgIdShift + 6);
  77. constexpr auto kSearchQueryOffsetHint = -1;
  78. static_assert(SpecialMsgIdShift + 0xFF < 0);
  79. static_assert(-(SpecialMsgIdShift + 0xFF) > ServerMaxMsgId);
  80. [[nodiscard]] constexpr inline bool IsClientMsgId(MsgId id) noexcept {
  81. return (id >= StartClientMsgId && id < EndClientMsgId);
  82. }
  83. [[nodiscard]] constexpr inline int32 ClientMsgIndex(MsgId id) noexcept {
  84. Expects(IsClientMsgId(id));
  85. return int(id.bare - StartClientMsgId.bare);
  86. }
  87. [[nodiscard]] constexpr inline MsgId ClientMsgByIndex(int32 index) noexcept {
  88. Expects(index >= 0);
  89. return MsgId(StartClientMsgId.bare + index);
  90. }
  91. [[nodiscrd]] constexpr inline bool IsStoryMsgId(MsgId id) noexcept {
  92. return (id >= StartStoryMsgId && id < EndStoryMsgId);
  93. }
  94. [[nodiscard]] constexpr inline StoryId StoryIdFromMsgId(MsgId id) noexcept {
  95. Expects(IsStoryMsgId(id));
  96. return StoryId(id.bare - StartStoryMsgId.bare);
  97. }
  98. [[nodiscard]] constexpr inline MsgId StoryIdToMsgId(StoryId id) noexcept {
  99. Expects(id >= 0);
  100. return MsgId(StartStoryMsgId.bare + id);
  101. }
  102. [[nodiscard]] constexpr inline bool IsServerMsgId(MsgId id) noexcept {
  103. return (id > 0 && id < ServerMaxMsgId);
  104. }
  105. struct MsgRange {
  106. constexpr MsgRange() noexcept = default;
  107. constexpr MsgRange(MsgId from, MsgId till) noexcept
  108. : from(from)
  109. , till(till) {
  110. }
  111. friend inline constexpr bool operator==(MsgRange, MsgRange) = default;
  112. MsgId from = 0;
  113. MsgId till = 0;
  114. };
  115. struct FullMsgId {
  116. constexpr FullMsgId() noexcept = default;
  117. constexpr FullMsgId(PeerId peer, MsgId msg) noexcept
  118. : peer(peer), msg(msg) {
  119. }
  120. FullMsgId(ChannelId channelId, MsgId msgId) = delete;
  121. friend inline constexpr auto operator<=>(FullMsgId, FullMsgId) = default;
  122. constexpr explicit operator bool() const noexcept {
  123. return msg != 0;
  124. }
  125. constexpr bool operator!() const noexcept {
  126. return msg == 0;
  127. }
  128. PeerId peer = 0;
  129. MsgId msg = 0;
  130. };
  131. #ifdef _DEBUG
  132. inline QDebug operator<<(QDebug debug, const FullMsgId &fullMsgId) {
  133. debug.nospace()
  134. << "FullMsgId(peer: "
  135. << fullMsgId.peer.value
  136. << ", msg: "
  137. << fullMsgId.msg.bare
  138. << ")";
  139. return debug;
  140. }
  141. #endif // _DEBUG
  142. Q_DECLARE_METATYPE(FullMsgId);
  143. struct FullReplyTo {
  144. FullMsgId messageId;
  145. TextWithEntities quote;
  146. FullStoryId storyId;
  147. MsgId topicRootId = 0;
  148. int quoteOffset = 0;
  149. [[nodiscard]] bool valid() const {
  150. return messageId || (storyId && storyId.peer);
  151. }
  152. explicit operator bool() const {
  153. return valid();
  154. }
  155. friend inline auto operator<=>(FullReplyTo, FullReplyTo) = default;
  156. friend inline bool operator==(FullReplyTo, FullReplyTo) = default;
  157. };
  158. struct GlobalMsgId {
  159. FullMsgId itemId;
  160. uint64 sessionUniqueId = 0;
  161. friend inline constexpr auto operator<=>(
  162. GlobalMsgId,
  163. GlobalMsgId) = default;
  164. constexpr explicit operator bool() const noexcept {
  165. return itemId && sessionUniqueId;
  166. }
  167. constexpr bool operator!() const noexcept {
  168. return !itemId || !sessionUniqueId;
  169. }
  170. };
  171. namespace std {
  172. template <>
  173. struct hash<MsgId> : private hash<int64> {
  174. size_t operator()(MsgId value) const noexcept {
  175. return hash<int64>::operator()(value.bare);
  176. }
  177. };
  178. template <>
  179. struct hash<FullStoryId> {
  180. size_t operator()(FullStoryId value) const {
  181. return QtPrivate::QHashCombine().operator()(
  182. std::hash<BareId>()(value.peer.value),
  183. value.story);
  184. }
  185. };
  186. template <>
  187. struct hash<FullMsgId> {
  188. size_t operator()(FullMsgId value) const {
  189. return QtPrivate::QHashCombine().operator()(
  190. std::hash<BareId>()(value.peer.value),
  191. value.msg.bare);
  192. }
  193. };
  194. } // namespace std