19#ifndef CPPREALM_SCHEMA_HPP
20#define CPPREALM_SCHEMA_HPP
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>
34 enum class ObjectType {
41 template <
typename T>
43 template <
typename Result,
typename Class>
46 using class_type = Class;
47 using member_type = Result;
54 template <
typename ... Typescript >
55 constexpr auto make_subpack_tuple(Ts&&... xs)
57 return std::tuple<Ts...>(std::forward<Ts>(xs)...);
60 template <
typename T>
69 template <auto Ptr,
bool IsPrimaryKey = false>
73 std::conditional_t<std::is_pointer_v<Result>,
托管<Result> , Result>;
76 静态 constexpr auto ptr = Ptr;
78 internal::bridge::property::type type;
79 const char * name =
"" ;
84 显式 constexpr 属性(
const char *actual_name)
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);
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);
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);
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);
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);
121 template <
typename T,
typename ... Types>
126 template <
template <
typename ...>
typename Variant,
typename ... VariantTypes,
typename NextType,
typename ... RemainingTypes>
129 std::disjunction< std::is_same<NextType, VariantTypes> ... >::value
130 , unique_variant<Variant<VariantTypes...>, RemainingTypes...>
131 , unique_variant<Variant<VariantTypes..., NextType>, RemainingTypes...>
135 template <
typename Class,
typename 属性>
138 const char *names[
sizeof ...(Properties)] = {};
139 const char *primary_key_name =
"" ;
141 静态 constexpr std::tuple<Properties...> properties{};
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;
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;
157 return do_apply_name<N + 1 >(tup);
161 constexpr auto apply_name(
const std::tuple<Properties...> &tup) {
162 return do_apply_name< 0 >(tup);
165 std::tuple<Properties...> ps;
167 显式 constexpr schema (
const char *name_, Properties &&... props)
170 auto tup = std::make_tuple(props...);
173 显式 constexpr schema (
const char *name_, std::tuple<Properties...>&& props)
178 显式 constexpr 模式 (
const char *name_, ObjectType object_type, std::tuple<Properties...>&& props)
180 , ps(props), m_object_type(object_type) {
183 template <
size_t N,
typename P>
185 if constexpr (P::is_primary_key) {
188 if constexpr (N + 1 ==
sizeof ...(Properties)) {
200 using PrimaryKeyProperty =
decltype (
primary_key ());
201 静态 constexpr bool HasPrimaryKeyProperty = !std::is_void_v<PrimaryKeyProperty>;
203 bool is_embedded()
const {
204 return m_object_type == ObjectType::Embedded;
212 if (!p.name().empty()) {
216 std:: 应用([&](
const auto &... p) {
217 (add_property(p), ...);
220 if constexpr (HasPrimaryKeyProperty) {
221 schema .set_primary_key(primary_key_name);
223 if (m_object_type == ObjectType::Embedded) {
224 schema .set_object_type(internal::bridge::object_schema::object_type::Embedded);
226 if (m_object_type == ObjectType::Asymmetric) {
227 schema .set_object_type(internal::bridge::object_schema::object_type::TopLevelAsymmetric);
232 template <
size_t N,
typename P>
233 constexpr auto set(Class &
object , P &
property )
const {
234 if constexpr (N + 1 ==
sizeof ...(Properties)) {
239 return 设立<N + 1 >(
对象 , std::get<N + 1 >(properties));
243 template <
size_t N,
typename P>
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 ()};
254 if constexpr (N + 1 ==
sizeof ...(Properties)) {
255 if (property_name == std::string_view(names[N])) {
257 if constexpr (std::is_pointer_v<typename P::Result>) {
260 return (cls.*ptr).detach();
265 if (property_name == std::string_view(names[N])) {
267 if constexpr (std::is_pointer_v<typename P::Result>) {
270 return (cls.*ptr).detach();
273 return property_value_for_name<N + 1 >(property_name, cls, std::get<N + 1 >(properties), exclusive_collections);
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);
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)>>) {
291 if constexpr (std::is_same_v<
decltype (ptr), std::remove_const_t<
decltype (
属性 .ptr)>>) {
296 return name_for_property<N + 1 >(ptr, std::get<N + 1 >(ps));
300 constexpr const char * name_for_property()
const {
301 return name_for_property< 0 >(ptr, std::get< 0 >(ps));
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));
308 ObjectType m_object_type = ObjectType::None;
311 template <auto Ptr,
bool IsPrimaryKey = false>
312 静态 constexpr auto属性(
const char * name)
317 template <
typename ...T>
318 静态 constexpr auto 模式(
const char * name,
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)...);
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));
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));
定义: object_schema.hpp: 33
定义: managed_primary_key.hpp:30