Realm C++ SDK 버전 v2.2.0

schema.hpp

1
2//
3//저작권 2022 Realm Inc.
4//
5// Apache 라이선스, 버전 2.0("라이선스")에 따라 라이선스가 부여됩니다.
6// 라이선스를 준수하는 경우를 제외하고는 이 파일을 사용할 수 없습니다.
7// 다음에서 라이선스 사본을 얻을 수 있습니다.
8//
9// http://www.apache.org/licences/LICENSE-2.0
10//
11// 관련 법률에서 요구하거나 문서로 동의하지 않는 한, 소프트웨어
12// 라이선스에 따라 배포되는 것은 '있는 그대로' 배포됩니다,
13// Express 묵시적이든 어떤 종류의 보증이나 조건도 제공하지 않습니다.
14// 권한을 관리하는 특정 언어에 대한 내용은 라이선스를 참조하세요.
15// 라이선스에 따른 제한 사항.
16//
18
19#ifndef CPPREALM_SCHEMA_HPP
20#define CPPRALM_SCHEMA_HPP
21
22#include <cpprealm/link.hpp>
23#include <cpprealm/internal/bridge/lnklst.hpp>
24#include <cpprealm/internal/bridge/object_schema.hpp>
25#include <cpprealm/internal/bridge/realm.hpp>
26#include <cpprealm/internal/bridge/table.hpp>
27#include <cpprealm/internal/type_info.hpp>
28#include <variant>
29
30#include <type_traits>
31#include <iostream>
32
33네임스페이스 영역 {
34 열거형 클래스 ObjectType {
35 없음,
36 TopLevel,
37 임베디드,
38 비대칭
39 };
40 네임스페이스 내부 {
41 템플릿 <typename T>
43 template <typename 결과, typename 클래스>
44 구조체 ptr_type_extractor_base<Result Class::*>
45 {
46 using class_type = Class;
47 using member_type = Result;
48 };
49
50 template <auto T>
52 };
53
54 template<typename... Typescript>
55 constexpr auto make_subpack_tuple(Ts&&... xs)
56 {
57 return std::tuple<Ts...>(std::forward<Ts>(xs)...);
58 }
59
60 템플릿 <typename T>
61 구조체 지속 형_추출기 {
62 Result = T 를 사용 합니다.
63 };
64 }
65
66
67 // 마크: 스키마
68 네임스페이스 schemagen {
69 템플릿 <auto Ptr, bool IsPrimaryKey = false>
70 구조체 속성 {
72 VariantResult =
73 std::conditional_t<std::is_pointer_v<Result>, managed<Result>, Result>;
74
76 static constexpr 자동 ptr = Ptr;
77 static constexpr bool is_primary_key = IsPrimaryKey || internal::type_info::is_primary_key<Result>::value;
78 internal::bridge::property::type type;
79 const char* name = "";
80
82 {
83 }
84 명시적 constexpr 속성(const char* real_name)
86 {
87 이름 = real_name;
88 }
89
90 연산자 internal::bridge:: 속성() const {
91 internal::bridge::property 속성(이름, 유형, is_primary_key);
93 만약 constexpr (std::is_pointer_v<typename Result::value_type>) {
94 속성.set_object_link(관리되는<std::remove_pointer_t<typename Result::value_type>, oid>::schema.name);
95 }
97 만약 constexpr (std::is_pointer_v<typename Result::value_type>) {
98 속성.set_object_link(관리되는<std::remove_pointer_t<typename Result::value_type>, oid>::schema.name);
99 }
103 속성.set_object_link(managed<std::remove_pointer_t<typename Result:: mapped_type ::value_type>, oid >:: 스키마.name);
104 속성.set_type(type | internal::bridge::property::type::Nullable);
105 }
106 } 다른 경우 if constexpr (std::is_pointer_v<typename Result::mapped_type>) {
107 속성.set_object_link(managed<std::remove_pointer_t<typename Result:: mapped_type>, oid >:: 스키마.name);
108 속성.set_type(type | internal::bridge::property::type::Nullable);
109 }
110 } 다른 경우 if constexpr (std::is_pointer_v<Result>) {
111 속성.set_object_link (관리<유형 이름 std::remove_pointer_t<Result>, oid>::schema.name);
112 속성.set_type(type | internal::bridge::property::type::Nullable);
115 }
116
117 반환 속성;
118 }
119 };
120
121 template <typename T, typename ... types>
122 구조체 unique_variant {
123 유형 = T 를 사용 합니다.
124 };
125
126 template <template<typename...> typename Variant, typename... VariantTypes, typename NextType, typename... RemainingTypes>
127 구조체 unique_variant<Variant<VariantTypes...> , NextType, RemainingTypes...>
128 : std::conditional<
129 std::dis Junction< std::is_same<NextType, VariantTypes> ... >::value
130 , unique_variant<Variant<VariantTypes...>, RemainingTypes...>
131 , unique_variant<Variant<VariantTypes..., NextType>, RemainingTypes...>
132 >::type
133 {};
134
135 템플릿 <typename class, typename 속성>
136 구조체 schema {
137 const char *name;
138 const char *names[sizeof...(Properties)] = {};
139 const char *primary_key_name = "";
140
141 static constexpr std::tuple<Properties...> properties{};
142 using variant_t = typename unique_variant<std::variant<>, std::monostate, typename Properties::VariantResult...>::type;
143
144 템플릿<size_t N>
145 constexpr auto do_apply_name(const std::tuple<Properties...> &tup) {
146 만약 constexpr (N + 1 == sizeof...(Properties)) {
147 이름[N] = std::get<N>(tup).name;
148 if (std::get<N>(tup).is_primary_key) {
149 primary_key_name = std::get<N>(tup).name;
150 }
151 return;
152 } 기타 {
153 이름[N] = std::get<N>(tup).name;
154 if (std::get<N>(tup).is_primary_key) {
155 primary_key_name = std::get<N>(tup).name;
156 }
157 return do_apply_name<N + 1>(tup);
158 }
159 }
160
161 constexpr auto apply_name(const std::tuple<Properties...> &tup) {
162 return do_apply_name<0>(tup);
163 }
164
165 std::tuple<Properties...> ps;
166
167 명시적 constexpr schema(const char *name_, 속성 &&... props)
168 : name(name_)
169 , ps(props...) {
170 auto tup = std::make_tuple(props...);
171 apply_name(tup);
172 }
173 명시적 constexpr schema(const char *name_, std::tuple<Properties...>&& props)
174 : name(name_)
175 , ps(props) {
176 apply_name(props);
177 }
178 명시적 constexpr 스키마(const char *name_, ObjectType object_type, std::tuple<Properties...>&& props)
179 : name(name_)
180 , ps(props), m_object_type(object_type) {
181 apply_name(props);
182 }
183 템플릿<size_t N, typename P>
184 static constexpr 자동 primary_key(P &) {
185 만약 constexpr (P::is_primary_key) {
186 반환 P();
187 } 기타 {
188 만약 constexpr (N + 1 == sizeof...(Properties)) {
189 return;
190 } 기타 {
191 반환 primary_key<N + 1>(std::get<N + 1>(properties));
192 }
193 }
194 }
195
196 static constexpr 자동 primary_key() {
197 반환 primary_key<0>(std::get<0>(properties));
198 }
199
200 PrimaryKeyProperty = decltype(primary_key());
201 static constexpr bool HasPrimaryKeyProperty = !std::is_oid_v<PrimaryKeyProperty>;
202
203 bool is_embedded() const {
204 return m_object_type == ObjectType::Embedded;
205 }
206
207 [[nodiscard]] internal::bridge::object_schema to_core_schema() const {
209 스키마.set_name(name);
210
211 auto add_property = [&](const internal::bridge::property &p) {
212 if (!p.name().empty()) {
213 스키마.add_property(p);
214 }
215 };
216 std:: 적용([&](const auto&... p) {
217 (add_property(p), ...);
218 }, ps);
219
220 만약 constexpr (HasPrimaryKeyProperty) {
221 schema.set_primary_key(primary_key_name);
222 }
223 if (m_object_type == ObjectType::Embedded) {
224 schema.set_object_type(internal::bridge::object_schema::object_type::Embedded);
225 }
226 if (m_object_type == ObjectType::Asymmetric) {
227 schema.set_object_type(internal::bridge::object_schema::object_type::TopLevelAsymmetric);
228 }
229 반환 스키마;
230 }
231
232 템플릿<size_t N, typename P>
233 constexpr auto set(Class &object, P &속성) const {
234 만약 constexpr (N + 1 == sizeof...(Properties)) {
235 속성. 설정하다(객체, 이름[N]);
236 return;
237 } 기타 {
238 속성. 설정하다(객체, 이름[N]);
239 return 설정하다<N + 1>(객체, std::get<N + 1>(properties));
240 }
241 }
242
243 템플릿<size_t N, typename P>
244 constexpr variant_t
245 속성 값_for_name(std::string_view 속성 이름, const 관리<클래스, 무효> &cls, P &속성, bool linking_collections = true) const {
246 bool is_array = 영역::internal::bridge::property_has_flag(속성.type, 영역::internal::bridge:: 속성::type::Array);
247 bool is_dictionary = 영역::internal::bridge::property_has_flag(속성.type, 영역::internal::bridge:: 속성::type::Dictionary);
248 bool is_set = 영역::internal::bridge::property_has_flag(속성.type, 영역::internal::bridge:: 속성::type::Set);
249 bool is_collection = is_array || is_dictionary || is_set;
250 if (제외 컬렉션 && is_collection) {
251 return variant_t{std::monostate()};
252 }
253
254 만약 constexpr (N + 1 == sizeof...(Properties)) {
255 if (property_name == std::string_view(names[N])) {
256 자동 ptr = managed<클래스, 무효>:: 템플릿 unmanaged_to_managed_pointer(속성.ptr);
257 만약 constexpr (std::is_pointer_v<typename P::Result>) {
258 return (cls.*ptr);
259 } 기타 {
260 return (cls.*ptr).detach();
261 }
262 }
263 반환 variant_t{};
264 } 기타 {
265 if (property_name == std::string_view(names[N])) {
266 자동 ptr = managed<클래스, 무효>:: 템플릿 unmanaged_to_managed_pointer(속성.ptr);
267 만약 constexpr (std::is_pointer_v<typename P::Result>) {
268 return (cls.*ptr);
269 } 기타 {
270 return (cls.*ptr).detach();
271 }
272 }
273 return Property_value_for_name<N + 1>(property_name, cls, std::get<N + 1>(properties), linking_collections);
274 }
275 }
276 constexpr 자동 속성 값_for_name(std::string_view 속성 이름, const managed<클래스, 무효> &cls, bool linking_collections = true) const {
277 return Property_value_for_name<0>(property_name, cls, std::get<0>(properties), linking_collections);
278 }
279
280 템플릿<size_t N, typename T, typename P>
281 constexpr const char*
282 name_for_property(T ptr, P &속성) const {
283 만약 constexpr (N + 1 == sizeof...(Properties)) {
284 만약 constexpr (std::is_same_v<decltype(ptr), std::remove_const_t<decltype(속성.ptr)>>) {
285 if (ptr == 속성.ptr) {
286 반환 속성.name;
287 }
288 }
289 반환 "";
290 } 기타 {
291 만약 constexpr (std::is_same_v<decltype(ptr), std::remove_const_t<decltype(속성.ptr)>>) {
292 if (ptr == 속성.ptr) {
293 반환 속성.name;
294 }
295 }
296 return name_for_property<N + 1>(ptr, std::get<N + 1>(ps));
297 }
298 }
299 템플릿 <auto ptr>
300 constexpr const char* name_for_property() const {
301 return name_for_property<0>(ptr, std::get<0>(ps));
302 }
303 템플릿 <typename T>
304 constexpr const char* name_for_property(T ptr) const {
305 return name_for_property<0>(ptr, std::get<0>(ps));
306 }
307 private:
308 ObjectType m_object_type = ObjectType::None;
309 };
310 }
311 템플릿 <auto Ptr, bool IsPrimaryKey = false>
312 static constexpr auto 속성(const char* name)
313 {
315 }
316
317 템플릿 <typename ...T>
318 static constexpr 자동 스키마(const char * 이름,
319 T&&... props) {
320 auto tup = internal::make_subpack_tuple(props...);
321 auto i = std::get<0>(tup);
322 using Cls = typename decltype(i)::Class;
323 return schemagen::schema<Cls, T...>(name, std::move(props)...);
324 }
325
326 템플릿 <typename ...T>
327 static constexpr 자동 스키마(const char * 이름,
328 std::tuple<T...>&& props) {
329 auto i = std::get<0>(props);
330 using Cls = typename decltype(i)::Class;
331 return schemagen:: 스키마<Cls, T...>(name, std::move(props));
332 }
333
334 템플릿 <typename ...T>
335 static constexpr 자동 스키마(const char * 이름,
336 ObjectType object_type,
337 std::tuple<T...>&& props) {
338 auto i = std::get<0>(props);
339 using Cls = typename decltype(i)::Class;
340 return schemagen:: 스키마<Cls, T...>(name, object_type, std::move(props));
341 }
342}
343
344#endif /* CPPRALM_SCHEMA_HPP */
정의: object_schema.hpp:33
정의: type_info.hpp:70
정의: type_info.hpp:62
정의: obj.hpp:62
정의: managed_primary_key.hpp:30
정의: schema.hpp:70
정의: schema.hpp:136
정의: schema.hpp:122