@@ -0,0 +1,6 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/misc.h> | |||
#include <cpphibernate/schema.h> | |||
#include <cpphibernate/types.h> |
@@ -0,0 +1,56 @@ | |||
#pragma once | |||
#include <boost/hana.hpp> | |||
#include <cpputils/mp/core.h> | |||
#define cpphibernate_equality_comparable() \ | |||
template<typename T_other> \ | |||
constexpr decltype(auto) operator==(T_other&&) const \ | |||
{ \ | |||
return ::boost::hana::type<::utl::mp::decay_t<decltype(*this)>> { } == \ | |||
::boost::hana::type<::utl::mp::decay_t<T_other>> { }; \ | |||
} \ | |||
\ | |||
template<typename T_other> \ | |||
constexpr decltype(auto) operator!=(T_other&&) const \ | |||
{ \ | |||
return ::boost::hana::type<::utl::mp::decay_t<decltype(*this)>> { } != \ | |||
::boost::hana::type<::utl::mp::decay_t<T_other>> { }; \ | |||
} | |||
#define cpphibernate_constructable(name, value) \ | |||
name() = value | |||
#define cpphibernate_copyable(name, value) \ | |||
name(const name&) = value; \ | |||
name& operator=(const name&) = value | |||
#define cpphibernate_moveable(name, value) \ | |||
name(name&&) = value; \ | |||
name& operator=(name&&) = value | |||
#define cpphibernate_define_namespace_beg(parent, name) \ | |||
parent { \ | |||
namespace name | |||
#define cpphibernate_define_namespace_end(parent) \ | |||
} \ | |||
parent | |||
#define beg_namespace_cpphibernate namespace cpphibernate | |||
#define end_namespace_cpphibernate | |||
#define beg_namespace_cpphibernate_schema cpphibernate_define_namespace_beg(beg_namespace_cpphibernate, schema) | |||
#define end_namespace_cpphibernate_schema cpphibernate_define_namespace_end(end_namespace_cpphibernate) | |||
#define beg_namespace_cpphibernate_misc cpphibernate_define_namespace_beg(beg_namespace_cpphibernate, misc) | |||
#define end_namespace_cpphibernate_misc cpphibernate_define_namespace_end(end_namespace_cpphibernate) | |||
beg_namespace_cpphibernate | |||
{ | |||
namespace mp = ::utl::mp; | |||
namespace hana = ::boost::hana; | |||
} | |||
end_namespace_cpphibernate |
@@ -0,0 +1,5 @@ | |||
#pragma once | |||
#include <cpphibernate/misc/general.h> | |||
#include <cpphibernate/misc/meta.h> | |||
#include <cpphibernate/misc/wrap.h> |
@@ -0,0 +1,19 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
beg_namespace_cpphibernate_misc | |||
{ | |||
/* make_generic_predicate */ | |||
template<template<typename...> class T_builder> | |||
struct make_generic_predicate | |||
{ | |||
template<typename... T_args> | |||
constexpr decltype(auto) operator()(T_args&&... args) const | |||
{ return T_builder<mp::list<T_args...>>::apply(std::forward<T_args>(args)...); } | |||
}; | |||
} | |||
end_namespace_cpphibernate_misc |
@@ -0,0 +1,130 @@ | |||
#pragma once | |||
#include <list> | |||
#include <vector> | |||
#include <memory> | |||
#include <cpphibernate/config.h> | |||
#include <cpputils/container/nullable.h> | |||
beg_namespace_cpphibernate_misc | |||
{ | |||
namespace __impl | |||
{ | |||
/* is_container_impl */ | |||
template<typename T> | |||
struct is_container_impl | |||
: public mp::c_false_t | |||
{ }; | |||
template<typename T> | |||
struct is_container_impl<std::list<T>> | |||
: public mp::c_true_t | |||
{ }; | |||
template<typename T> | |||
struct is_container_impl<std::vector<T>> | |||
: public mp::c_true_t | |||
{ }; | |||
/* is_nullable_impl */ | |||
template<typename T> | |||
struct is_nullable_impl | |||
: public mp::c_false_t | |||
{ }; | |||
template<typename T> | |||
struct is_nullable_impl<utl::nullable<T>> | |||
: public mp::c_true_t | |||
{ }; | |||
template<typename T> | |||
struct is_nullable_impl<std::unique_ptr<T>> | |||
: public mp::c_true_t | |||
{ }; | |||
template<typename T> | |||
struct is_nullable_impl<std::shared_ptr<T>> | |||
: public mp::c_true_t | |||
{ }; | |||
/* is_pointer_impl */ | |||
template<typename T> | |||
struct is_pointer_impl | |||
: public mp::c_false_t | |||
{ }; | |||
template<typename T> | |||
struct is_pointer_impl<std::unique_ptr<T>> | |||
: public mp::c_true_t | |||
{ }; | |||
template<typename T> | |||
struct is_pointer_impl<std::shared_ptr<T>> | |||
: public mp::c_true_t | |||
{ }; | |||
/* real_dataset_impl */ | |||
template<typename T, typename = void> | |||
struct real_dataset_impl | |||
{ using type = T; }; | |||
template<typename T> | |||
struct real_dataset_impl<utl::nullable<T>, void> | |||
{ using type = typename real_dataset_impl<T>::type; }; | |||
template<typename T> | |||
struct real_dataset_impl<std::unique_ptr<T>, void> | |||
{ using type = typename real_dataset_impl<T>::type; }; | |||
template<typename T> | |||
struct real_dataset_impl<std::shared_ptr<T>, void> | |||
{ using type = typename real_dataset_impl<T>::type; }; | |||
template<typename T> | |||
struct real_dataset_impl<std::vector<T>, void> | |||
{ using type = typename real_dataset_impl<T>::type; }; | |||
template<typename T> | |||
struct real_dataset_impl<std::list<T>, void> | |||
{ using type = typename real_dataset_impl<T>::type; }; | |||
template<typename T_from, typename T_to, typename = void> | |||
struct change_dataset_type_impl | |||
{ using type = T_to; }; | |||
template<template<typename...> class X, typename T_from, typename T_to> | |||
struct change_dataset_type_impl<X<T_from>, T_to, void> | |||
{ using type = X<T_to>; }; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_container | |||
: public __impl::is_container_impl<T> | |||
{ }; | |||
template<typename T> | |||
struct is_nullable | |||
: public __impl::is_nullable_impl<T> | |||
{ }; | |||
template<typename T> | |||
struct is_pointer | |||
: public __impl::is_pointer_impl<T> | |||
{ }; | |||
template<typename T> | |||
using real_dataset_t = typename __impl::real_dataset_impl<T>::type; | |||
} | |||
end_namespace_cpphibernate_misc |
@@ -0,0 +1,44 @@ | |||
#pragma once | |||
#include <list> | |||
#include <vector> | |||
#include <memory> | |||
#include <cpphibernate/config.h> | |||
#include <cpputils/container/nullable.h> | |||
beg_namespace_cpphibernate_misc | |||
{ | |||
template<typename T> | |||
using unwrap_t = typename T::type; | |||
template<typename T> | |||
using decay_unwrap_t = typename mp::decay_t<T>::type; | |||
namespace __impl | |||
{ | |||
struct wrap_t | |||
{ | |||
template<typename T> | |||
constexpr decltype(auto) operator()(T) const noexcept | |||
{ return hana::type_c<T>; } | |||
}; | |||
struct unwrapped_t | |||
{ | |||
template<typename T> | |||
constexpr decltype(auto) operator()(T) const noexcept | |||
{ return unwrap_t<T> { }; } | |||
}; | |||
} | |||
constexpr decltype(auto) wrap = __impl::wrap_t { }; | |||
constexpr decltype(auto) unwrap = __impl::unwrapped_t { }; | |||
} | |||
end_namespace_cpphibernate_misc |
@@ -0,0 +1,13 @@ | |||
#pragma once | |||
#include <cpphibernate/schema/attribute.h> | |||
#include <cpphibernate/schema/attributes.h> | |||
#include <cpphibernate/schema/field.h> | |||
#include <cpphibernate/schema/fields.h> | |||
#include <cpphibernate/schema/getter.h> | |||
#include <cpphibernate/schema/macros.h> | |||
#include <cpphibernate/schema/print.h> | |||
#include <cpphibernate/schema/schema.h> | |||
#include <cpphibernate/schema/setter.h> | |||
#include <cpphibernate/schema/table.h> | |||
#include <cpphibernate/schema/tables.h> |
@@ -0,0 +1,60 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
beg_namespace_cpphibernate_schema | |||
{ | |||
namespace __impl | |||
{ | |||
/* attribute_t */ | |||
template<typename T_inner> | |||
struct attribute_t | |||
: public T_inner | |||
{ | |||
using inner_type = T_inner; | |||
using this_type = attribute_t<inner_type>; | |||
cpphibernate_equality_comparable(); | |||
}; | |||
struct hex_t { static constexpr decltype(auto) name = "hex"; }; | |||
struct compress_t { static constexpr decltype(auto) name = "compress"; }; | |||
struct primary_key_t { static constexpr decltype(auto) name = "primary_key"; }; | |||
} | |||
namespace attribute | |||
{ | |||
using hex_type = __impl::attribute_t<__impl::hex_t>; | |||
using compress_type = __impl::attribute_t<__impl::compress_t>; | |||
using primary_key_type = __impl::attribute_t<__impl::primary_key_t>; | |||
/** value is stored as hexadecimal string, and will be converted to its binary form on read */ | |||
constexpr hex_type hex { }; | |||
/** value is stored as compressed binary, and will be uncompressed on read */ | |||
constexpr compress_type compress { }; | |||
/** this value represents a primary key (it must be stored in the dataset to be able to do the operations on the database) */ | |||
constexpr primary_key_type primary_key { }; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_attribute | |||
: public mp::is_specialization_of<T, __impl::attribute_t> | |||
{ }; | |||
template<typename... T> | |||
struct all_are_attribures | |||
: public mp::all_true<is_attribute<T>::value...> | |||
{ }; | |||
} | |||
end_namespace_cpphibernate_schema |
@@ -0,0 +1,63 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/misc.h> | |||
#include <cpphibernate/schema/attribute.h> | |||
beg_namespace_cpphibernate_schema | |||
{ | |||
namespace __impl | |||
{ | |||
/* attributes_t */ | |||
template<typename... T_attributes> | |||
using attributes_t = hana::basic_tuple<T_attributes...>; | |||
/* is_attributes_impl */ | |||
template<typename T, typename = void> | |||
struct is_attributes_impl | |||
: mp::c_false_t | |||
{ }; | |||
template<typename... T> | |||
struct is_attributes_impl<attributes_t<T...>, mp::enable_if<all_are_attribures<T...>>> | |||
: mp::c_true_t | |||
{ }; | |||
/* attributes_builder */ | |||
template<typename T, typename = void> | |||
struct attributes_builder | |||
{ | |||
template<typename... T_args> | |||
static constexpr decltype(auto) apply(T_args&&...) | |||
{ static_assert(sizeof...(T_args) == -1, "Invalid parameters for hibernate::schema::make_attributes(...)!"); } | |||
}; | |||
template<typename... T> | |||
struct attributes_builder<mp::list<T...>, mp::enable_if_c< | |||
all_are_attribures<mp::decay_t<T>...>::value>> | |||
{ | |||
template<typename... T_args> | |||
static constexpr decltype(auto) apply(T_args&&...) | |||
{ return attributes_t<mp::decay_t<T_args>...> { }; } | |||
}; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_attributes | |||
: public __impl::is_attributes_impl<T> | |||
{ }; | |||
/* make */ | |||
constexpr decltype(auto) make_attributes = misc::make_generic_predicate<__impl::attributes_builder> { }; | |||
} | |||
end_namespace_cpphibernate_schema |
@@ -0,0 +1,115 @@ | |||
#pragma once | |||
#include <cpphibernate/misc.h> | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/schema/getter.h> | |||
#include <cpphibernate/schema/setter.h> | |||
#include <cpputils/misc/indent.h> | |||
#include <cpputils/misc/type_helper.h> | |||
beg_namespace_cpphibernate_schema | |||
{ | |||
namespace __impl | |||
{ | |||
/* field_t */ | |||
template<typename T_name, typename T_getter, typename T_setter, typename T_attributes> | |||
struct field_t | |||
{ | |||
using name_type = T_name; | |||
using getter_type = T_getter; | |||
using setter_type = T_setter; | |||
using attributes_type = T_attributes; | |||
using this_type = field_t<name_type, getter_type, setter_type, attributes_type>; | |||
name_type name; | |||
getter_type getter; | |||
setter_type setter; | |||
attributes_type attributes; | |||
constexpr field_t( | |||
T_name&& p_name, | |||
T_getter&& p_getter, | |||
T_setter&& p_setter, | |||
T_attributes&& p_attributes) | |||
: name (std::forward<T_name> (p_name)) | |||
, getter (std::forward<T_getter> (p_getter)) | |||
, setter (std::forward<T_setter> (p_setter)) | |||
, attributes (std::forward<T_attributes>(p_attributes)) | |||
{ } | |||
cpphibernate_copyable(field_t, delete); | |||
cpphibernate_moveable(field_t, default); | |||
cpphibernate_equality_comparable(); | |||
inline void print(std::ostream& os) const | |||
{ | |||
using namespace ::utl; | |||
using value_type = typename mp::decay_t<getter_type>::value_type; | |||
using dataset_type = misc::real_dataset_t<value_type>; | |||
size_t index = 0; | |||
os << indent << '{' | |||
<< incindent | |||
<< indent << "\"name\": \"" << name << "\"," | |||
<< indent << "\"value_type\": \"" << utl::type_helper<value_type>::name() << "\"" | |||
<< indent << "\"dataset_type\": \"" << utl::type_helper<dataset_type>::name() << "\"" | |||
<< indent << "\"attributes\": " | |||
<< indent << '[' | |||
<< incindent; | |||
hana::for_each(attributes, [&](auto& attrib){ | |||
if (index++ > 0) os << ","; | |||
os << indent << attrib.name; | |||
}); | |||
os << decindent | |||
<< indent << ']' | |||
<< decindent | |||
<< indent << '}'; | |||
} | |||
}; | |||
/* field_builder */ | |||
template<typename X, typename = void> | |||
struct field_builder | |||
{ | |||
template <typename ...T_args> | |||
static constexpr decltype(auto) apply(T_args&&... args) | |||
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::make_field(...)!"); } | |||
}; | |||
template<typename T_name, typename T_getter, typename T_setter, typename T_attributes> | |||
struct field_builder<mp::list<T_name, T_getter, T_setter, T_attributes>, mp::enable_if_c< | |||
is_getter<mp::decay_t<T_getter>>::value | |||
&& is_setter<mp::decay_t<T_setter>>::value | |||
&& is_attributes<mp::decay_t<T_attributes>>::value>> | |||
{ | |||
using field_type = field_t<T_name, T_getter, T_setter, T_attributes>; | |||
static constexpr decltype(auto) apply(T_name&& name, T_getter&& getter, T_setter&& setter, T_attributes&& attributes) | |||
{ return field_type(std::forward<T_name>(name), std::forward<T_getter>(getter), std::forward<T_setter>(setter), std::forward<T_attributes>(attributes)); } | |||
}; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_field | |||
: public mp::is_specialization_of<T, __impl::field_t> | |||
{ }; | |||
template<typename... T> | |||
struct all_are_fields | |||
: public mp::all_true<is_field<T>::value...> | |||
{ }; | |||
/* make */ | |||
constexpr decltype(auto) make_field = misc::make_generic_predicate<__impl::field_builder> { }; | |||
} | |||
end_namespace_cpphibernate_schema |
@@ -0,0 +1,62 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/misc/general.h> | |||
#include <cpphibernate/schema/field.h> | |||
beg_namespace_cpphibernate_schema | |||
{ | |||
namespace __impl | |||
{ | |||
/* fields_t */ | |||
template<typename... T_fields> | |||
using fields_t = hana::basic_tuple<T_fields...>; | |||
/* is_fields_impl */ | |||
template<typename T, typename = void> | |||
struct is_fields_impl | |||
: public mp::c_false_t | |||
{ }; | |||
template<typename... T> | |||
struct is_fields_impl<fields_t<T...>, mp::enable_if<all_are_fields<T...>>> | |||
: public mp::c_true_t | |||
{ }; | |||
/* fields_builder */ | |||
template <typename T, typename = void> | |||
struct fields_builder | |||
{ | |||
template <typename ...T_args> | |||
static constexpr decltype(auto) apply(T_args&&... args) | |||
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::make_fields(...)!"); } | |||
}; | |||
template<typename... T> | |||
struct fields_builder<mp::list<T...>, mp::enable_if<all_are_fields<T...>>> | |||
{ | |||
template <typename ...T_args> | |||
static constexpr decltype(auto) apply(T_args&&... args) | |||
{ return fields_t<T_args...>(std::forward<T_args>(args)...); } | |||
}; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_fields : | |||
public __impl::is_fields_impl<T> | |||
{ }; | |||
/* constructors */ | |||
constexpr decltype(auto) make_fields = misc::make_generic_predicate<__impl::fields_builder> { }; | |||
} | |||
end_namespace_cpphibernate_schema |
@@ -0,0 +1,206 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/misc/general.h> | |||
beg_namespace_cpphibernate_schema | |||
{ | |||
namespace __impl | |||
{ | |||
/* getter_t */ | |||
template<typename T_value> | |||
struct getter_t | |||
{ | |||
using value_type = T_value; | |||
}; | |||
/* getter_none_t */ | |||
struct getter_none_t | |||
: public getter_t<void> | |||
{ | |||
using base_type = getter_t<void>; | |||
using value_type = typename base_type::value_type; | |||
cpphibernate_constructable(getter_none_t, default); | |||
cpphibernate_copyable (getter_none_t, delete); | |||
cpphibernate_moveable (getter_none_t, default); | |||
}; | |||
/* getter_member_var_t */ | |||
template<typename T_dataset, typename T_value, typename T_member> | |||
struct getter_member_var_t | |||
: public getter_t<T_value> | |||
{ | |||
using base_type = getter_t<T_value>; | |||
using value_type = typename base_type::value_type; | |||
using dataset_type = T_dataset; | |||
using member_type = T_member; | |||
member_type member; | |||
template<typename X_member> | |||
constexpr getter_member_var_t(X_member&& p_member) | |||
: member(std::forward<X_member>(p_member)) | |||
{ } | |||
cpphibernate_copyable(getter_member_var_t, delete); | |||
cpphibernate_moveable(getter_member_var_t, default); | |||
template<typename X_dataset> | |||
constexpr decltype(auto) operator()(X_dataset&& data) const | |||
{ return std::forward<X_dataset>(data).*member; } | |||
}; | |||
/* getter_member_func_t */ | |||
template<typename T_dataset, typename T_value, typename T_member> | |||
struct getter_member_func_t | |||
: public getter_t<T_value> | |||
{ | |||
using base_type = getter_t<T_value>; | |||
using value_type = typename base_type::value_type; | |||
using dataset_type = T_dataset; | |||
using member_type = T_member; | |||
member_type member; | |||
template<typename X_member> | |||
constexpr getter_member_func_t(X_member&& p_member) | |||
: member(std::forward<X_member>(p_member)) | |||
{ }; | |||
cpphibernate_copyable(getter_member_func_t, delete); | |||
cpphibernate_moveable(getter_member_func_t, default); | |||
template<typename X_dataset> | |||
constexpr decltype(auto) operator()(X_dataset&& data) const | |||
{ return (std::forward<X_dataset>(data).*member)(); } | |||
}; | |||
/* getter_lambda_t */ | |||
template<typename T_dataset, typename T_lambda> | |||
struct getter_lambda_t | |||
: public getter_t<decltype(std::declval<T_lambda>()(std::declval<T_dataset>()))> | |||
{ | |||
using base_type = getter_t<decltype(std::declval<T_lambda>()(std::declval<T_dataset>()))>; | |||
using value_type = typename base_type::value_type; | |||
using dataset_type = T_dataset; | |||
using lambda_type = T_lambda; | |||
lambda_type lambda; | |||
template<typename X_lambda> | |||
constexpr getter_lambda_t(X_lambda&& p_lambda) | |||
: lambda(std::forward<X_lambda>(p_lambda)) | |||
{ } | |||
cpphibernate_copyable(getter_lambda_t, delete); | |||
cpphibernate_moveable(getter_lambda_t, default); | |||
template<typename X_dataset> | |||
constexpr decltype(auto) operator()(X_dataset&& data) const | |||
{ return lambda(std::forward<X_dataset>(data)); } | |||
}; | |||
/* is_getter_impl */ | |||
template<typename T, typename = void> | |||
struct is_getter_impl | |||
: public mp::c_false_t | |||
{ }; | |||
template<typename T> | |||
struct is_getter_impl<T, mp::enable_if_c< | |||
mp::is_base_of<getter_t<typename T::value_type>, T>::value>> | |||
: public mp::c_true_t | |||
{ }; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_getter : | |||
public __impl::is_getter_impl<T> | |||
{ }; | |||
/* make */ | |||
constexpr decltype(auto) make_getter_none() | |||
{ return __impl::getter_none_t(); } | |||
template<typename T_dataset, typename T_value> | |||
constexpr decltype(auto) make_getter_member_var(T_value T_dataset::* member) | |||
{ return __impl::getter_member_var_t<T_dataset, T_value, T_value T_dataset::*>(member); } | |||
template<typename T_dataset, typename T_value> | |||
constexpr decltype(auto) make_getter_member_func(T_value (T_dataset::*member)()) | |||
{ return __impl::getter_member_func_t<T_dataset, T_value, T_value (T_dataset::*)()>(member); } | |||
template<typename T_dataset, typename T_value> | |||
constexpr decltype(auto) make_getter_member_func(T_value (T_dataset::*member)() const) | |||
{ return __impl::getter_member_func_t<const T_dataset, T_value, T_value (T_dataset::*)() const>(member); } | |||
template<typename T_dataset, typename T_lambda> | |||
constexpr decltype(auto) make_getter_lambda(T_lambda&& lambda, boost::hana::basic_type<T_dataset>) | |||
{ return __impl::getter_lambda_t<T_dataset, T_lambda>(std::forward<T_lambda>(lambda)); } | |||
namespace __impl | |||
{ | |||
/* getter_buildser */ | |||
template<typename X, typename = void> | |||
struct getter_builder | |||
{ | |||
template<typename... Args> | |||
static constexpr decltype(auto) apply(Args&&...) | |||
{ return make_getter_none(); } | |||
}; | |||
template<typename T_dataset, typename T_value> | |||
struct getter_builder<mp::list<T_value T_dataset::*>, void> | |||
{ | |||
static constexpr decltype(auto) apply(T_value T_dataset::*member) | |||
{ return make_getter_member_var(member); } | |||
}; | |||
template<typename T_dataset, typename T_value> | |||
struct getter_builder<mp::list<T_value (T_dataset::*)(void)>, void> | |||
{ | |||
static constexpr decltype(auto) apply(T_value (T_dataset::*member)(void)) | |||
{ return make_getter_member_func(member); } | |||
}; | |||
template<typename T_dataset, typename T_value> | |||
struct getter_builder<mp::list<T_value (T_dataset::*)(void) const>, void> | |||
{ | |||
static constexpr decltype(auto) apply(T_value (T_dataset::*member)(void) const) | |||
{ return make_getter_member_func(member); } | |||
}; | |||
template<typename T_func, typename T_dataset_type, typename T_value_type> | |||
struct getter_builder<mp::list<T_func, T_dataset_type, T_value_type>, mp::enable_if_c< | |||
hana::is_a<hana::type_tag, mp::decay_t<T_dataset_type>> | |||
&& hana::is_a<hana::type_tag, mp::decay_t<T_value_type>>>> | |||
{ | |||
static constexpr decltype(auto) apply(T_func&& func, T_dataset_type&& dataset_type, T_value_type&& value_type) | |||
{ return make_getter_lambda(std::forward<T_func>(func), std::forward<T_dataset_type>(dataset_type), std::forward<T_value_type>(value_type)); } | |||
}; | |||
} | |||
/* make */ | |||
constexpr decltype(auto) make_getter = misc::make_generic_predicate<__impl::getter_builder> { }; | |||
} | |||
end_namespace_cpphibernate_schema |
@@ -0,0 +1,43 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/types.h> | |||
#define cpphibernate_make_string(str) \ | |||
#str | |||
#define cpphibernate_make_schema(name, ...) \ | |||
cpphibernate::schema::make_schema( \ | |||
cpphibernate_make_string(name), \ | |||
cpphibernate::schema::make_tables(__VA_ARGS__)) | |||
#define cpphibernate_make_table_name(name, type, id, ...) \ | |||
cpphibernate::schema::make_table( \ | |||
cpphibernate_make_string(name), \ | |||
boost::hana::type_c<type>, \ | |||
boost::hana::size_c<id>, \ | |||
cpphibernate::schema::make_fields(__VA_ARGS__)) | |||
#define cpphibernate_make_table(name, id, ...) \ | |||
cpphibernate_make_table_name(name, name, id, __VA_ARGS__) | |||
#define cpphibernate_make_field_custom(name, getter, setter, ...) \ | |||
cpphibernate::schema::make_field( \ | |||
cpphibernate_make_string(name), \ | |||
cpphibernate::schema::make_getter(getter), \ | |||
cpphibernate::schema::make_setter(setter), \ | |||
cpphibernate::schema::make_attributes(__VA_ARGS__)) | |||
#define cpphibernate_make_field_name(name, member_ptr, ...) \ | |||
cpphibernate_make_field_custom( \ | |||
name, member_ptr, member_ptr, __VA_ARGS__) | |||
#define cpphibernate_make_field(type, member, ...) \ | |||
cpphibernate_make_field_name( \ | |||
member, &type::member, __VA_ARGS__) | |||
#define cpphibernate_make_id(member_ptr) \ | |||
cpphibernate_make_field_name( \ | |||
null, \ | |||
member_ptr, \ | |||
cpphibernate::schema::attribute::primary_key) |
@@ -0,0 +1,18 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
namespace std | |||
{ | |||
template<typename T_char, typename T_traits, typename X> | |||
inline auto operator <<(basic_ostream<T_char, T_traits>& os, X&& x) | |||
-> ::utl::mp::enable_if< | |||
utl::mp::is_valid<decltype(std::forward<X>(x).print(os))>, | |||
basic_ostream<T_char, T_traits>&> | |||
{ | |||
std::forward<X>(x).print(os); | |||
return os; | |||
} | |||
} |
@@ -0,0 +1,85 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/misc/general.h> | |||
#include <cpphibernate/schema/tables.h> | |||
beg_namespace_cpphibernate_schema | |||
{ | |||
namespace __impl | |||
{ | |||
/* schema_t */ | |||
template<typename T_name, typename T_tables> | |||
struct schema_t | |||
{ | |||
using name_type = T_name; | |||
using tables_type = T_tables; | |||
name_type name; | |||
tables_type tables; | |||
constexpr schema_t( | |||
T_name&& p_name, | |||
T_tables&& p_tables) | |||
: name (std::forward<T_name> (p_name)) | |||
, tables(std::forward<T_tables>(p_tables)) | |||
{ } | |||
cpphibernate_copyable(schema_t, delete); | |||
cpphibernate_moveable(schema_t, default); | |||
inline void print(std::ostream& os) const | |||
{ | |||
using namespace ::utl; | |||
size_t index = 0; | |||
os << indent << '{' | |||
<< incindent | |||
<< indent << "\"name\": \"" << name << "\"," | |||
<< indent << "\"tables\": " | |||
<< indent << '[' | |||
<< incindent; | |||
hana::for_each(tables, [&](auto& table){ | |||
if (index++ > 0) os << ","; | |||
table.print(os); | |||
}); | |||
os << decindent | |||
<< indent << ']' | |||
<< decindent | |||
<< indent << '}'; | |||
} | |||
}; | |||
/* schema_builder */ | |||
template <typename X, typename = void> | |||
struct schema_builder | |||
{ | |||
template <typename... T_args> | |||
static constexpr decltype(auto) apply(T_args&&... args) | |||
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::make_schema(...)!"); } | |||
}; | |||
template<typename T_name, typename T_tables> | |||
struct schema_builder<mp::list<T_name, T_tables>, mp::enable_if_c< | |||
is_tables<mp::clean_type<T_tables>>::value>> | |||
{ | |||
static constexpr decltype(auto) apply(T_name&& name, T_tables&& tables) | |||
{ return schema_t<T_name, T_tables>(std::forward<T_name>(name), std::forward<T_tables>(tables)); } | |||
}; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_schema : mp::is_specialization_of<T, __impl::schema_t> { }; | |||
/* make */ | |||
constexpr decltype(auto) make_schema = misc::make_generic_predicate<__impl::schema_builder> { }; | |||
} | |||
end_namespace_cpphibernate_schema |
@@ -0,0 +1,206 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/misc/general.h> | |||
beg_namespace_cpphibernate_schema | |||
{ | |||
namespace __impl | |||
{ | |||
/* setter_t */ | |||
template<typename T_value> | |||
struct setter_t | |||
{ | |||
using value_type = T_value; | |||
}; | |||
/* setter_none_t */ | |||
struct setter_none_t | |||
: public setter_t<void> | |||
{ | |||
using base_type = setter_t<void>; | |||
using value_type = typename base_type::value_type; | |||
cpphibernate_constructable(setter_none_t, default); | |||
cpphibernate_copyable (setter_none_t, delete); | |||
cpphibernate_moveable (setter_none_t, default); | |||
}; | |||
/* setter_member_var_t */ | |||
template<typename T_dataset, typename T_value, typename T_member> | |||
struct setter_member_var_t | |||
: public setter_t<T_value> | |||
{ | |||
using base_type = setter_t<T_value>; | |||
using value_type = typename base_type::value_type; | |||
using dataset_type = T_dataset; | |||
using member_type = T_member; | |||
member_type member; | |||
template<typename X_member> | |||
constexpr setter_member_var_t(X_member&& p_member) | |||
: member(std::forward<X_member>(p_member)) | |||
{ } | |||
cpphibernate_copyable(setter_member_var_t, delete); | |||
cpphibernate_moveable(setter_member_var_t, default); | |||
template<typename X_dataset, typename X_value> | |||
constexpr decltype(auto) operator()(X_dataset&& data, X_value&& value) const | |||
{ return std::forward<X_dataset>(data).*member = std::forward<X_value>(value); } | |||
}; | |||
/* setter_member_func_t */ | |||
template<typename T_dataset, typename T_value, typename T_member> | |||
struct setter_member_func_t | |||
: public setter_t<T_value> | |||
{ | |||
using base_type = setter_t<T_value>; | |||
using value_type = typename base_type::value_type; | |||
using dataset_type = T_dataset; | |||
using member_type = T_member; | |||
member_type member; | |||
template<typename X_member> | |||
constexpr setter_member_func_t(X_member&& p_member) | |||
: member(std::forward<X_member>(p_member)) | |||
{ }; | |||
cpphibernate_copyable(setter_member_func_t, delete); | |||
cpphibernate_moveable(setter_member_func_t, default); | |||
template<typename X_dataset, typename X_value> | |||
constexpr decltype(auto) operator()(X_dataset&& data, X_value&& value) const | |||
{ return (std::forward<X_dataset>(data).*member)(std::forward<X_value>(value)); } | |||
}; | |||
/* setter_lambda_t */ | |||
template<typename T_dataset, typename T_value, typename T_lambda> | |||
struct setter_lambda_t | |||
: public setter_t<T_value> | |||
{ | |||
using base_type = setter_t<T_value>; | |||
using value_type = typename base_type::value_type; | |||
using dataset_type = T_dataset; | |||
using lambda_type = T_lambda; | |||
lambda_type lambda; | |||
template<typename X_lambda> | |||
constexpr setter_lambda_t(X_lambda&& p_lambda) | |||
: lambda(std::forward<X_lambda>(p_lambda)) | |||
{ } | |||
cpphibernate_copyable(setter_lambda_t, delete); | |||
cpphibernate_moveable(setter_lambda_t, default); | |||
template<typename X_dataset, typename X_value> | |||
constexpr decltype(auto) operator()(X_dataset&& data, X_value&& value) const | |||
{ return lambda(std::forward<X_dataset>(data), std::forward<X_value>(value)); } | |||
}; | |||
/* is_setter_impl */ | |||
template<typename T, typename = void> | |||
struct is_setter_impl | |||
: public mp::c_false_t | |||
{ }; | |||
template<typename T> | |||
struct is_setter_impl<T, mp::enable_if_c< | |||
mp::is_base_of<setter_t<typename T::value_type>, T>::value>> | |||
: public mp::c_true_t | |||
{ }; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_setter : | |||
public __impl::is_setter_impl<T> | |||
{ }; | |||
/* make */ | |||
constexpr decltype(auto) make_setter_none() | |||
{ return __impl::setter_none_t(); } | |||
template<typename T_dataset, typename T_value> | |||
constexpr decltype(auto) make_setter_member_var(T_value T_dataset::* member) | |||
{ return __impl::setter_member_var_t<T_dataset, T_value, T_value T_dataset::*>(member); } | |||
template<typename T_dataset, typename T_value, typename T_return> | |||
constexpr decltype(auto) make_setter_member_func(T_return (T_dataset::*member)(T_value)) | |||
{ return __impl::setter_member_func_t<T_dataset, T_value, T_return (T_dataset::*)(T_value)>(member); } | |||
template<typename T_dataset, typename T_value, typename T_return> | |||
constexpr decltype(auto) make_setter_member_func(T_return (T_dataset::*member)(T_value) const) | |||
{ return __impl::setter_member_func_t<const T_dataset, T_value, T_return (T_dataset::*)(T_value) const>(member); } | |||
template<typename T_dataset, typename T_value, typename T_lambda> | |||
constexpr decltype(auto) make_setter_lambda(T_lambda&& lambda, boost::hana::basic_type<T_dataset>, boost::hana::basic_type<T_value>) | |||
{ return __impl::setter_lambda_t<T_dataset, T_value, T_lambda>(std::forward<T_lambda>(lambda)); } | |||
namespace __impl | |||
{ | |||
/* setter_buildser */ | |||
template<typename X, typename = void> | |||
struct setter_builder | |||
{ | |||
template<typename... Args> | |||
static constexpr decltype(auto) apply(Args&&...) | |||
{ return make_setter_none(); } | |||
}; | |||
template<typename T_dataset, typename T_value> | |||
struct setter_builder<mp::list<T_value T_dataset::*>, void> | |||
{ | |||
static constexpr decltype(auto) apply(T_value T_dataset::*member) | |||
{ return make_setter_member_var(member); } | |||
}; | |||
template<typename T_dataset, typename T_value> | |||
struct setter_builder<mp::list<T_value (T_dataset::*)(void)>, void> | |||
{ | |||
static constexpr decltype(auto) apply(T_value (T_dataset::*member)(void)) | |||
{ return make_setter_member_func(member); } | |||
}; | |||
template<typename T_dataset, typename T_value> | |||
struct setter_builder<mp::list<T_value (T_dataset::*)(void) const>, void> | |||
{ | |||
static constexpr decltype(auto) apply(T_value (T_dataset::*member)(void) const) | |||
{ return make_setter_member_func(member); } | |||
}; | |||
template<typename T_func, typename T_dataset_type, typename T_value_type> | |||
struct setter_builder<mp::list<T_func, T_dataset_type, T_value_type>, mp::enable_if_c< | |||
hana::is_a<hana::type_tag, mp::clean_type<T_dataset_type>> | |||
&& hana::is_a<hana::type_tag, mp::clean_type<T_value_type>>>> | |||
{ | |||
static constexpr decltype(auto) apply(T_func&& func, T_dataset_type&& dataset_type, T_value_type&& value_type) | |||
{ return make_setter_lambda(std::forward<T_func>(func), std::forward<T_dataset_type>(dataset_type), std::forward<T_value_type>(value_type)); } | |||
}; | |||
} | |||
/* make */ | |||
constexpr decltype(auto) make_setter = misc::make_generic_predicate<__impl::setter_builder> { }; | |||
} | |||
end_namespace_cpphibernate_schema |
@@ -0,0 +1,109 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/misc/wrap.h> | |||
#include <cpphibernate/misc/general.h> | |||
#include <cpphibernate/schema/fields.h> | |||
beg_namespace_cpphibernate_schema | |||
{ | |||
namespace __impl | |||
{ | |||
/* table_t */ | |||
template<typename T_name, typename T_dataset_wrapped, typename T_table_id, typename T_fields> | |||
struct table_t | |||
{ | |||
using name_type = T_name; | |||
using dataset_wrapped_type = mp::decay_t<T_dataset_wrapped>; | |||
using table_id_type = T_table_id; | |||
using fields_type = T_fields; | |||
using this_type = table_t<name_type, dataset_wrapped_type, table_id_type, fields_type>; | |||
name_type name; | |||
dataset_wrapped_type dataset_wrapped; | |||
table_id_type table_id; | |||
fields_type fields; | |||
constexpr table_t( | |||
T_name p_name, | |||
T_dataset_wrapped p_dataset_wrapped, | |||
T_table_id p_table_id, | |||
T_fields p_fields) | |||
: name (std::forward<T_name> (p_name)) | |||
, dataset_wrapped (std::forward<T_dataset_wrapped>(p_dataset_wrapped)) | |||
, table_id (std::forward<T_table_id> (p_table_id)) | |||
, fields (std::forward<T_fields> (p_fields)) | |||
{ } | |||
cpphibernate_copyable(table_t, delete); | |||
cpphibernate_moveable(table_t, default); | |||
cpphibernate_equality_comparable(); | |||
inline void print(std::ostream& os) const | |||
{ | |||
using namespace ::utl; | |||
size_t index = 0; | |||
os << indent << '{' | |||
<< incindent | |||
<< indent << "\"name\": \"" << name << "\"," | |||
<< indent << "\"dataset_wrapped\": \"" << utl::type_helper<misc::decay_unwrap_t<dataset_wrapped_type>>::name() << "\"" | |||
<< indent << "\"table_id\": \"" << hana::value(table_id) << "\"" | |||
<< indent << "\"fields\": " | |||
<< indent << '[' | |||
<< incindent; | |||
hana::for_each(fields, [&](auto& field){ | |||
if (index++ > 0) os << ","; | |||
field.print(os); | |||
}); | |||
os << decindent | |||
<< indent << ']' | |||
<< decindent | |||
<< indent << '}'; | |||
} | |||
}; | |||
/* table_builder */ | |||
template <typename X, typename = void> | |||
struct table_builder | |||
{ | |||
template <typename... T_args> | |||
static constexpr decltype(auto) apply(T_args&&... args) | |||
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::make_table(...)!"); } | |||
}; | |||
template<typename T_name, typename T_dataset_wrapped, typename T_id, typename T_fields> | |||
struct table_builder<mp::list<T_name, T_dataset_wrapped, T_id, T_fields>, mp::enable_if_c< | |||
hana::is_a<hana::type_tag, T_dataset_wrapped> | |||
&& is_fields<mp::decay_t<T_fields>>::value>> | |||
{ | |||
static constexpr decltype(auto) apply(T_name&& name, T_dataset_wrapped&& dataset_wrapped, T_id&& id, T_fields&& fields) | |||
{ | |||
return table_t<T_name, T_dataset_wrapped, T_id, T_fields>( | |||
std::forward<T_name> (name), | |||
std::forward<T_dataset_wrapped> (dataset_wrapped), | |||
std::forward<T_id> (id), | |||
std::forward<T_fields> (fields)); | |||
} | |||
}; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_table : mp::is_specialization_of<T, __impl::table_t> { }; | |||
template<typename... T> | |||
struct all_are_tables : mp::all_true<is_table<T>::value...> { }; | |||
/* make */ | |||
constexpr decltype(auto) make_table = misc::make_generic_predicate<__impl::table_builder> { }; | |||
} | |||
end_namespace_cpphibernate_schema |
@@ -0,0 +1,62 @@ | |||
#pragma once | |||
#include <cpphibernate/config.h> | |||
#include <cpphibernate/misc/general.h> | |||
#include <cpphibernate/schema/table.h> | |||
beg_namespace_cpphibernate_schema | |||
{ | |||
namespace __impl | |||
{ | |||
/* tables_t */ | |||
template<typename... T_table> | |||
using tables_t = hana::tuple<T_table...>; | |||
/* is_tables_impl */ | |||
template<typename T, typename = void> | |||
struct is_tables_impl | |||
: mp::c_false_t | |||
{ }; | |||
template<typename... T> | |||
struct is_tables_impl<tables_t<T...>, mp::enable_if<all_are_tables<T...>>> | |||
: mp::c_true_t | |||
{ }; | |||
/* tables_builder */ | |||
template <typename X, typename = void> | |||
struct tables_builder | |||
{ | |||
template <typename... T_args> | |||
static constexpr decltype(auto) apply(T_args&&... args) | |||
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::make_tables(...)!"); } | |||
}; | |||
template<typename... T> | |||
struct tables_builder<mp::list<T...>, mp::enable_if<all_are_tables<T...>>> | |||
{ | |||
template <typename ...T_tables> | |||
static constexpr decltype(auto) apply(T_tables&&... tables) | |||
{ return tables_t<T_tables...>(std::forward<T_tables>(tables)...); } | |||
}; | |||
} | |||
/* meta */ | |||
template<typename T> | |||
struct is_tables | |||
: public __impl::is_tables_impl<T> | |||
{ }; | |||
/* make */ | |||
constexpr decltype(auto) make_tables = misc::make_generic_predicate<__impl::tables_builder> { }; | |||
} | |||
end_namespace_cpphibernate_schema |
@@ -0,0 +1,51 @@ | |||
#pragma once | |||
#include <string> | |||
#include <iostream> | |||
#include <cpphibernate/config.h> | |||
#include <cpputils/misc/exception.h> | |||
beg_namespace_cpphibernate | |||
{ | |||
/* string */ | |||
template<size_t N> | |||
struct string | |||
: public std::string | |||
{ | |||
static constexpr decltype(auto) max_size = N; | |||
using std::string::string; | |||
using std::string::operator=; | |||
}; | |||
/* uuid */ | |||
struct uuid | |||
: public std::array<uint8_t, 16> | |||
{ | |||
public: | |||
inline uuid() | |||
: std::array<uint8_t, 16>::array({ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }) | |||
{ } | |||
inline uuid(const std::string& str) | |||
: std::array<uint8_t, 16>::array({ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }) | |||
{ | |||
if (!from_string(str, *this)) | |||
throw utl::argument_exception("str", "invalid uuid"); | |||
} | |||
cpphibernate_copyable(uuid, default); | |||
cpphibernate_moveable(uuid, default); | |||
void to_string(std::ostream& os) const; | |||
public: | |||
static bool from_string(const std::string& str, uuid& val); | |||
}; | |||
} | |||
end_namespace_cpphibernate |
@@ -11,6 +11,10 @@ Set ( CMAKE_CXX_STANDARD 17 ) | |||
Set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PEDANTIC_C_FLAGS}" ) | |||
Set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PEDANTIC_CXX_FLAGS}" ) | |||
# Dependencies #################################################################################### | |||
Find_Package ( cpputils REQUIRED ) | |||
# Project: cpphibernate ############################################################################### | |||
Project ( cpphibernate VERSION 1.0.0.0 LANGUAGES CXX ) | |||
@@ -20,6 +24,10 @@ Target_Include_Directories ( | |||
cpphibernate | |||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include | |||
) | |||
Target_Link_Libraries ( | |||
cpphibernate | |||
cpputils | |||
) | |||
If ( __COTIRE_INCLUDED ) | |||
Cotire ( cpphibernate ) | |||
EndIf ( ) | |||
@@ -0,0 +1,54 @@ | |||
#include <iomanip> | |||
#include <cpphibernate/types.h> | |||
using namespace ::cpphibernate;; | |||
void uuid::to_string(std::ostream& os) const | |||
{ | |||
os << std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 0] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 1] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 2] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 3] | |||
<< '-' | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 4] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 5] | |||
<< '-' | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 6] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 7] | |||
<< '-' | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 8] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[ 9] | |||
<< '-' | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[10] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[11] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[12] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[13] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[14] | |||
<< std::setw(2) << std::setfill('0') << std::hex << (int)(*this)[15]; | |||
} | |||
bool uuid::from_string(const std::string& str, uuid& val) | |||
{ | |||
const char* c = str.data(); | |||
const char* e = c + str.size(); | |||
size_t i = 0; | |||
val.fill(0); | |||
while(i < 32 && c < e) | |||
{ | |||
if (*c >= '0' && *c <= '9') | |||
val[i >> 1] |= ((*c - '0') << (4 * (1 - (i & 1)))); | |||
else if (*c >= 'a' && *c <= 'f') | |||
val[i >> 1] |= ((*c - 'a' + 10) << (4 * (1 - (i & 1)))); | |||
else if (*c >= 'A' && *c <= 'F') | |||
val[i >> 1] |= ((*c - 'A' + 10) << (4 * (1 - (i & 1)))); | |||
else if (*c != '-') | |||
return false; | |||
if (*c != '-') | |||
++i; | |||
++c; | |||
} | |||
if (i != 32 || c != e) | |||
return false; | |||
return true; | |||
} |
@@ -0,0 +1,128 @@ | |||
#include <gtest/gtest.h> | |||
#include <cpphibernate.h> | |||
using namespace ::cpphibernate; | |||
struct test1 | |||
{ | |||
uuid id; | |||
std::string str_data; | |||
string<64> str64_data; | |||
}; | |||
struct test2 | |||
{ | |||
uuid id; | |||
uint8_t u8_data; | |||
int8_t i8_data; | |||
uint16_t u16_data; | |||
int16_t i16_data; | |||
}; | |||
struct test3 | |||
{ | |||
uuid id; | |||
uint32_t u32_data; | |||
int32_t i32_data; | |||
uint64_t u64_data; | |||
int64_t i64_data; | |||
}; | |||
struct base | |||
{ | |||
uuid id; | |||
std::string name; | |||
}; | |||
struct derived1 | |||
: public base | |||
{ | |||
uuid derived1_id; | |||
test1 test1_data; | |||
}; | |||
struct derived2 | |||
: public base | |||
{ | |||
uuid derived2_id; | |||
utl::nullable<test2> test2_nullable; | |||
std::unique_ptr<test2> test2_ptr_u; | |||
std::shared_ptr<test2> test2_ptr_s; | |||
}; | |||
struct derived3 | |||
: public derived1 | |||
{ | |||
uuid derived3_id; | |||
std::list<test3> test3_list; | |||
std::vector<test3> test3_vector; | |||
}; | |||
constexpr decltype(auto) test_schema = cpphibernate_make_schema( | |||
test, | |||
cpphibernate_make_table_name( | |||
tbl_test1, | |||
test1, | |||
1, | |||
cpphibernate_make_id (&test1::id), | |||
cpphibernate_make_field (test1, str_data), | |||
cpphibernate_make_field (test1, str64_data) | |||
), | |||
cpphibernate_make_table_name( | |||
tbl_test2, | |||
test2, | |||
2, | |||
cpphibernate_make_id (&test2::id), | |||
cpphibernate_make_field (test2, u8_data), | |||
cpphibernate_make_field (test2, i8_data), | |||
cpphibernate_make_field (test2, u16_data), | |||
cpphibernate_make_field (test2, i16_data) | |||
), | |||
cpphibernate_make_table_name( | |||
tbl_test3, | |||
test3, | |||
3, | |||
cpphibernate_make_id (&test3::id), | |||
cpphibernate_make_field (test3, u32_data), | |||
cpphibernate_make_field (test3, i32_data), | |||
cpphibernate_make_field (test3, u64_data), | |||
cpphibernate_make_field (test3, i64_data) | |||
), | |||
cpphibernate_make_table_name( | |||
tbl_base, | |||
base, | |||
10, | |||
cpphibernate_make_id (&base::id), | |||
cpphibernate_make_field (base, name) | |||
), | |||
cpphibernate_make_table_name( | |||
tbl_derived1, | |||
derived1, | |||
11, | |||
cpphibernate_make_id (&derived1::derived1_id), | |||
cpphibernate_make_field (derived1, test1_data) | |||
), | |||
cpphibernate_make_table_name( | |||
tbl_derived2, | |||
derived2, | |||
12, | |||
cpphibernate_make_id (&derived2::derived2_id), | |||
cpphibernate_make_field (derived2, test2_nullable), | |||
cpphibernate_make_field (derived2, test2_ptr_u), | |||
cpphibernate_make_field (derived2, test2_ptr_s) | |||
), | |||
cpphibernate_make_table_name( | |||
tbl_derived3, | |||
derived3, | |||
13, | |||
cpphibernate_make_id (&derived3::derived3_id), | |||
cpphibernate_make_field (derived3, test3_list), | |||
cpphibernate_make_field (derived3, test3_vector) | |||
) | |||
); | |||
TEST(CppHibernateTests, fuuu) | |||
{ | |||
std::cout << test_schema << std::endl; | |||
} |