Realm C++ SDK版本 v 2.2.0

schema.hpp

1
2//
3// 版权所有 2022 Realm Inc.
4//
5// 根据 Apache 许可证 2.0 版(“许可证”)获得许可;
6// 除非符合合规,否则不得使用此文件。
7// 您可以在以下网址获取许可证副本:
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// 除非适用法律要求或书面同意,否则软件
12// 根据许可证分发是按“原样”分发的,
13// 不提供任何类型的Express或暗示的保证或条件。
14// 请参阅管理权限的特定语言的许可证和
15// 许可证下的限制。
16//
18
19#ifndef CPPREALM_SCHEMA_HPP
20#define CPPREALM_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 enum class ObjectType {
35无,
36 TopLevel,
37嵌入式,
38不对称
39 };
40 命名空间内部 {
41 template < typename T>
43 template < typename Result, typename Class>
44 struct 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 template < typename T>
62 using Result = T;
63 };
64 }
65
66
67 // MARK: schema
68 命名空间schemagen {
69 template <auto Ptr, bool IsPrimaryKey = false>
70 struct 属性{
72 using VariantResult =
73 std::conditional_t<std::is_pointer_v<Result>, 托管<Result> , Result>;
74
75 using Class = typenameInternal ::ptr_type_extractor<Ptr>::class_type
76 静态 constexpr auto ptr = Ptr;
77 静态 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 *actual_name)
86 {
87 name =actual_name;
88 }
89
90 运算符 inside::bridge:: 属性 () const {
91 inside::bridge::property property (name, type, is_primary_key);
93 if constexpr (std::is_pointer_v<typename Result::value_type>) {
94 property .set_object_link( managed <std::remove_pointer_t<typename Result::value_type>, void >::schema.name);
95 }
97 if constexpr (std::is_pointer_v<typename Result::value_type>) {
98 property .set_object_link( managed <std::remove_pointer_t<typename Result::value_type>, void >::schema.name);
99 }
103 属性 .set_object_link( 托管 <std::remove_pointer_t<typename Result::mapped_type::value_type>, void >:: 模式.name);
104 property .set_type(type | Internal::bridge::property::type::Nullable);
105 }
106 } else if constexpr (std::is_pointer_v<typename Result::mapped_type>) {
107 属性 .set_object_link( 托管 <std::remove_pointer_t<typename Result::mapped_type>, void >:: 模式.name);
108 property .set_type(type | Internal::bridge::property::type::Nullable);
109 }
110 } else if constexpr (std::is_pointer_v<Result>) {
111 property .set_object_link( managed < typename std::remove_pointer_t<Result>, void >::schema.name);
112 property .set_type(type | Internal::bridge::property::type::Nullable);
114 return inside::bridge:: 属性 {};
115 }
116
117 return 属性
118 }
119 };
120
121 template < typename T, typename ... Types>
123 using type = T;
124 };
125
126 template < template < typename ...> typename Variant, typename ... VariantTypes, typename NextType, typename ... RemainingTypes>
127 struct unique_variant <Variant<VariantTypes...> , NextType, RemainingTypes...>
128 : std::conditional<
129 std::disjunction< std::is_same<NextType, VariantTypes> ... >::value
130 , unique_variant<Variant<VariantTypes...>, RemainingTypes...>
131 , unique_variant<Variant<VariantTypes..., NextType>, RemainingTypes...>
132 >::type
133 {};
134
135 template < typename Class, typename 属性>
136 struct schema {
137 const char *name;
138 const char *names[ sizeof ...(Properties)] = {};
139 const char *primary_key_name = "" ;
140
141 静态 constexpr std::tuple<Properties...> properties{};
142 usingvariant_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 if constexpr (N + 1 == sizeof ...(Properties)) {
147 names[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 } else {
153 names[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_, Properties &&... 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 template < size_t N, typename P>
184 静态 constexpr auto primary_key (P &) {
185 if constexpr (P::is_primary_key) {
186 return P();
187 } else {
188 if constexpr (N + 1 == sizeof ...(Properties)) {
189 return ;
190 } else {
191 return Primary_key<N + 1 > (std::get<N + 1 >(properties));
192 }
193 }
194 }
195
196 静态 constexpr auto primary_key () {
197 return primary_key< 0 > (std::get< 0 >(properties));
198 }
199
200 using PrimaryKeyProperty = decltype ( primary_key ());
201 静态 constexpr bool HasPrimaryKeyProperty = !std::is_void_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 inside ::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 if 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 return schema
230 }
231
232 template < size_t N, typename P>
233 constexpr auto set(Class & object , P & property ) const {
234 if constexpr (N + 1 == sizeof ...(Properties)) {
235 属性。设立(对象, 名称[N]);
236 return ;
237 } else {
238 属性。设立(对象, 名称[N]);
239 return 设立<N + 1 >( 对象 , std::get<N + 1 >(properties));
240 }
241 }
242
243 template < size_t N, typename P>
244 constexpr variant_t
245 property_value_for_name(std::string_view property_name, const Managed<Class, void> &cls, P & property , bool exclusive_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 (excluded_collections && is_collection) {
251 returnvariant_t{std:: monostate ()};
252 }
253
254 if constexpr (N + 1 == sizeof ...(Properties)) {
255 if (property_name == std::string_view(names[N])) {
256 auto ptr = Managed<Class, void>::template unmanaged_to_managed_pointer( property .ptr);
257 if constexpr (std::is_pointer_v<typename P::Result>) {
258 return (cls.*ptr);
259 } else {
260 return (cls.*ptr).detach();
261 }
262 }
263 returnvariant_t {};
264 } else {
265 if (property_name == std::string_view(names[N])) {
266 auto ptr = Managed<Class, void>::template unmanaged_to_managed_pointer( property .ptr);
267 if constexpr (std::is_pointer_v<typename P::Result>) {
268 return (cls.*ptr);
269 } else {
270 return (cls.*ptr).detach();
271 }
272 }
273 return property_value_for_name<N + 1 >(property_name, cls, std::get<N + 1 >(properties), exclusive_collections);
274 }
275 }
276 constexpr auto property_value_for_name(std::string_view property_name, const 托管<Class, void> &cls, bool execution_collections = true ) const {
277 return property_value_for_name< 0 >(property_name, cls, std::get< 0 >(properties), exclusive_collections);
278 }
279
280 template < size_t N, typename T, typename P>
281 constexpr const char *
282 name_for_property(T ptr, P & property ) const {
283 if constexpr (N + 1 == sizeof ...(Properties)) {
284 if constexpr (std::is_same_v< decltype (ptr), std::remove_const_t< decltype ( 属性 .ptr)>>) {
285 if (ptr == property .ptr) {
286 return 属性.name;
287 }
288 }
289 return "" ;
290 } else {
291 if constexpr (std::is_same_v< decltype (ptr), std::remove_const_t< decltype ( 属性 .ptr)>>) {
292 if (ptr == property .ptr) {
293 return 属性.name;
294 }
295 }
296 return name_for_property<N + 1 >(ptr, std::get<N + 1 >(ps));
297 }
298 }
299 template <auto ptr>
300 constexpr const char * name_for_property() const {
301 return name_for_property< 0 >(ptr, std::get< 0 >(ps));
302 }
303 template < 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 template <auto Ptr, bool IsPrimaryKey = false>
312 静态 constexpr auto属性( const char * name)
313 {
315 }
316
317 template < typename ...T>
318 静态 constexpr auto 模式( const char * name,
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 template < typename ...T>
327 静态 constexpr auto 模式( const char * name,
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 template < typename ...T>
335 静态 constexpr auto 模式( const char * name,
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 /* CPPREALM_SCHEMA_HPP */
定义: object_schema.hpp: 33
定义:属性.hpp: 33
定义: schema.hpp: 51
定义: type_info.hpp: 70
定义: type_info.hpp: 45
定义: type_info.hpp: 297
定义: type_info.hpp: 62
定义: type_info.hpp: 54
定义: obj.hpp:62
定义: managed_primary_key.hpp:30
定义: schema.hpp: 70
定义: schema.hpp: 136
定义: schema.hpp: 122