1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QPROTOBUFONEOF_H
5#define QPROTOBUFONEOF_H
6
7#if 0
8# pragma qt_class(QProtobufOneof)
9#endif
10
11#include <QtCore/QExplicitlySharedDataPointer>
12#include <QtCore/qmetaobject.h>
13#include <QtCore/qvariant.h>
14#include <QtProtobuf/qtprotobuftypes.h>
15#include <QtProtobuf/qprotobufmessage.h>
16
17#include <type_traits>
18
19QT_BEGIN_NAMESPACE
20
21class QAbstractProtobufSerializer;
22
23namespace QtProtobufPrivate {
24
25class QProtobufOneofPrivate;
26class Q_PROTOBUF_EXPORT QProtobufOneof final
27{
28 template<typename T>
29 using IsProtobufMessageType =
30 typename std::enable_if_t<!std::is_pointer_v<T>
31 && std::is_base_of_v<QProtobufMessage, T>
32 && HasProtobufPropertyOrdering<T>,
33 int>;
34
35 template<typename T>
36 using IsNonMessageProtobufType = typename std::enable_if_t<
37 std::disjunction_v<
38 std::is_same<T, QtProtobuf::int32>, std::is_same<T, QtProtobuf::int64>,
39 std::is_same<T, QtProtobuf::sint32>, std::is_same<T, QtProtobuf::sint64>,
40 std::is_same<T, QtProtobuf::uint32>, std::is_same<T, QtProtobuf::uint64>,
41 std::is_same<T, QtProtobuf::fixed32>, std::is_same<T, QtProtobuf::fixed64>,
42 std::is_same<T, QtProtobuf::sfixed32>, std::is_same<T, QtProtobuf::sfixed64>,
43 std::is_same<T, float>, std::is_same<T, double>,
44 std::is_same<T, QtProtobuf::boolean>, std::is_enum<T>,
45 std::is_same<T, QString>, std::is_same<T, QByteArray>>,
46 int>;
47
48public:
49 QProtobufOneof();
50 ~QProtobufOneof();
51 QProtobufOneof(const QProtobufOneof &other);
52 QProtobufOneof &operator=(const QProtobufOneof &other);
53 QProtobufOneof(QProtobufOneof &&other) noexcept : d_ptr(std::exchange(obj&: other.d_ptr, new_val: {})) { }
54 QProtobufOneof &operator=(QProtobufOneof &&other) noexcept
55 {
56 qt_ptr_swap(lhs&: d_ptr, rhs&: other.d_ptr);
57 return *this;
58 }
59
60 template<typename T>
61 void setValue(const T &value, int fieldNumber)
62 {
63 setValue(QVariant::fromValue<T>(value), fieldNumber);
64 }
65
66 template<typename T, IsNonMessageProtobufType<T> = 0>
67 T value() const
68 {
69 Q_ASSERT(QMetaType::fromType<T>() == rawValue().metaType());
70 return rawValue().value<T>();
71 }
72
73 template<typename T, IsProtobufMessageType<T> = 0>
74 T *value() const
75 {
76 Q_ASSERT(QMetaType::fromType<T>() == rawValue().metaType());
77 return reinterpret_cast<T *>(rawValue().data());
78 }
79
80 template<typename T, IsNonMessageProtobufType<T> = 0>
81 bool isEqual(const T &otherValue, int fieldNumber) const
82 {
83 return this->fieldNumber() == fieldNumber
84 && QMetaType::fromType<T>() == rawValue().metaType() && value<T>() == otherValue;
85 }
86
87 template<typename T, IsProtobufMessageType<T> = 0>
88 bool isEqual(const T &otherValue, int fieldNumber) const
89 {
90 return this->fieldNumber() == fieldNumber
91 && QMetaType::fromType<T>() == rawValue().metaType() && value<T>()
92 && *(value<T>()) == otherValue;
93 }
94
95 int fieldNumber() const;
96 bool holdsField(int fieldNumber) const;
97
98private:
99 friend bool operator==(const QProtobufOneof &lhs, const QProtobufOneof &rhs)
100 {
101 return lhs.isEqual(other: rhs);
102 }
103 friend bool operator!=(const QProtobufOneof &lhs, const QProtobufOneof &rhs)
104 {
105 return !lhs.isEqual(other: rhs);
106 }
107 bool isEqual(const QProtobufOneof &other) const;
108
109 friend class QT_PREPEND_NAMESPACE(QProtobufMessage);
110
111 void setValue(const QVariant &value, int fieldNumber);
112 QVariant &rawValue() const;
113
114 QProtobufOneofPrivate *d_ptr;
115 Q_DECLARE_PRIVATE(QProtobufOneof)
116};
117} // namespace QtProtobufPrivate
118
119QT_END_NAMESPACE
120
121Q_DECLARE_METATYPE(QtProtobufPrivate::QProtobufOneof)
122
123#endif // QPROTOBUFONEOF_H
124

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