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 <QtProtobuf/qprotobufmessage.h>
12#include <QtProtobuf/qtprotobuftypes.h>
13
14#include <QtCore/qmetatype.h>
15#include <QtCore/qtclasshelpermacros.h>
16#include <QtCore/qvariant.h>
17
18QT_BEGIN_NAMESPACE
19
20namespace QtProtobufPrivate {
21
22class QProtobufOneofPrivate;
23class QProtobufOneof final
24{
25 template <typename T>
26 using is_oneof_value_type = std::disjunction<
27 QtProtobuf::is_protobuf_message_without_ordering<T>,
28 QtProtobuf::is_protobuf_non_message<T>>;
29 template <typename T>
30 using if_oneof_value_type = std::enable_if_t<is_oneof_value_type<T>::value, bool>;
31
32 template <typename T>
33 using is_oneof_compatible = std::disjunction<QtProtobuf::is_protobuf_message<T>,
34 is_oneof_value_type<T>>;
35 template <typename T>
36 using if_oneof_compatible = std::enable_if_t<is_oneof_compatible<T>::value, bool>;
37
38public:
39 Q_PROTOBUF_EXPORT QProtobufOneof();
40 Q_PROTOBUF_EXPORT ~QProtobufOneof();
41 Q_PROTOBUF_EXPORT QProtobufOneof(const QProtobufOneof &other);
42 Q_PROTOBUF_EXPORT QProtobufOneof &operator=(const QProtobufOneof &other);
43 QProtobufOneof(QProtobufOneof &&other) noexcept : d_ptr(std::exchange(obj&: other.d_ptr, new_val: {})) { }
44 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QProtobufOneof)
45 void swap(QProtobufOneof &other) noexcept
46 {
47 qt_ptr_swap(lhs&: d_ptr, rhs&: other.d_ptr);
48 }
49
50 template <typename T, if_oneof_compatible<T> = true>
51 void setValue(const T &value, int fieldNumber)
52 {
53 setValue(QVariant::fromValue<T>(value), fieldNumber);
54 }
55
56 template<typename T, QtProtobuf::if_protobuf_message<T> = true>
57 void setValue(T &&value, int fieldNumber)
58 {
59 setValue(QVariant::fromValue<T>(std::forward<T>(value)), fieldNumber);
60 }
61
62 template <typename T, if_oneof_value_type<T> = true>
63 T value() const
64 {
65 ensureMetaType(lhs: QMetaType::fromType<T>(), rhs: rawValue().metaType());
66 return rawValue().value<T>();
67 }
68
69 template <typename T, QtProtobuf::if_protobuf_message<T> = true>
70 T *message()
71 {
72 ensureRawValue(metaType: QMetaType::fromType<T>());
73 return static_cast<T *>(rawValue().data());
74 }
75
76 template <typename T, QtProtobuf::if_protobuf_message<T> = true>
77 const T *message() const
78 {
79 ensureMetaType(lhs: QMetaType::fromType<T>(), rhs: rawValue().metaType());
80 return static_cast<const T *>(rawValue().data());
81 }
82
83 template <typename T, if_oneof_value_type<T> = true>
84 bool isEqual(const T &otherValue, int fieldNumber) const
85 {
86 return this->fieldNumber() == fieldNumber
87 && QMetaType::fromType<T>() == rawValue().metaType() && value<T>() == otherValue;
88 }
89
90 template <typename T, QtProtobuf::if_protobuf_message<T> = true>
91 bool isEqual(const T &otherValue, int fieldNumber) const
92 {
93 if (this->fieldNumber() != fieldNumber
94 || QMetaType::fromType<T>() != rawValue().metaType()) {
95 return false;
96 }
97
98 const auto *messagePtr = message<T>();
99 return messagePtr && *messagePtr == otherValue;
100 }
101
102 Q_PROTOBUF_EXPORT int fieldNumber() const;
103 Q_PROTOBUF_EXPORT bool holdsField(int fieldNumber) const;
104
105private:
106 Q_ALWAYS_INLINE static void ensureMetaType(QMetaType lhs, QMetaType rhs)
107 {
108 Q_ASSERT(lhs == rhs);
109 }
110
111 Q_PROTOBUF_EXPORT void ensureRawValue(QMetaType metaType);
112
113 friend Q_PROTOBUF_EXPORT bool comparesEqual(const QProtobufOneof &lhs,
114 const QProtobufOneof &rhs) noexcept;
115 Q_DECLARE_EQUALITY_COMPARABLE(QProtobufOneof)
116
117 friend class QT_PREPEND_NAMESPACE(QProtobufMessage);
118
119 Q_PROTOBUF_EXPORT void setValue(const QVariant &value, int fieldNumber);
120 Q_PROTOBUF_EXPORT const QVariant &rawValue() const;
121 QVariant &rawValue()
122 {
123 return const_cast<QVariant &>(std::as_const(t&: *this).rawValue());
124 }
125
126 QProtobufOneofPrivate *d_ptr;
127 Q_DECLARE_PRIVATE(QProtobufOneof)
128};
129} // namespace QtProtobufPrivate
130
131QT_END_NAMESPACE
132
133#endif // QPROTOBUFONEOF_H
134

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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