Realm C++ SDK Version v2.2.0

type_info.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_TYPE_INFO_HPP
20#define CPPREALM_TYPE_INFO_HPP
21
22#include <cpprealm/internal/bridge/property.hpp>
23#include <cpprealm/internal/bridge/uuid.hpp>
24#include <cpprealm/internal/bridge/binary.hpp>
25#include <cpprealm/internal/bridge/timestamp.hpp>
26#include <cpprealm/internal/bridge/mixed.hpp>
27#include <cpprealm/internal/bridge/obj_key.hpp>
28#include <cpprealm/internal/bridge/list.hpp>
29#include <cpprealm/internal/bridge/dictionary.hpp>
30#include <cpprealm/internal/bridge/object_id.hpp>
31#include <cpprealm/internal/bridge/decimal128.hpp>
32#include <cpprealm/internal/bridge/set.hpp>
33
34#include <map>
35#include <vector>
36
37namespace realm {
38 template <auto>
39 struct linking_objects;
40 template <typename>
41 struct primary_key;
42}
43namespace realm::internal::type_info {
44 template <typename T, typename = void>
45 struct is_optional : std::false_type {
46 using underlying = T;
47 };
48 template <template <typename> typename Optional, typename T>
49 struct is_optional<Optional<T>,
50 std::enable_if_t<std::is_same_v<std::optional<T>, Optional<T>>>> : std::true_type {
51 using underlying = T;
52 };
53 template <typename T, typename = void>
54 struct is_vector : std::false_type {
55 static constexpr auto value = false;
56 };
57 template <typename T>
58 struct is_vector<std::vector<T>> : std::true_type {
59 static constexpr auto value = true;
60 };
61 template <typename T, typename = void>
62 struct is_set : std::false_type {
63 static constexpr auto value = false;
64 };
65 template <typename T>
66 struct is_set<std::set<T>> : std::true_type {
67 static constexpr auto value = true;
68 };
69 template <typename T, typename = void>
70 struct is_map : std::false_type {
71 using value_type = T;
72 };
73 template <typename T>
74 struct is_map<std::map<std::string, T>> : std::true_type {
75 using value_type = T;
76 };
77 template <typename, typename>
78 struct managed;
79 template <typename T, typename = void>
80 struct type_info;
81
82 namespace {
83 template <typename T>
84 using is_primitive = std::negation<std::disjunction<
85 std::is_same<typename type_info<T>::internal_type, std::optional<bridge::obj_key>>,
86 std::is_same<typename type_info<T>::internal_type, bridge::obj_key>,
87 std::is_same<typename type_info<T>::internal_type, bridge::list>,
88 std::is_same<typename type_info<T>::internal_type, bridge::dictionary>
89 >>;
90
91 template <typename T, typename = void>
92 struct is_variant_t : std::false_type {};
93 template <template <typename ...> typename Variant, typename ...Ts>
94 struct is_variant_t<Variant<Ts...>, std::enable_if_t<std::is_same_v<std::variant<Ts...>, Variant<Ts...>>>>
95 : std::true_type {
96 };
97
98 template<size_t N, typename Variant>
99 constexpr bool check_variant_types() {
100 if constexpr (!is_variant_t<Variant>::value) {
101 return false;
102 } else if constexpr (N >= std::variant_size_v<Variant>) {
103 return true;
104 } else {
105 if constexpr (std::is_same_v<std::variant_alternative_t<N, Variant>, std::monostate>) {
106 return check_variant_types<N + 1, Variant>();
107 } else if constexpr (is_primitive<std::variant_alternative_t<N, Variant>>::value) {
108 return check_variant_types<N + 1, Variant>();
109 } else {
110 return false;
111 }
112 }
113 }
114
115 template<typename T>
116 using MixedPersistableConcept =
117 std::conjunction<is_variant_t<T>,
118 std::conditional_t<check_variant_types<0, T>(), std::true_type, std::false_type>
119 >;
120
121 namespace {
122 static_assert(std::conjunction<
123 std::is_convertible<int, int64_t>,
124 std::is_constructible<int, int64_t>>::value);
125 static_assert(std::conjunction<
126 std::is_convertible<const char*, std::string>,
127 std::is_constructible<std::string, const char*>>::value);
128 }
129 }
130 template <typename T>
131 struct type_info<T*> {
133 static constexpr bridge::property::type type() {
134 return bridge::property::type::Object;
135 }
136 };
137 template <auto T>
140 static constexpr bridge::property::type type() {
141 return bridge::property::type::LinkingObjects | bridge::property::type::Array;
142 }
143 };
144 template <typename T>
145 struct is_link : std::false_type {
146 static constexpr auto value = false;
147 static constexpr auto is_managed = false;
148 };
149 template <typename T>
150 struct is_link<managed<T*, void>> : std::true_type {
151 static constexpr auto value = true;
152 static constexpr auto is_managed = true;
153 };
154 template <typename T>
155 struct is_link<T*> : std::true_type {
156 static constexpr auto value = true;
157 static constexpr auto is_managed = false;
158 };
159
160 template <typename T>
161 struct is_backlink : std::false_type {
162 static constexpr auto value = false;
163 };
164 template <auto T>
165 struct is_backlink<linking_objects<T>> : std::true_type {
166 static constexpr auto value = true;
167 };
168 template <>
169 struct type_info<std::monostate> {
170 using internal_type = std::monostate;
171 static constexpr bridge::property::type type() {
172 return bridge::property::type::Mixed;
173 }
174 };
175 template <>
176 struct type_info<std::string> {
177 using internal_type = std::string;
178 static constexpr bridge::property::type type() {
179 return bridge::property::type::String;
180 }
181 };
182 template <>
183 struct type_info<const char*> {
184 using internal_type = std::string;
185 static constexpr bridge::property::type type() {
186 return bridge::property::type::String;
187 }
188 };
189 template <>
190 struct type_info<int64_t> {
191 using internal_type = int64_t;
192 static constexpr bridge::property::type type() {
193 return bridge::property::type::Int;
194 }
195 };
196 template <>
197 struct type_info<int> {
198 using internal_type = int64_t;
199 static constexpr bridge::property::type type() {
200 return bridge::property::type::Int;
201 }
202 };
203 template <>
204 struct type_info<double> {
205 using internal_type = double;
206 static constexpr bridge::property::type type() {
207 return bridge::property::type::Double;
208 }
209 };
210 template <>
211 struct type_info<bool> {
212 using internal_type = bool;
213 static constexpr bridge::property::type type() {
214 return bridge::property::type::Bool;
215 }
216 };
217 template <>
218 struct type_info<uuid> {
220 static constexpr bridge::property::type type() {
221 return bridge::property::type::UUID;
222 }
223 };
224 template <>
227 static constexpr bridge::property::type type() {
228 return bridge::property::type::ObjectId;
229 }
230 };
231 template <>
234 static constexpr bridge::property::type type() {
235 return bridge::property::type::Decimal;
236 }
237 };
238 template <>
239 struct type_info<std::vector<uint8_t>> {
241 static constexpr bridge::property::type type() {
242 return bridge::property::type::Data;
243 }
244 };
245 template <typename E>
246 struct type_info<E, std::enable_if_t<std::is_enum_v<E>>> {
247 using internal_type = int64_t;
248 static constexpr bridge::property::type type() {
249 return bridge::property::type::Int;
250 }
251 };
252 template <typename ValueType>
253 struct type_info<std::map<std::string, ValueType>> {
255 static constexpr bridge::property::type type() {
256 return bridge::property::type::Dictionary | type_info<ValueType>::type();
257 }
258 };
259 template <typename ValueType>
260 struct type_info<std::set<ValueType>> {
262 static constexpr bridge::property::type type() {
263 return bridge::property::type::Set | type_info<ValueType>::type();
264 }
265 };
266 template <typename T>
267 struct type_info<T, std::enable_if_t<MixedPersistableConcept<T>::value>> {
269
270 static constexpr auto type() {
271 return bridge::property::type::Mixed | bridge::property::type::Nullable;
272 }
273 };
274 template <typename T>
275 struct type_info<std::optional<T>> {
276 using internal_type = std::optional<typename type_info<T>::internal_type>;
277 static constexpr auto type() {
278 return type_info<T>::type() | bridge::property::type::Nullable;
279 }
280 };
281 template <typename C, typename D>
282 struct type_info<std::chrono::time_point<C, D>> {
284 static constexpr auto type() {
285 return bridge::property::type::Date;
286 }
287 };
288 template <typename V>
289 struct type_info<std::vector<V>, std::enable_if_t<std::negation_v<std::is_same<V, uint8_t>>>> {
291 static constexpr auto type() {
292 return type_info<V>::type() | bridge::property::type::Array;
293 }
294 };
295
296 template <typename T>
297 struct is_primary_key : std::false_type {
298 static constexpr auto value = false;
299 };
300 template <typename T>
301 struct is_primary_key<primary_key<T>> : std::true_type {
302 static constexpr auto value = true;
303 };
304
305 template <typename T>
306 struct type_info<primary_key<T>, void> {
307 using internal_type = typename type_info<T>::internal_type;
308 static constexpr bridge::property::type type() {
309 return type_info<T>::type();
310 }
311 };
312
313}
314#endif //CPPREALM_TYPE_INFO_HPP
Definition: types.hpp:75
Definition: binary.hpp:30
Definition: decimal128.hpp:30
Definition: dictionary.hpp:138
Definition: list.hpp:49
Definition: mixed.hpp:69
Definition: obj_key.hpp:33
Definition: object_id.hpp:31
Definition: set.hpp:48
Definition: timestamp.hpp:30
Definition: uuid.hpp:32
Definition: type_info.hpp:70
Definition: type_info.hpp:45
Definition: type_info.hpp:297
Definition: type_info.hpp:62
Definition: type_info.hpp:54
Definition: type_info.hpp:78
Definition: results.hpp:419
Definition: types.hpp:56
Definition: managed_primary_key.hpp:30
Definition: types.hpp:35