Realm C++ SDK Version v2.2.0

link.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_BRIDGE_LINK_HPP
20#define CPPREALM_BRIDGE_LINK_HPP
21
22#include <cpprealm/accessors.hpp>
23#include <cpprealm/macros.hpp>
24#include <cpprealm/rbool.hpp>
25
26#include <cpprealm/internal/type_info.hpp>
27
28namespace realm {
29 template <typename, typename>
30 struct managed;
31
32 template<typename T>
33 struct managed<T*> : managed_base {
34 T* detach() const {
35 T* v = new T();
36 managed<T> m(m_obj->is_null(m_key) ? *m_obj : m_obj->get_linked_object(m_key), *m_realm);
37 auto assign = [&m, &v](auto& pair) {
38 (*v).*(std::decay_t<decltype(pair.first)>::ptr) = (m.*(pair.second)).detach();
39 };
40 auto zipped = internal::zip_tuples(managed<T>::schema.ps, managed<T>::managed_pointers());
41 std::apply([&v, &m, &assign](auto && ...pair) {
42 (assign(pair), ...);
43 }, zipped);
44 return v;
45 }
46
47 struct ref_type {
48 explicit ref_type(managed<T>&& value) : m_managed(std::move(value)) { }
49 const managed<T>* operator ->() const {
50 return &m_managed;
51 }
52 managed<T>* operator ->() {
53 return &m_managed;
54 }
55
56 const managed<T>& operator *() const {
57 return m_managed;
58 }
59 managed<T>& operator *() {
60 return m_managed;
61 }
62
63 bool operator ==(const managed<T*>& rhs) const {
64 if (this->m_managed.m_realm != *rhs.m_realm) {
65 return false;
66 }
67 return this->m_managed.m_obj.get_key() == rhs.m_obj->get_key();
68 }
69 bool operator ==(const managed<T>& rhs) const {
70 if (this->m_managed.m_realm != rhs.m_realm) {
71 return false;
72 }
73 return this->m_managed.m_obj.get_table() == rhs.m_obj.get_table() &&
74 this->m_managed.m_obj.get_key() == rhs.m_obj.get_key();
75 }
76 bool operator ==(const ref_type& rhs) const {
77 if (this->m_managed.m_realm != rhs.m_managed.m_realm) {
78 return false;
79 }
80 return this->m_managed.m_obj.get_table() == rhs.m_managed.m_obj.get_table() &&
81 this->m_managed.m_obj.get_key() == rhs.m_managed.m_obj.get_key();
82 }
83 bool operator !=(const managed<T*>& rhs) const {
84 return !this->operator==(rhs);
85 }
86 bool operator !=(const managed<T>& rhs) const {
87 return !this->operator==(rhs);
88 }
89 bool operator !=(const ref_type& rhs) const {
90 return !this->operator==(rhs);
91 }
92 private:
93 managed<T> m_managed;
94 };
95 ref_type operator ->() const {
96 if (this->m_rbool_query) {
97 this->m_rbool_query->add_link_chain(m_key);
98 return ref_type(managed<T>::prepare_for_query(*m_realm, this->m_rbool_query));
99 }
100 return ref_type(managed<T>(m_obj->get_linked_object(m_key), *m_realm));
101 }
102 operator bool() const {
103 if (m_obj && m_key) {
104 return !m_obj->is_null(m_key);
105 }
106 return false;
107 }
108 managed &operator=(const managed<T>& obj) {
109 m_obj->set(m_key, obj.m_obj.get_key());
110 return *this;
111 }
112 managed &operator=(const managed<T*> &obj) {
113 m_obj->set(m_key, obj.m_obj->get_key());
114 return *this;
115 }
116 managed &operator=(std::nullptr_t) {
117 m_obj->set_null(m_key);
118 return *this;
119 }
120 managed &operator=(T* o) {
121 auto table = m_realm->table_for_object_type(managed<T>::schema.name);
122 internal::bridge::obj obj;
123 if (!o) {
124 m_obj->set_null(m_key);
125 return *this;
126 } else if constexpr (managed<T>::schema.HasPrimaryKeyProperty) {
127 auto pk = (*o).*(managed<T>::schema.primary_key().ptr);
128 obj = table.create_object_with_primary_key(realm::internal::bridge::mixed(serialize(pk.value)));
129 m_obj->set(m_key, obj.get_key());
130 } else if (managed<T>::schema.is_embedded()) {
131 obj = m_obj->create_and_set_linked_object(m_key);
132 } else {
133 obj = table.create_object();
134 m_obj->set(m_key, obj.get_key());
135 }
136
137 std::apply([&obj, &o, realm = *m_realm](auto && ...p) {
138 (accessor<typename std::decay_t<decltype(p)>::Result>::set(
139 obj, obj.get_table().get_column_key(p.name), realm, (*o).*(std::decay_t<decltype(p)>::ptr)
140 ), ...);
141 }, managed<T>::schema.ps);
142 return *this;
143 }
144
145 rbool operator ==(std::nullptr_t) const {
146 if (m_rbool_query) {
147 return m_rbool_query->link_equal(m_key, std::nullopt);
148 }
149 return !m_obj->get_linked_object(m_key).is_valid();
150 }
151 rbool operator ==(const managed<T>& rhs) const {
152 if (m_rbool_query) {
153 return m_rbool_query->link_equal(m_key, rhs.m_obj);
154 }
155 if (*this->m_realm != rhs.m_realm)
156 return false;
157 return m_obj->get_linked_object(m_key).get_key() == rhs.m_obj.get_key();
158 }
159
160 rbool operator ==(const managed<T*>& rhs) const {
161 if (m_rbool_query) {
162 return m_rbool_query->link_equal(m_key, *rhs.m_obj);
163 }
164 if (*this->m_realm != *rhs.m_realm)
165 return false;
166 return m_obj->get_linked_object(m_key).get_key() == rhs.m_obj->get_key();
167 }
168
169 rbool operator !=(std::nullptr_t) const {
170 if (m_rbool_query) {
171 return m_rbool_query->link_not_equal(m_key, std::nullopt);
172 }
173 return m_obj->get_linked_object(m_key).is_valid();
174 }
175 rbool operator !=(const managed<T>& rhs) const {
176 if (m_rbool_query) {
177 return m_rbool_query->link_not_equal(m_key, rhs.m_obj);
178 }
179 return m_obj->get_linked_object(m_key).is_valid();
180 }
181
182 rbool operator !=(const managed<T*>& rhs) const {
183 if (m_rbool_query) {
184 return m_rbool_query->link_not_equal(m_key, *rhs.m_obj);
185 }
186 return m_obj->get_linked_object(m_key).is_valid();
187 }
188
189 private:
190 managed<T*>() = default;
191 template<typename, typename>
192 friend struct managed;
193 };
194} //namespace realm
195#endif //CPPREALM_BRIDGE_LINK_HPP
Definition: mixed.hpp:69
Definition: link.hpp:33
Definition: macros.hpp:286
Definition: obj.hpp:62