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
19QT_BEGIN_NAMESPACE
20
21namespace QtProtobuf {
22Q_NAMESPACE_EXPORT(Q_PROTOBUF_EXPORT)
23
24[[maybe_unused]] constexpr int InvalidFieldNumber = 0;
25
26enum 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};
36Q_ENUM_NS(WireTypes)
37
38// The 'tag' template param exists only create a unique type
39template<typename T, typename tag>
40struct 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
57private:
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
69using int32 = TransparentWrapper<int32_t, struct int_tag>;
70using int64 = TransparentWrapper<int64_t, struct int_tag>;
71using uint32 = uint32_t;
72using uint64 = uint64_t;
73using sint32 = int32_t;
74using sint64 = int64_t;
75using fixed32 = TransparentWrapper<uint32_t, struct fixed_tag>;
76using fixed64 = TransparentWrapper<uint64_t, struct fixed_tag>;
77using sfixed32 = TransparentWrapper<int32_t, struct fixed_tag>;
78using sfixed64 = TransparentWrapper<int64_t, struct fixed_tag>;
79using boolean = bool;
80using int32List = QList<int32>;
81using int64List = QList<int64>;
82using uint32List = QList<uint32>;
83using uint64List = QList<uint64>;
84using sint32List = QList<sint32>;
85using sint64List = QList<sint64>;
86using fixed32List = QList<fixed32>;
87using fixed64List = QList<fixed64>;
88using sfixed32List = QList<sfixed32>;
89using sfixed64List = QList<sfixed64>;
90using floatList = QList<float>;
91using doubleList = QList<double>;
92using boolList = QList<bool>;
93
94template<typename T>
95using HasProtobufStaticPropertyOrdering = decltype(T::staticPropertyOrdering);
96
97template <typename T>
98using has_q_protobuf_object_macro = qxp::is_detected<HasProtobufStaticPropertyOrdering, T>;
99
100template <typename T>
101constexpr bool has_q_protobuf_object_macro_v = has_q_protobuf_object_macro<T>::value;
102
103template <typename T>
104inline constexpr bool IsProtobufScalarValueType = false;
105template <>
106constexpr inline bool IsProtobufScalarValueType<QtProtobuf::int32> = true;
107template <>
108constexpr inline bool IsProtobufScalarValueType<QtProtobuf::int64> = true;
109template <>
110constexpr inline bool IsProtobufScalarValueType<QtProtobuf::sint32> = true;
111template <>
112constexpr inline bool IsProtobufScalarValueType<QtProtobuf::sint64> = true;
113template <>
114constexpr inline bool IsProtobufScalarValueType<QtProtobuf::uint32> = true;
115template <>
116constexpr inline bool IsProtobufScalarValueType<QtProtobuf::uint64> = true;
117template <>
118constexpr inline bool IsProtobufScalarValueType<QtProtobuf::fixed32> = true;
119template <>
120constexpr inline bool IsProtobufScalarValueType<QtProtobuf::fixed64> = true;
121template <>
122constexpr inline bool IsProtobufScalarValueType<QtProtobuf::sfixed32> = true;
123template <>
124constexpr inline bool IsProtobufScalarValueType<QtProtobuf::sfixed64> = true;
125template <>
126constexpr inline bool IsProtobufScalarValueType<float> = true;
127template <>
128constexpr inline bool IsProtobufScalarValueType<double> = true;
129template <>
130constexpr inline bool IsProtobufScalarValueType<QtProtobuf::boolean> = true;
131template <>
132constexpr inline bool IsProtobufScalarValueType<QString> = true;
133template <>
134constexpr inline bool IsProtobufScalarValueType<QByteArray> = true;
135
136template <typename T>
137using is_protobuf_scalar_value_type = std::bool_constant<IsProtobufScalarValueType<T>>;
138
139template <typename T>
140using 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
144template <typename T>
145using if_protobuf_message = std::enable_if_t<is_protobuf_message<T>::value, bool>;
146
147template <typename T>
148using is_protobuf_non_message = std::disjunction<std::is_enum<T>,
149 QtProtobuf::is_protobuf_scalar_value_type<T>>;
150
151template <typename T>
152using if_protobuf_non_message = std::enable_if_t<is_protobuf_non_message<T>::value, bool>;
153
154template <typename T>
155using is_protobuf_type = std::disjunction<is_protobuf_message<T>, is_protobuf_non_message<T>>;
156
157template <typename T>
158using if_protobuf_type = std::enable_if_t<is_protobuf_type<T>::value, bool>;
159
160template <typename T>
161using 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
165template <typename T>
166using if_protobuf_message_without_ordering = std::enable_if_t<
167 is_protobuf_message_without_ordering<T>::value, bool>;
168
169template <typename T>
170inline constexpr bool IsProtobufMapKeyType = false;
171template <>
172constexpr inline bool IsProtobufMapKeyType<QtProtobuf::int32> = true;
173template <>
174constexpr inline bool IsProtobufMapKeyType<QtProtobuf::int64> = true;
175template <>
176constexpr inline bool IsProtobufMapKeyType<QtProtobuf::sint32> = true;
177template <>
178constexpr inline bool IsProtobufMapKeyType<QtProtobuf::sint64> = true;
179template <>
180constexpr inline bool IsProtobufMapKeyType<QtProtobuf::uint32> = true;
181template <>
182constexpr inline bool IsProtobufMapKeyType<QtProtobuf::uint64> = true;
183template <>
184constexpr inline bool IsProtobufMapKeyType<QtProtobuf::fixed32> = true;
185template <>
186constexpr inline bool IsProtobufMapKeyType<QtProtobuf::fixed64> = true;
187template <>
188constexpr inline bool IsProtobufMapKeyType<QtProtobuf::sfixed32> = true;
189template <>
190constexpr inline bool IsProtobufMapKeyType<QtProtobuf::sfixed64> = true;
191template <>
192constexpr inline bool IsProtobufMapKeyType<QtProtobuf::boolean> = true;
193template <>
194constexpr inline bool IsProtobufMapKeyType<QString> = true;
195
196template <typename T>
197using is_protobuf_map_key = std::bool_constant<IsProtobufMapKeyType<T>>;
198
199template <typename T>
200using if_protobuf_map_key = std::enable_if_t<is_protobuf_map_key<T>::value, bool>;
201
202template <typename K, typename V>
203using 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
208QT_END_NAMESPACE
209
210Q_DECLARE_METATYPE(QtProtobuf::int32)
211Q_DECLARE_METATYPE(QtProtobuf::int64)
212Q_DECLARE_METATYPE(QtProtobuf::fixed32)
213Q_DECLARE_METATYPE(QtProtobuf::fixed64)
214Q_DECLARE_METATYPE(QtProtobuf::sfixed32)
215Q_DECLARE_METATYPE(QtProtobuf::sfixed64)
216
217#endif // QTPROTOBUFTYPES_H
218

source code of qtgrpc/src/protobuf/qtprotobuftypes.h