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