Realm C++ SDK Version v2.2.0

managed_numeric.hpp

1
2//
3// Copyright 2024 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_MANAGED_NUMERIC_HPP
20#define CPPREALM_MANAGED_NUMERIC_HPP
21
22#include <cpprealm/macros.hpp>
23#include <cpprealm/rbool.hpp>
24
25namespace realm {
26 template<>
27 struct managed<int64_t> : managed_base {
28 using managed<int64_t>::managed_base::operator=;
29
30 managed_base& operator =(const int64_t& v) {
31 this->m_obj->template set<int64_t>(m_key, v);
32 return *this;
33 }
34
35 [[nodiscard]] int64_t detach() const {
36 return m_obj->template get<int64_t>(m_key);
37 }
38
39 [[nodiscard]] int64_t operator *() const {
40 return detach();
41 }
42
43 [[nodiscard]] operator int64_t() const {
44 return detach();
45 }
46
47 template<typename T>
48 std::enable_if_t<std::is_integral_v<T>, rbool> operator==(const T& rhs) const noexcept {
49 if (this->m_rbool_query) {
50 return this->m_rbool_query->equal(m_key, (int64_t)rhs);
51 }
52 return serialize(detach()) == rhs;
53 }
54
55 template<typename T>
56 std::enable_if_t<std::is_integral_v<T>, rbool> operator!=(const T& rhs) const noexcept {
57 if (this->m_rbool_query) {
58 return this->m_rbool_query->not_equal(m_key, (int64_t)rhs);
59 }
60 return serialize(detach()) != rhs;
61 }
62
63 template<typename T>
64 std::enable_if_t<std::is_integral_v<T>, rbool> operator>(const T& rhs) const noexcept {
65 if (this->m_rbool_query) {
66 return this->m_rbool_query->greater(m_key, (int64_t)rhs);
67 }
68 return serialize(detach()) > rhs;
69 }
70
71 template<typename T>
72 std::enable_if_t<std::is_integral_v<T>, rbool> operator<(const T& rhs) const noexcept {
73 if (this->m_rbool_query) {
74 return this->m_rbool_query->less(m_key, (int64_t)rhs);
75 }
76 return serialize(detach()) < rhs;
77 }
78
79 template<typename T>
80 std::enable_if_t<std::is_integral_v<T>, rbool> operator>=(const T& rhs) const noexcept {
81 if (this->m_rbool_query) {
82 return this->m_rbool_query->greater_equal(m_key, (int64_t)rhs);
83 }
84 return serialize(detach()) >= rhs;
85 }
86
87 template<typename T>
88 std::enable_if_t<std::is_integral_v<T>, rbool> operator<=(const T& rhs) const noexcept {
89 if (this->m_rbool_query) {
90 return this->m_rbool_query->less_equal(m_key, (int64_t)rhs);
91 }
92 return serialize(detach()) <= rhs;
93 }
94
95 managed& operator+=(const int64_t& o) {
96 auto old_val = m_obj->template get<int64_t>(m_key);
97 m_obj->template set<int64_t>(this->m_key, old_val + o);
98 return *this;
99 }
100 void operator++(int) {
101 auto old_val = m_obj->template get<int64_t>(m_key);
102 m_obj->template set<int64_t>(this->m_key, old_val + 1);
103 }
104 void operator++() {
105 auto old_val = m_obj->template get<int64_t>(m_key);
106 m_obj->template set<int64_t>(this->m_key, old_val + 1);
107 }
108 managed& operator-=(const int64_t& o) {
109 auto old_val = m_obj->template get<int64_t>(m_key);
110 m_obj->template set<int64_t>(this->m_key, old_val - o);
111 return *this;
112 }
113 void operator--(int) {
114 auto old_val = m_obj->template get<int64_t>(m_key);
115 m_obj->template set<int64_t>(this->m_key, old_val - 1);
116 }
117 void operator--() {
118 auto old_val = m_obj->template get<int64_t>(m_key);
119 m_obj->template set<int64_t>(this->m_key, old_val - 1);
120 }
121 managed& operator*=(const int64_t& o) {
122 auto old_val = m_obj->template get<int64_t>(m_key);
123 m_obj->template set<int64_t>(this->m_key, old_val * o);
124 return *this;
125 }
126
127 private:
128 managed() = default;
129 managed(const managed&) = delete;
130 managed(managed &&) = delete;
131 managed& operator=(const managed&) = delete;
132 managed& operator=(managed&&) = delete;
133 template<typename, typename>
134 friend struct managed;
135 };
136
137 template<>
138 struct managed<double> : managed_base {
139 using managed<double>::managed_base::operator=;
140
141 managed_base& operator =(const double& v) {
142 this->m_obj->template set<double>(m_key, v);
143 return *this;
144 }
145
146 managed_base& operator =(const int& v) {
147 this->m_obj->template set<double>(m_key, (double)v);
148 return *this;
149 }
150
151 [[nodiscard]] double detach() const {
152 return m_obj->template get<double>(m_key);
153 }
154
155 double operator *() const {
156 return detach();
157 }
158 [[nodiscard]] operator double() const {
159 return detach();
160 }
161
162 template<typename T>
163 std::enable_if_t< std::disjunction_v<std::is_integral<T>, std::is_floating_point<T>>, rbool> operator==(const T& rhs) const noexcept {
164 if (this->m_rbool_query) {
165 return this->m_rbool_query->equal(m_key, (double)rhs);
166 }
167 return serialize(detach()) == rhs;
168 }
169
170 template<typename T>
171 std::enable_if_t< std::disjunction_v<std::is_integral<T>, std::is_floating_point<T>>, rbool> operator!=(const T& rhs) const noexcept {
172 if (this->m_rbool_query) {
173 return this->m_rbool_query->not_equal(m_key, (double)rhs);
174 }
175 return serialize(detach()) != rhs;
176 }
177
178 template<typename T>
179 std::enable_if_t< std::disjunction_v<std::is_integral<T>, std::is_floating_point<T>>, rbool> operator>(const T& rhs) const noexcept {
180 if (this->m_rbool_query) {
181 return this->m_rbool_query->greater(m_key, (double)rhs);
182 }
183 return serialize(detach()) > rhs;
184 }
185
186 template<typename T>
187 std::enable_if_t< std::disjunction_v<std::is_integral<T>, std::is_floating_point<T>>, rbool> operator<(const T& rhs) const noexcept {
188 if (this->m_rbool_query) {
189 return this->m_rbool_query->less(m_key, (double)rhs);
190 }
191 return serialize(detach()) < rhs;
192 }
193
194 template<typename T>
195 std::enable_if_t< std::disjunction_v<std::is_integral<T>, std::is_floating_point<T>>, rbool> operator>=(const T& rhs) const noexcept {
196 if (this->m_rbool_query) {
197 return this->m_rbool_query->greater_equal(m_key, (double)rhs);
198 }
199 return serialize(detach()) >= rhs;
200 }
201
202 template<typename T>
203 std::enable_if_t< std::disjunction_v<std::is_integral<T>, std::is_floating_point<T>>, rbool> operator<=(const T& rhs) const noexcept {
204 if (this->m_rbool_query) {
205 return this->m_rbool_query->less_equal(m_key, (double)rhs);
206 }
207 return serialize(detach()) <= rhs;
208 }
209
210 void operator+=(const double& o) {
211 auto old_val = m_obj->template get<double>(m_key);
212 m_obj->template set<double>(this->m_key, old_val + o);
213 }
214 void operator++(int) {
215 auto old_val = m_obj->template get<double>(m_key);
216 m_obj->template set<double>(this->m_key, old_val + 1.0);
217 }
218 void operator++() {
219 auto old_val = m_obj->template get<double>(m_key);
220 m_obj->template set<double>(this->m_key, old_val + 1.0);
221 }
222 void operator-=(const double& o) {
223 auto old_val = m_obj->template get<double>(m_key);
224 m_obj->template set<double>(this->m_key, old_val - o);
225 }
226 void operator--(int) {
227 auto old_val = m_obj->template get<double>(m_key);
228 m_obj->template set<double>(this->m_key, old_val - 1.0);
229 }
230 void operator--() {
231 auto old_val = m_obj->template get<double>(m_key);
232 m_obj->template set<double>(this->m_key, old_val - 1.0);
233 }
234 void operator*=(const double& o) {
235 auto old_val = m_obj->template get<double>(m_key);
236 m_obj->template set<double>(this->m_key, old_val * o);
237 }
238
239 private:
240 managed() = default;
241 managed(const managed&) = delete;
242 managed(managed &&) = delete;
243 managed& operator=(const managed&) = delete;
244 managed& operator=(managed&&) = delete;
245 template<typename, typename>
246 friend struct managed;
247 };
248
249 template<>
250 struct managed<bool> : managed_base {
251 using managed<bool>::managed_base::operator=;
252
253 [[nodiscard]] bool detach() const {
254 return m_obj->template get<bool>(m_key);
255 }
256 [[nodiscard]] operator bool() const {
257 return detach();
258 }
259 bool operator *() const {
260 return detach();
261 }
262
263 rbool operator==(const bool& rhs) const noexcept;
264 rbool operator!=(const bool& rhs) const noexcept;
265
266 private:
267 managed() = default;
268 managed(const managed&) = delete;
269 managed(managed &&) = delete;
270 managed& operator=(const managed&) = delete;
271 managed& operator=(managed&&) = delete;
272 template<typename, typename>
273 friend struct managed;
274 };
275
276#define CPP_REALM_MANAGED_OPTIONAL_NUMERIC(type) \
277 template<> \
278 struct managed<std::optional<type>> : managed_base { \
279 using managed<std::optional<type>>::managed_base::operator=; \
280 \
281 managed<std::optional<type>>& operator =(const double& v) { \
282 this->m_obj->template set<type>(m_key, v); \
283 return *this; \
284 } \
285 \
286 managed<std::optional<type>>& operator =(const int& v) { \
287 this->m_obj->template set<type>(m_key, (double)v); \
288 return *this; \
289 } \
290 \
291 [[nodiscard]] std::optional<type> detach() const { \
292 return m_obj->get_optional<type>(m_key); \
293 } \
294\
295 [[nodiscard]] std::optional<type> operator *() const { \
296 return detach(); \
297 } \
298 [[nodiscard]] operator std::optional<type>() const { \
299 return detach(); \
300 } \
301 rbool operator==(const std::optional<type>& rhs) const noexcept; \
302 rbool operator!=(const std::optional<type>& rhs) const noexcept; \
303 void operator+=(const type& o) { \
304 auto old_val = m_obj->get_optional<type>(m_key); \
305 if (!old_val) { \
306 throw std::runtime_error("Cannot perform arithmetic on null value."); \
307 } \
308 m_obj->template set<type>(this->m_key, (*old_val) + o); \
309 } \
310 void operator++(int) { \
311 auto old_val = m_obj->get_optional<type>(m_key); \
312 if (!old_val) { \
313 throw std::runtime_error("Cannot perform arithmetic on null value."); \
314 } \
315 m_obj->template set<type>(this->m_key, (*old_val) + 1); \
316 } \
317 void operator-=(const type& o) { \
318 auto old_val = m_obj->get_optional<type>(m_key); \
319 if (!old_val) { \
320 throw std::runtime_error("Cannot perform arithmetic on null value."); \
321 } \
322 m_obj->template set<type>(this->m_key, (*old_val) - o); \
323 } \
324 void operator--(int) { \
325 auto old_val = m_obj->get_optional<type>(m_key); \
326 if (!old_val) { \
327 throw std::runtime_error("Cannot perform arithmetic on null value."); \
328 } \
329 m_obj->template set<type>(this->m_key, (*old_val) - 1); \
330 } \
331 void operator*=(const type& o) { \
332 auto old_val = m_obj->get_optional<type>(m_key); \
333 if (!old_val) { \
334 throw std::runtime_error("Cannot perform arithmetic on null value."); \
335 } \
336 m_obj->template set<type>(this->m_key, (*old_val) * o); \
337 } \
338 void operator*(const type& o) { \
339 auto old_val = m_obj->get_optional<type>(m_key); \
340 if (!old_val) { \
341 throw std::runtime_error("Cannot perform arithmetic on null value."); \
342 } \
343 m_obj->template set<type>(this->m_key, (*old_val) * o); \
344 } \
345 void operator/(const type& o) { \
346 auto old_val = m_obj->get_optional<type>(m_key); \
347 if (!old_val) { \
348 throw std::runtime_error("Cannot perform arithmetic on null value."); \
349 } \
350 m_obj->template set<type>(this->m_key, (*old_val) / o); \
351 } \
352 private: \
353 managed() = default; \
354 managed(const managed&) = delete; \
355 managed(managed &&) = delete; \
356 managed& operator=(const managed&) = delete; \
357 managed& operator=(managed&&) = delete; \
358 template<typename, typename> \
359 friend struct managed; \
360 }; \
361
362CPP_REALM_MANAGED_OPTIONAL_NUMERIC(int64_t)
363CPP_REALM_MANAGED_OPTIONAL_NUMERIC(double)
364
365 template<>
366 struct managed<std::optional<bool>> : managed_base {
367 using managed<std::optional<bool>>::managed_base::operator=;
368
369 [[nodiscard]] std::optional<bool> detach() const {
370 return m_obj->template get_optional<bool>(m_key);
371 }
372
373 [[nodiscard]] operator std::optional<bool>() const {
374 return m_obj->template get_optional<bool>(m_key);
375 }
376
377 std::optional<bool> operator *() const {
378 return detach();
379 }
380
381 rbool operator==(const std::optional<bool>& rhs) const noexcept;
382 rbool operator!=(const std::optional<bool>& rhs) const noexcept;
383
384 private:
385 managed() = default;
386 managed(const managed&) = delete;
387 managed(managed &&) = delete;
388 managed& operator=(const managed&) = delete;
389 managed& operator=(managed&&) = delete;
390 template<typename, typename>
391 friend struct managed;
392 };
393
394 template <typename T>
395 struct managed<T, std::enable_if_t<std::is_enum_v<T>>> : public managed_base {
396 managed<T>& operator =(const T& v) {
397 m_obj->template set<int64_t>(m_key, static_cast<int64_t>(v));
398 return *this;
399 }
400
401 [[nodiscard]] T detach() const {
402 return static_cast<T>(m_obj->get<int64_t>(m_key));
403 }
404
405 [[nodiscard]] T operator *() const {
406 return detach();
407 }
408
409 [[nodiscard]] operator T() const {
410 return detach();
411 }
412
413 //MARK: - comparison operators
414 rbool operator==(const T& rhs) const noexcept {
415 if (this->m_rbool_query) {
416 return this->m_rbool_query->equal(m_key, serialize(rhs));
417 }
418 return detach() == rhs;
419 }
420 rbool operator!=(const T& rhs) const noexcept {
421 if (this->m_rbool_query) {
422 return this->m_rbool_query->not_equal(m_key, serialize(rhs));
423 }
424 return detach() != rhs;
425 }
426 rbool operator>(const T& rhs) const noexcept {
427 if (this->m_rbool_query) {
428 return this->m_rbool_query->greater(m_key, serialize(rhs));
429 }
430 return detach() > rhs;
431 }
432 rbool operator<(const T& rhs) const noexcept {
433 if (this->m_rbool_query) {
434 return this->m_rbool_query->greater(m_key, serialize(rhs));
435 }
436 return detach() < rhs;
437 }
438 rbool operator>=(const T& rhs) const noexcept {
439 if (this->m_rbool_query) {
440 return this->m_rbool_query->greater_equal(m_key, serialize(rhs));
441 }
442 return detach() >= rhs;
443 }
444 rbool operator<=(const T& rhs) const noexcept {
445 if (this->m_rbool_query) {
446 return this->m_rbool_query->less_equal(m_key, serialize(rhs));
447 }
448 return detach() <= rhs;
449 }
450
451 private:
452 managed() = default;
453 managed(const managed&) = delete;
454 managed(managed &&) = delete;
455 managed& operator=(const managed&) = delete;
456 managed& operator=(managed&&) = delete;
457 template<typename, typename>
458 friend struct managed;
459 };
460
461 template <typename T>
462 struct managed<std::optional<T>, std::enable_if_t<std::is_enum_v<T>>> : public managed_base {
463 managed<std::optional<T>>& operator =(const std::optional<T>& v) {
464 if (v) {
465 m_obj->template set<std::optional<int64_t>>(m_key, static_cast<int64_t>(*v));
466 } else {
467 m_obj->set_null(m_key);
468 }
469 return *this;
470 }
471
472 [[nodiscard]] std::optional<T> detach() const {
473 if (auto v = m_obj->get_optional<int64_t>(m_key)) {
474 return static_cast<T>(*v);
475 }
476 return std::nullopt;
477 }
478
479 [[nodiscard]] std::optional<T> operator *() const {
480 return detach();
481 }
482
483 [[nodiscard]] operator std::optional<T>() const {
484 return detach();
485 }
486
487 //MARK: - comparison operators
488 rbool operator==(const std::optional<T>& rhs) const noexcept {
489 if (this->m_rbool_query) {
490 return this->m_rbool_query->equal(m_key, serialize(rhs));
491 }
492 return detach() == rhs;
493 }
494 rbool operator!=(const std::optional<T>& rhs) const noexcept {
495 if (this->m_rbool_query) {
496 return this->m_rbool_query->not_equal(m_key, serialize(rhs));
497 }
498 return detach() != rhs;
499 }
500 rbool operator>(const T& rhs) const noexcept {
501 if (this->m_rbool_query) {
502 return this->m_rbool_query->greater(m_key, rhs);
503 }
504 return detach() > rhs;
505 }
506 rbool operator<(const T& rhs) const noexcept {
507 if (this->m_rbool_query) {
508 return this->m_rbool_query->less(m_key, rhs);
509 }
510 return detach() < rhs;
511 }
512 rbool operator>=(const T& rhs) const noexcept {
513 if (this->m_rbool_query) {
514 return this->m_rbool_query->greater_equal(m_key, rhs);
515 }
516 return detach() >= rhs;
517 }
518 rbool operator<=(const T& rhs) const noexcept {
519 if (this->m_rbool_query) {
520 return this->m_rbool_query->less_equal(m_key, rhs);
521 }
522 return detach() <= rhs;
523 }
524
525 private:
526 managed() = default;
527 managed(const managed&) = delete;
528 managed(managed &&) = delete;
529 managed& operator=(const managed&) = delete;
530 managed& operator=(managed&&) = delete;
531 template<typename, typename>
532 friend struct managed;
533 };
534} // namespace realm
535
536#endif//CPPREALM_MANAGED_NUMERIC_HPP
Definition: rbool.hpp:36
Definition: macros.hpp:286
Definition: obj.hpp:62