1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com> |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #ifndef QTPROTOBUFTYPES_H |
6 | #define QTPROTOBUFTYPES_H |
7 | |
8 | #include <QtProtobuf/qprotobufmessage.h> |
9 | #include <QtProtobuf/qtprotobufexports.h> |
10 | |
11 | #include <QtCore/qendian.h> |
12 | #include <QtCore/qhash.h> |
13 | #include <QtCore/qlist.h> |
14 | #include <QtCore/qmetatype.h> |
15 | #include <QtCore/qstring.h> |
16 | |
17 | #include <type_traits> |
18 | |
19 | QT_BEGIN_NAMESPACE |
20 | |
21 | namespace QtProtobuf { |
22 | Q_NAMESPACE_EXPORT(Q_PROTOBUF_EXPORT) |
23 | |
24 | [[maybe_unused]] constexpr int InvalidFieldNumber = 0; |
25 | |
26 | enum class WireTypes |
27 | { |
28 | Unknown = -1, |
29 | Varint = 0, |
30 | Fixed64 = 1, |
31 | LengthDelimited = 2, |
32 | StartGroup = 3, |
33 | EndGroup = 4, |
34 | Fixed32 = 5 |
35 | }; |
36 | Q_ENUM_NS(WireTypes) |
37 | |
38 | // The 'tag' template param exists only create a unique type |
39 | template<typename T, typename tag> |
40 | struct TransparentWrapper |
41 | { |
42 | TransparentWrapper(T t_ = T()) : t(t_) { } |
43 | T t; |
44 | operator T &() { return t; } |
45 | operator T() const { return t; } |
46 | TransparentWrapper &operator=(T t_) |
47 | { |
48 | t = t_; |
49 | return *this; |
50 | } |
51 | |
52 | static T toType(TransparentWrapper t) { return t.t; } |
53 | static TransparentWrapper fromType(T t) { return TransparentWrapper(t); } |
54 | |
55 | static QString toString(TransparentWrapper t) { return QString::number(t.t); } |
56 | |
57 | private: |
58 | friend constexpr TransparentWrapper qbswap(TransparentWrapper source) |
59 | { |
60 | return { QT_PREPEND_NAMESPACE(qbswap)(source.t) }; |
61 | } |
62 | |
63 | friend size_t qHash(TransparentWrapper key, size_t seed = 0) noexcept |
64 | { |
65 | return QT_PREPEND_NAMESPACE(qHash)(seed, key.t); |
66 | } |
67 | }; |
68 | |
69 | using int32 = TransparentWrapper<int32_t, struct int_tag>; |
70 | using int64 = TransparentWrapper<int64_t, struct int_tag>; |
71 | using uint32 = uint32_t; |
72 | using uint64 = uint64_t; |
73 | using sint32 = int32_t; |
74 | using sint64 = int64_t; |
75 | using fixed32 = TransparentWrapper<uint32_t, struct fixed_tag>; |
76 | using fixed64 = TransparentWrapper<uint64_t, struct fixed_tag>; |
77 | using sfixed32 = TransparentWrapper<int32_t, struct fixed_tag>; |
78 | using sfixed64 = TransparentWrapper<int64_t, struct fixed_tag>; |
79 | using boolean = bool; |
80 | using int32List = QList<int32>; |
81 | using int64List = QList<int64>; |
82 | using uint32List = QList<uint32>; |
83 | using uint64List = QList<uint64>; |
84 | using sint32List = QList<sint32>; |
85 | using sint64List = QList<sint64>; |
86 | using fixed32List = QList<fixed32>; |
87 | using fixed64List = QList<fixed64>; |
88 | using sfixed32List = QList<sfixed32>; |
89 | using sfixed64List = QList<sfixed64>; |
90 | using floatList = QList<float>; |
91 | using doubleList = QList<double>; |
92 | using boolList = QList<bool>; |
93 | |
94 | template<typename T> |
95 | using HasProtobufStaticPropertyOrdering = decltype(T::staticPropertyOrdering); |
96 | |
97 | template <typename T> |
98 | using has_q_protobuf_object_macro = qxp::is_detected<HasProtobufStaticPropertyOrdering, T>; |
99 | |
100 | template <typename T> |
101 | constexpr bool has_q_protobuf_object_macro_v = has_q_protobuf_object_macro<T>::value; |
102 | |
103 | template <typename T> |
104 | inline constexpr bool IsProtobufScalarValueType = false; |
105 | template <> |
106 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::int32> = true; |
107 | template <> |
108 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::int64> = true; |
109 | template <> |
110 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::sint32> = true; |
111 | template <> |
112 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::sint64> = true; |
113 | template <> |
114 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::uint32> = true; |
115 | template <> |
116 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::uint64> = true; |
117 | template <> |
118 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::fixed32> = true; |
119 | template <> |
120 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::fixed64> = true; |
121 | template <> |
122 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::sfixed32> = true; |
123 | template <> |
124 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::sfixed64> = true; |
125 | template <> |
126 | constexpr inline bool IsProtobufScalarValueType<float> = true; |
127 | template <> |
128 | constexpr inline bool IsProtobufScalarValueType<double> = true; |
129 | template <> |
130 | constexpr inline bool IsProtobufScalarValueType<QtProtobuf::boolean> = true; |
131 | template <> |
132 | constexpr inline bool IsProtobufScalarValueType<QString> = true; |
133 | template <> |
134 | constexpr inline bool IsProtobufScalarValueType<QByteArray> = true; |
135 | |
136 | template <typename T> |
137 | using is_protobuf_scalar_value_type = std::bool_constant<IsProtobufScalarValueType<T>>; |
138 | |
139 | template <typename T> |
140 | using is_protobuf_message = std::conjunction<std::negation<std::is_pointer<T>>, |
141 | std::is_base_of<QProtobufMessage, T>, |
142 | has_q_protobuf_object_macro<T>>; |
143 | |
144 | template <typename T> |
145 | using if_protobuf_message = std::enable_if_t<is_protobuf_message<T>::value, bool>; |
146 | |
147 | template <typename T> |
148 | using is_protobuf_non_message = std::disjunction<std::is_enum<T>, |
149 | QtProtobuf::is_protobuf_scalar_value_type<T>>; |
150 | |
151 | template <typename T> |
152 | using if_protobuf_non_message = std::enable_if_t<is_protobuf_non_message<T>::value, bool>; |
153 | |
154 | template <typename T> |
155 | using is_protobuf_type = std::disjunction<is_protobuf_message<T>, is_protobuf_non_message<T>>; |
156 | |
157 | template <typename T> |
158 | using if_protobuf_type = std::enable_if_t<is_protobuf_type<T>::value, bool>; |
159 | |
160 | template <typename T> |
161 | using is_protobuf_message_without_ordering = std::conjunction< |
162 | std::negation<std::is_pointer<T>>, std::is_base_of<QProtobufMessage, T>, |
163 | std::negation<has_q_protobuf_object_macro<T>>>; |
164 | |
165 | template <typename T> |
166 | using if_protobuf_message_without_ordering = std::enable_if_t< |
167 | is_protobuf_message_without_ordering<T>::value, bool>; |
168 | |
169 | template <typename T> |
170 | inline constexpr bool IsProtobufMapKeyType = false; |
171 | template <> |
172 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::int32> = true; |
173 | template <> |
174 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::int64> = true; |
175 | template <> |
176 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::sint32> = true; |
177 | template <> |
178 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::sint64> = true; |
179 | template <> |
180 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::uint32> = true; |
181 | template <> |
182 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::uint64> = true; |
183 | template <> |
184 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::fixed32> = true; |
185 | template <> |
186 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::fixed64> = true; |
187 | template <> |
188 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::sfixed32> = true; |
189 | template <> |
190 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::sfixed64> = true; |
191 | template <> |
192 | constexpr inline bool IsProtobufMapKeyType<QtProtobuf::boolean> = true; |
193 | template <> |
194 | constexpr inline bool IsProtobufMapKeyType<QString> = true; |
195 | |
196 | template <typename T> |
197 | using is_protobuf_map_key = std::bool_constant<IsProtobufMapKeyType<T>>; |
198 | |
199 | template <typename T> |
200 | using if_protobuf_map_key = std::enable_if_t<is_protobuf_map_key<T>::value, bool>; |
201 | |
202 | template <typename K, typename V> |
203 | using if_protobuf_map = std::enable_if_t<std::conjunction_v<QtProtobuf::is_protobuf_map_key<K>, |
204 | QtProtobuf::is_protobuf_type<V>>, bool>; |
205 | |
206 | } // namespace QtProtobuf |
207 | |
208 | QT_END_NAMESPACE |
209 | |
210 | Q_DECLARE_METATYPE(QtProtobuf::int32) |
211 | Q_DECLARE_METATYPE(QtProtobuf::int64) |
212 | Q_DECLARE_METATYPE(QtProtobuf::fixed32) |
213 | Q_DECLARE_METATYPE(QtProtobuf::fixed64) |
214 | Q_DECLARE_METATYPE(QtProtobuf::sfixed32) |
215 | Q_DECLARE_METATYPE(QtProtobuf::sfixed64) |
216 | |
217 | #endif // QTPROTOBUFTYPES_H |
218 | |