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 | |
19 | QT_BEGIN_NAMESPACE |
20 | |
21 | class QAbstractProtobufSerializer; |
22 | |
23 | namespace QtProtobufPrivate { |
24 | |
25 | class QProtobufOneofPrivate; |
26 | class 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 | |
48 | public: |
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 | |
98 | private: |
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 | |
119 | QT_END_NAMESPACE |
120 | |
121 | Q_DECLARE_METATYPE(QtProtobufPrivate::QProtobufOneof) |
122 | |
123 | #endif // QPROTOBUFONEOF_H |
124 | |