Realm C++ SDK Version v2.2.0

types.hpp

1
2//
3// Copyright 2022 Realm Inc.
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16//
18
19#ifndef CPPREALM_TYPES_HPP
20#define CPPREALM_TYPES_HPP
21
22#include <array>
23#include <optional>
24#include <set>
25#include <stdexcept>
26
27#include <cpprealm/internal/bridge/realm.hpp>
28#include <cpprealm/internal/bridge/schema.hpp>
29#include <cpprealm/internal/type_info.hpp>
30
31namespace realm {
32
33 const size_t not_in_collection = -1;
34
35 struct uuid {
36 explicit uuid(const std::string &);
37 uuid(const std::array<uint8_t, 16>&);
38 uuid() = default;
39 [[nodiscard]] std::string to_string() const;
40 [[nodiscard]] std::string to_base64() const;
41 [[nodiscard]] std::array<uint8_t, 16> to_bytes() const;
44 friend struct internal::bridge::uuid;
45 template <typename mapped_type>
46 friend struct box_base;
47 };
48
49 inline bool operator ==(const uuid& lhs, const uuid& rhs) { return lhs.m_uuid == rhs.m_uuid; }
50 inline bool operator !=(const uuid& lhs, const uuid& rhs) { return lhs.m_uuid != rhs.m_uuid; }
51 inline bool operator >(const uuid& lhs, const uuid& rhs) { return lhs.m_uuid > rhs.m_uuid; }
52 inline bool operator >=(const uuid& lhs, const uuid& rhs) { return lhs.m_uuid >= rhs.m_uuid; }
53 inline bool operator <(const uuid& lhs, const uuid& rhs) { return lhs.m_uuid < rhs.m_uuid; }
54 inline bool operator <=(const uuid& lhs, const uuid& rhs) { return lhs.m_uuid <= rhs.m_uuid; }
55
56 struct object_id {
57 explicit object_id(const std::string &);
58 object_id() = default;
59 [[nodiscard]] static object_id generate();
60 [[nodiscard]] std::string to_string() const;
63 friend struct internal::bridge::object_id;
64 template <typename mapped_type>
65 friend struct box_base;
66 };
67
68 inline bool operator ==(const object_id& lhs, const object_id& rhs) { return lhs.m_object_id == rhs.m_object_id; }
69 inline bool operator !=(const object_id& lhs, const object_id& rhs) { return lhs.m_object_id != rhs.m_object_id; }
70 inline bool operator <(const object_id& lhs, const object_id& rhs) { return lhs.m_object_id < rhs.m_object_id; }
71 inline bool operator >(const object_id& lhs, const object_id& rhs) { return lhs.m_object_id > rhs.m_object_id; }
72 inline bool operator <=(const object_id& lhs, const object_id& rhs) { return lhs.m_object_id <= rhs.m_object_id; }
73 inline bool operator >=(const object_id& lhs, const object_id& rhs) { return lhs.m_object_id >= rhs.m_object_id; }
74
75 struct decimal128 {
76 explicit decimal128(const std::string &);
77 decimal128(const double &);
78 decimal128() = default;
79 [[nodiscard]] std::string to_string() const;
80 [[nodiscard]] bool is_NaN() const;
83 friend struct internal::bridge::decimal128;
84 template <typename mapped_type>
85 friend struct box_base;
86
87 decimal128 operator-(const decimal128& o);
88 decimal128 operator+(const decimal128& o);
89 decimal128 operator*(const decimal128& o);
90 decimal128 operator/(const decimal128& o);
91
92 decimal128& operator-=(const decimal128& o);
93 decimal128& operator+=(const decimal128& o);
94 decimal128& operator*=(const decimal128& o);
95 decimal128& operator/=(const decimal128& o);
96 };
97
98 inline bool operator >(const decimal128& lhs, const decimal128& rhs) { return lhs.m_decimal > rhs.m_decimal; }
99 inline bool operator >=(const decimal128& lhs, const decimal128& rhs) { return lhs.m_decimal >= rhs.m_decimal; }
100 inline bool operator <(const decimal128& lhs, const decimal128& rhs) { return lhs.m_decimal < rhs.m_decimal; }
101 inline bool operator <=(const decimal128& lhs, const decimal128& rhs) { return lhs.m_decimal <= rhs.m_decimal; }
102 inline bool operator ==(const decimal128& lhs, const decimal128& rhs) { return lhs.m_decimal == rhs.m_decimal; }
103 inline bool operator !=(const decimal128& lhs, const decimal128& rhs) { return lhs.m_decimal != rhs.m_decimal; }
104}
105
106namespace realm {
107
108 static inline int64_t serialize(int64_t v, const std::optional<internal::bridge::realm>& = std::nullopt) {
109 return v;
110 }
111 static inline int64_t deserialize(int64_t v) {
112 return v;
113 }
114
115 static inline std::optional<int64_t> serialize(const std::optional<int64_t>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
116 return v;
117 }
118 static inline std::optional<int64_t> deserialize(const std::optional<int64_t>& v) {
119 return v;
120 }
121
122 static inline double serialize(const double& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
123 return v;
124 }
125 static inline double deserialize(const double& v) {
126 return v;
127 }
128
129 static inline std::optional<double> serialize(const std::optional<double>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
130 return v;
131 }
132 static inline std::optional<double> deserialize(const std::optional<double>& v) {
133 return v;
134 }
135
136 static inline bool serialize(bool v, const std::optional<internal::bridge::realm>& = std::nullopt) {
137 return v;
138 }
139 static inline bool deserialize(bool v) {
140 return v;
141 }
142
143 static inline std::optional<bool> serialize(std::optional<bool> v, const std::optional<internal::bridge::realm>& = std::nullopt) {
144 return v;
145 }
146 static inline std::optional<bool> deserialize(std::optional<bool> v) {
147 return v;
148 }
149
150 template<typename T>
151 static inline typename std::enable_if_t<std::is_enum_v<T>, int64_t> serialize(const T& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
152 return static_cast<int64_t>(v);
153 }
154 template<typename T, std::enable_if_t<std::is_enum_v<T>>>
155 static inline T deserialize(int64_t v) {
156 return static_cast<T>(v);
157 }
158
159 template<typename T>
160 static inline std::enable_if_t<std::is_enum_v<typename T::value_type>, std::optional<int64_t>> serialize(const T& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
161 if (v) {
162 return static_cast<int64_t>(*v);
163 } else {
164 return std::nullopt;
165 }
166 }
167 template<typename T, std::enable_if_t<std::is_enum_v<typename T::value_type>>>
168 static inline std::optional<int64_t> deserialize(std::optional<int64_t> v) {
169 if (v) {
170 return static_cast<T>(*v);
171 } else {
172 return std::nullopt;
173 }
174 }
175
176 static inline std::string serialize(const std::string& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
177 return v;
178 }
179 static inline std::string deserialize(const std::string& v) {
180 return v;
181 }
182
183 static inline std::optional<std::string> serialize(const std::optional<std::string>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
184 return v;
185 }
186 static inline std::optional<std::string> deserialize(const std::optional<std::string>& v) {
187 return v;
188 }
189
190 static inline internal::bridge::uuid serialize(const uuid& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
191 return v;
192 }
193 static inline uuid deserialize(const internal::bridge::uuid& v) {
194 return v.operator ::realm::uuid();
195 }
196
197 static inline std::optional<internal::bridge::uuid> serialize(const std::optional<uuid>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
198 return v;
199 }
200 static inline std::optional<uuid> deserialize(const std::optional<internal::bridge::uuid>& v) {
201 if (v) {
202 return v->operator ::realm::uuid();
203 } else {
204 return std::nullopt;
205 }
206 }
207
208 static inline internal::bridge::binary serialize(const std::vector<uint8_t>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
209 return v;
210 }
211 static inline std::vector<uint8_t> deserialize(const internal::bridge::binary& v) {
212 return v.operator std::vector<uint8_t>();
213 }
214
215 static inline std::optional<internal::bridge::binary> serialize(const std::optional<std::vector<uint8_t>>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
216 return v;
217 }
218 static inline std::optional<std::vector<uint8_t>> deserialize(const std::optional<internal::bridge::binary>& v) {
219 if (v) {
220 return v->operator std::vector<uint8_t>();
221 } else {
222 return std::nullopt;
223 }
224 }
225
226 static inline internal::bridge::timestamp serialize(const std::chrono::time_point<std::chrono::system_clock>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
227 return v;
228 }
229 static inline std::chrono::time_point<std::chrono::system_clock> deserialize(const internal::bridge::timestamp& v) {
230 return v.operator std::chrono::time_point<std::chrono::system_clock>();
231 }
232
233 static inline std::optional<internal::bridge::timestamp> serialize(const std::optional<std::chrono::time_point<std::chrono::system_clock>>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
234 return v;
235 }
236 static inline std::optional<std::chrono::time_point<std::chrono::system_clock>> deserialize(const std::optional<internal::bridge::timestamp>& v) {
237 if (v) {
238 return v->operator std::chrono::time_point<std::chrono::system_clock>();
239 } else {
240 return std::nullopt;
241 }
242 }
243
244 static inline internal::bridge::object_id serialize(const realm::object_id& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
245 return v;
246 }
247 static inline realm::object_id deserialize(const internal::bridge::object_id& v) {
248 return v.operator ::realm::object_id();
249 }
250
251 static inline std::optional<internal::bridge::object_id> serialize(const std::optional<realm::object_id>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
252 return v;
253 }
254 static inline std::optional<realm::object_id> deserialize(const std::optional<internal::bridge::object_id>& v) {
255 if (v) {
256 return v->operator ::realm::object_id();
257 } else {
258 return std::nullopt;
259 }
260 }
261
262 static inline internal::bridge::decimal128 serialize(const realm::decimal128& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
263 return v;
264 }
265 static inline realm::decimal128 deserialize(const internal::bridge::decimal128& v) {
266 return v.operator ::realm::decimal128();
267 }
268
269 static inline std::optional<internal::bridge::decimal128> serialize(const std::optional<realm::decimal128>& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
270 return v;
271 }
272 static inline std::optional<realm::decimal128> deserialize(const std::optional<internal::bridge::decimal128>& v) {
273 if (v) {
274 return v->operator ::realm::decimal128();
275 } else {
276 return std::nullopt;
277 }
278 }
279
280 template <typename T>
281 static inline typename std::enable_if_t<internal::type_info::MixedPersistableConcept<T>::value, internal::bridge::mixed> serialize(const T& v, const std::optional<internal::bridge::realm>& = std::nullopt) {
282 return std::visit([&](auto&& arg) {
283 using StoredType = std::decay_t<decltype(arg)>;
284 using M = typename internal::type_info::type_info<StoredType>::internal_type;
285 return internal::bridge::mixed(M(arg));
286 }, v);
287 }
288
289 template <typename T>
290 static inline typename std::enable_if_t<!internal::type_info::MixedPersistableConcept<T>::value, T>
291 deserialize(const internal::bridge::mixed& value) {
292 if constexpr (internal::type_info::is_optional<T>::value) {
293 return std::nullopt;
294 } else if constexpr (std::is_same_v<T, int64_t>) {
295 return value.operator int64_t();
296 } else if constexpr (std::is_same_v<T, bool>) {
297 return value.operator bool();
298 } else if constexpr (std::is_same_v<T, std::string>) {
299 return static_cast<std::string>(value);
300 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
301 return static_cast<std::vector<uint8_t>>(static_cast<internal::bridge::binary>(value));
302 } else if constexpr (std::is_same_v<T, std::chrono::time_point<std::chrono::system_clock>>) {
303 return static_cast<internal::bridge::timestamp>(value);
304 } else if constexpr (std::disjunction_v<std::is_same<T, double>, std::is_same<T, float>>) {
305 return static_cast<double>(value);
306 } else if constexpr (std::is_same_v<T, realm::uuid>) {
307 return value.operator internal::bridge::uuid().operator ::realm::uuid();
308 } else if constexpr (std::is_same_v<T, realm::object_id>) {
309 return value.operator internal::bridge::object_id().operator ::realm::object_id();
310 } else if constexpr (std::is_same_v<T, realm::decimal128>) {
311 return value.operator internal::bridge::decimal128() .operator ::realm::decimal128();
312 } else if constexpr (std::is_enum_v<T>) {
313 return static_cast<T>(value.operator int64_t());
314 } else {
315 abort();
316 }
317 }
318
319 template <typename T>
320 static inline typename std::enable_if_t<internal::type_info::MixedPersistableConcept<T>::value, T>
321 deserialize(const internal::bridge::mixed& value) {
322 if (value.is_null()) {
323 return std::monostate();
324 }
325
326 switch (value.type()) {
327 case internal::bridge::data_type::Int:
328 return value.operator int64_t();
329 case internal::bridge::data_type::Bool:
330 return value.operator bool();
331 case internal::bridge::data_type::String:
332 return static_cast<std::string>(value);
333 case internal::bridge::data_type::Binary:
334 return static_cast<std::vector<uint8_t>>(static_cast<internal::bridge::binary>(value));
335 case internal::bridge::data_type::Timestamp:
336 return static_cast<internal::bridge::timestamp>(value);
337 case internal::bridge::data_type::Float:
338 case internal::bridge::data_type::Double:
339 return static_cast<double>(value);
340 case internal::bridge::data_type::UUID:
341 return value.operator internal::bridge::uuid().operator ::realm::uuid();
342 case internal::bridge::data_type::ObjectId:
343 return value.operator internal::bridge::object_id().operator ::realm::object_id();
344 case internal::bridge::data_type::Decimal:
345 return value.operator internal::bridge::decimal128().operator ::realm::decimal128();
346 case internal::bridge::data_type::TypedLink:
347 throw std::runtime_error("Objects stored in mixed properties must be accessed via `get_object_value()`");
348 default:
349 throw std::runtime_error("Unknown datatype while deserializing mixed property.");
350 }
351 }
352
353} // namespace realm
354
355
356#endif//CPPREALM_TYPES_HPP
Definition: managed_dictionary.hpp:31
Definition: types.hpp:75
Definition: decimal128.hpp:30
Definition: object_id.hpp:31
Definition: uuid.hpp:32
Definition: types.hpp:56
Definition: types.hpp:35