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 | #include <QtProtobuf/qprotobufoneof.h> |
5 | |
6 | QT_BEGIN_NAMESPACE |
7 | |
8 | namespace QtProtobufPrivate { |
9 | /*! |
10 | \internal |
11 | \fn template<typename T, QtProtobuf::if_protobuf_type<T> = true> void QProtobufOneof::setValue(const T &value, int fieldNumber) |
12 | \fn template<typename T, QtProtobuf::if_protobuf_message<T> = true> void setValue(T &&value, int fieldNumber) |
13 | |
14 | Stores the \a value into QProtobufOneof with corresponding \a |
15 | fieldNumber. |
16 | */ |
17 | |
18 | /*! |
19 | \internal |
20 | \fn template <typename T, QtProtobuf::if_protobuf_non_message<T> = true> T QProtobufOneof::value() const |
21 | |
22 | Returns the value of non-message protobuf type stored in the |
23 | QProtobufOneof object. |
24 | */ |
25 | |
26 | /*! |
27 | \internal |
28 | \fn template <typename T, QtProtobuf::if_protobuf_message<T> = true> const T *value() const |
29 | |
30 | Returns the pointer to a protobuf message that is stored inside the |
31 | QProtobufOneof object. |
32 | */ |
33 | |
34 | /*! |
35 | \internal |
36 | \fn template <typename T, QtProtobuf::if_protobuf_message<T> = true> T *value() |
37 | |
38 | Returns the pointer to a protobuf message that is stored inside the |
39 | QProtobufOneof object. Mutable overload. |
40 | */ |
41 | |
42 | /*! |
43 | \internal |
44 | \fn template <typename T, QtProtobuf::if_protobuf_non_message<T> = true> bool isEqual(const T &otherValue, int fieldNumber) const |
45 | Compares the data stored in QProtobufOneof with the value/fieldNumber |
46 | pair. |
47 | */ |
48 | |
49 | /*! |
50 | \internal |
51 | \fn template <typename T, QtProtobuf::if_protobuf_message<T> = true> bool isEqual(const T &otherValue, int fieldNumber) const |
52 | Compares the data stored in QProtobufOneof with the value/fieldNumber |
53 | pair. |
54 | */ |
55 | |
56 | class QProtobufOneofPrivate final |
57 | { |
58 | public: |
59 | QVariant value; |
60 | int fieldNumber = QtProtobuf::InvalidFieldNumber; |
61 | }; |
62 | |
63 | /*! |
64 | \internal |
65 | \brief The default constructor, constructs uninitialized QProtobufOneof. |
66 | */ |
67 | QProtobufOneof::QProtobufOneof() : d_ptr(new QProtobufOneofPrivate) { } |
68 | |
69 | /*! |
70 | \internal |
71 | Constructs a copy of other. This operation takes constant time, because |
72 | QProtobufOneof is implicitly shared. If a shared instance is modified, it |
73 | will be copied (copy-on-write). |
74 | */ |
75 | QProtobufOneof::QProtobufOneof(const QProtobufOneof &other) |
76 | : d_ptr(new QProtobufOneofPrivate(*other.d_ptr)) |
77 | { |
78 | } |
79 | |
80 | /*! |
81 | \internal |
82 | Assigns other to this QProtobufOneof and returns a reference to this |
83 | QProtobufOneof. |
84 | */ |
85 | |
86 | QProtobufOneof &QProtobufOneof::operator=(const QProtobufOneof &other) |
87 | { |
88 | if (this != &other) |
89 | *d_ptr = *other.d_ptr; |
90 | return *this; |
91 | } |
92 | |
93 | /*! |
94 | \internal |
95 | \fn QProtobufOneof::QProtobufOneof(QProtobufOneof &&other) noexcept |
96 | Move-constructs a QProtobufOneof instance, making it point at the same |
97 | object that other was pointing to. |
98 | */ |
99 | |
100 | /*! |
101 | \internal |
102 | \fn QProtobufOneof &QProtobufOneof::operator=(QProtobufOneof &&other) noexcept |
103 | Move-assigns other to this QProtobufOneof instance. |
104 | */ |
105 | |
106 | /*! |
107 | \internal |
108 | Checks if values stored in oneof is equal \a other. |
109 | */ |
110 | bool comparesEqual(const QProtobufOneof &lhs, const QProtobufOneof &rhs) noexcept |
111 | { |
112 | if (lhs.d_ptr == rhs.d_ptr) |
113 | return true; |
114 | return lhs.d_func()->fieldNumber == rhs.d_func()->fieldNumber |
115 | && lhs.d_func()->value == rhs.d_func()->value; |
116 | } |
117 | |
118 | /*! |
119 | \internal |
120 | Destroys the oneof. |
121 | */ |
122 | QProtobufOneof::~QProtobufOneof() |
123 | { |
124 | delete d_ptr; |
125 | } |
126 | |
127 | const QVariant &QProtobufOneof::rawValue() const |
128 | { |
129 | return d_ptr->value; |
130 | } |
131 | |
132 | /* |
133 | Setting of the QProtobufOneof data makes sense only using |
134 | value/fieldNumber pair. Instead of non-constant dereferencing of the |
135 | QSharedDataPointer we simply rewrite it, that keep its copies untouched but |
136 | creates a new data with the provided values. This avoids redundant data |
137 | copying when updating the data. |
138 | */ |
139 | void QProtobufOneof::setValue(const QVariant &value, int fieldNumber) |
140 | { |
141 | d_ptr->value = value; |
142 | d_ptr->fieldNumber = fieldNumber; |
143 | } |
144 | |
145 | /*! |
146 | \internal |
147 | Returns \c true if QProtobufOneof holds the field with \a fieldNumber. |
148 | */ |
149 | bool QProtobufOneof::holdsField(int fieldNumber) const |
150 | { |
151 | Q_D(const QProtobufOneof); |
152 | return d->fieldNumber == fieldNumber && fieldNumber != QtProtobuf::InvalidFieldNumber |
153 | && !d->value.isNull(); |
154 | } |
155 | |
156 | /*! |
157 | \internal |
158 | Returns the number of a protobuf field that is stored in the object |
159 | */ |
160 | int QProtobufOneof::fieldNumber() const |
161 | { |
162 | Q_D(const QProtobufOneof); |
163 | return d->fieldNumber; |
164 | } |
165 | |
166 | /*! |
167 | \internal |
168 | Ensures that underlying QVariant holds the required QMetaType. Initializes variant with the |
169 | default-constructed QMetaType if QVariant holds the different type. |
170 | */ |
171 | void QProtobufOneof::ensureRawValue(QMetaType metaType) |
172 | { |
173 | Q_D(QProtobufOneof); |
174 | if (metaType != d->value.metaType()) |
175 | d->value = QVariant::fromMetaType(type: metaType); |
176 | } |
177 | } // namespace QtProtobufPrivate |
178 | |
179 | QT_END_NAMESPACE |
180 | |