data_peer_id.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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. using BareId = uint64;
  9. struct PeerIdZeroHelper {
  10. };
  11. using PeerIdZero = void(PeerIdZeroHelper::*)();
  12. template <uint8 Shift>
  13. struct ChatIdType {
  14. BareId bare = 0;
  15. static constexpr BareId kShift = Shift;
  16. static constexpr BareId kReservedBit = BareId(0x80);
  17. static_assert((Shift & kReservedBit) == 0, "Last bit is reserved.");
  18. constexpr ChatIdType() noexcept = default;
  19. //constexpr ChatIdType(PeerIdZero) noexcept { // UserId id = 0;
  20. //}
  21. constexpr ChatIdType(BareId value) noexcept : bare(value) {
  22. }
  23. constexpr ChatIdType(MTPlong value) noexcept : bare(value.v) {
  24. }
  25. friend inline constexpr auto operator<=>(
  26. ChatIdType,
  27. ChatIdType) = default;
  28. [[nodiscard]] constexpr explicit operator bool() const noexcept {
  29. return (bare != 0);
  30. }
  31. [[nodiscard]] constexpr bool operator!() const noexcept {
  32. return !bare;
  33. }
  34. };
  35. template <uchar Shift>
  36. [[nodiscard]] inline constexpr bool operator==(
  37. ChatIdType<Shift> a,
  38. PeerIdZero) noexcept {
  39. return (a.bare == 0);
  40. }
  41. template <uchar Shift>
  42. [[nodiscard]] inline constexpr bool operator==(
  43. PeerIdZero,
  44. ChatIdType<Shift> a) noexcept {
  45. return (0 == a.bare);
  46. }
  47. template <uchar Shift>
  48. [[nodiscard]] inline constexpr bool operator!=(
  49. ChatIdType<Shift> a,
  50. PeerIdZero) noexcept {
  51. return (a.bare != 0);
  52. }
  53. template <uchar Shift>
  54. [[nodiscard]] inline constexpr bool operator!=(
  55. PeerIdZero,
  56. ChatIdType<Shift> a) noexcept {
  57. return (0 != a.bare);
  58. }
  59. template <uchar Shift>
  60. bool operator<(ChatIdType<Shift>, PeerIdZero) = delete;
  61. template <uchar Shift>
  62. bool operator<(PeerIdZero, ChatIdType<Shift>) = delete;
  63. template <uchar Shift>
  64. bool operator>(ChatIdType<Shift>, PeerIdZero) = delete;
  65. template <uchar Shift>
  66. bool operator>(PeerIdZero, ChatIdType<Shift>) = delete;
  67. template <uchar Shift>
  68. bool operator<=(ChatIdType<Shift>, PeerIdZero) = delete;
  69. template <uchar Shift>
  70. bool operator<=(PeerIdZero, ChatIdType<Shift>) = delete;
  71. template <uchar Shift>
  72. bool operator>=(ChatIdType<Shift>, PeerIdZero) = delete;
  73. template <uchar Shift>
  74. bool operator>=(PeerIdZero, ChatIdType<Shift>) = delete;
  75. using UserId = ChatIdType<0>;
  76. using ChatId = ChatIdType<1>;
  77. using ChannelId = ChatIdType<2>;
  78. using FakeChatId = ChatIdType<0x7F>;
  79. struct PeerIdHelper {
  80. BareId value = 0;
  81. constexpr PeerIdHelper(BareId value) noexcept : value(value) {
  82. }
  83. };
  84. struct PeerId {
  85. BareId value = 0;
  86. static constexpr BareId kChatTypeMask = BareId(0xFFFFFFFFFFFFULL);
  87. constexpr PeerId() noexcept = default;
  88. constexpr PeerId(PeerIdZero) noexcept { // PeerId id = 0;
  89. }
  90. template <uchar Shift>
  91. constexpr PeerId(ChatIdType<Shift> id) noexcept
  92. : value(id.bare | (BareId(Shift) << 48)) {
  93. }
  94. // This instead of explicit PeerId(BareId) allows to use both
  95. // PeerId(uint64(..)) and PeerId(0).
  96. constexpr PeerId(PeerIdHelper value) noexcept : value(value.value) {
  97. }
  98. friend inline constexpr auto operator<=>(PeerId, PeerId) = default;
  99. template <typename SomeChatIdType, BareId = SomeChatIdType::kShift>
  100. [[nodiscard]] constexpr bool is() const noexcept {
  101. return ((value >> 48) & BareId(0xFF)) == SomeChatIdType::kShift;
  102. }
  103. template <typename SomeChatIdType, BareId = SomeChatIdType::kShift>
  104. [[nodiscard]] constexpr SomeChatIdType to() const noexcept {
  105. return is<SomeChatIdType>() ? (value & kChatTypeMask) : 0;
  106. }
  107. [[nodiscard]] constexpr explicit operator bool() const noexcept {
  108. return (value != 0);
  109. }
  110. [[nodiscard]] constexpr bool operator!() const noexcept {
  111. return !value;
  112. }
  113. };
  114. [[nodiscard]] inline constexpr bool operator==(
  115. PeerId a,
  116. PeerIdZero) noexcept {
  117. return (a.value == 0);
  118. }
  119. [[nodiscard]] inline constexpr bool operator==(
  120. PeerIdZero,
  121. PeerId a) noexcept {
  122. return (0 == a.value);
  123. }
  124. [[nodiscard]] inline constexpr bool operator!=(
  125. PeerId a,
  126. PeerIdZero) noexcept {
  127. return (a.value != 0);
  128. }
  129. [[nodiscard]] inline constexpr bool operator!=(
  130. PeerIdZero,
  131. PeerId a) noexcept {
  132. return (0 != a.value);
  133. }
  134. bool operator<(PeerId, PeerIdZero) = delete;
  135. bool operator<(PeerIdZero, PeerId) = delete;
  136. bool operator>(PeerId, PeerIdZero) = delete;
  137. bool operator>(PeerIdZero, PeerId) = delete;
  138. bool operator<=(PeerId, PeerIdZero) = delete;
  139. bool operator<=(PeerIdZero, PeerId) = delete;
  140. bool operator>=(PeerId, PeerIdZero) = delete;
  141. bool operator>=(PeerIdZero, PeerId) = delete;
  142. [[nodiscard]] inline constexpr bool peerIsUser(PeerId id) noexcept {
  143. return id.is<UserId>();
  144. }
  145. [[nodiscard]] inline constexpr bool peerIsChat(PeerId id) noexcept {
  146. return id.is<ChatId>();
  147. }
  148. [[nodiscard]] inline constexpr bool peerIsChannel(PeerId id) noexcept {
  149. return id.is<ChannelId>();
  150. }
  151. [[nodiscard]] inline constexpr PeerId peerFromUser(UserId userId) noexcept {
  152. return userId;
  153. }
  154. [[nodiscard]] inline constexpr PeerId peerFromChat(ChatId chatId) noexcept {
  155. return chatId;
  156. }
  157. [[nodiscard]] inline constexpr PeerId peerFromChannel(
  158. ChannelId channelId) noexcept {
  159. return channelId;
  160. }
  161. [[nodiscard]] inline constexpr PeerId peerFromUser(MTPlong userId) noexcept {
  162. return peerFromUser(userId.v);
  163. }
  164. [[nodiscard]] inline constexpr PeerId peerFromChat(MTPint chatId) noexcept {
  165. return peerFromChat(chatId.v);
  166. }
  167. [[nodiscard]] inline constexpr PeerId peerFromChannel(
  168. MTPint channelId) noexcept {
  169. return peerFromChannel(channelId.v);
  170. }
  171. [[nodiscard]] inline constexpr UserId peerToUser(PeerId id) noexcept {
  172. return id.to<UserId>();
  173. }
  174. [[nodiscard]] inline constexpr ChatId peerToChat(PeerId id) noexcept {
  175. return id.to<ChatId>();
  176. }
  177. [[nodiscard]] inline constexpr ChannelId peerToChannel(PeerId id) noexcept {
  178. return id.to<ChannelId>();
  179. }
  180. [[nodiscard]] inline MTPlong peerToBareMTPInt(PeerId id) {
  181. return MTP_long(id.value & PeerId::kChatTypeMask);
  182. }
  183. [[nodiscard]] PeerId peerFromMTP(const MTPPeer &peer);
  184. [[nodiscard]] MTPpeer peerToMTP(PeerId id);
  185. // Supports both modern and legacy serializations.
  186. [[nodiscard]] PeerId DeserializePeerId(quint64 serialized);
  187. [[nodiscard]] quint64 SerializePeerId(PeerId id);
  188. namespace std {
  189. template <uchar Shift>
  190. struct hash<ChatIdType<Shift>> : private hash<BareId> {
  191. size_t operator()(ChatIdType<Shift> value) const noexcept {
  192. return hash<BareId>::operator()(value.bare);
  193. }
  194. };
  195. template <>
  196. struct hash<PeerId> : private hash<BareId> {
  197. size_t operator()(PeerId value) const noexcept {
  198. return hash<BareId>::operator()(value.value);
  199. }
  200. };
  201. } // namespace std