Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

192 righe
6.5 KiB

  1. #pragma once
  2. #include <cpphibernate/config.h>
  3. #include <cpphibernate/misc/general.h>
  4. beg_namespace_cpphibernate_schema
  5. {
  6. namespace __impl
  7. {
  8. /* getter_t */
  9. template<typename T_dataset, typename T_value>
  10. struct getter_t
  11. {
  12. using dataset_type = T_dataset;
  13. using value_type = T_value;
  14. };
  15. /* getter_member_var_t */
  16. template<typename T_dataset, typename T_value, typename T_member>
  17. struct getter_member_var_t
  18. : public getter_t<T_dataset, T_value>
  19. {
  20. using base_type = getter_t<T_dataset, T_value>;
  21. using dataset_type = typename base_type::dataset_type;
  22. using value_type = typename base_type::value_type;
  23. using member_type = T_member;
  24. member_type member;
  25. template<typename X_member>
  26. constexpr getter_member_var_t(X_member&& p_member)
  27. : member(std::forward<X_member>(p_member))
  28. { }
  29. cpphibernate_copyable(getter_member_var_t, delete);
  30. cpphibernate_moveable(getter_member_var_t, default);
  31. template<typename X_dataset>
  32. constexpr decltype(auto) operator()(X_dataset&& data) const
  33. { return std::forward<X_dataset>(data).*member; }
  34. };
  35. /* getter_member_func_t */
  36. template<typename T_dataset, typename T_value, typename T_member>
  37. struct getter_member_func_t
  38. : public getter_t<T_dataset, T_value>
  39. {
  40. using base_type = getter_t<T_dataset, T_value>;
  41. using dataset_type = typename base_type::dataset_type;
  42. using value_type = typename base_type::value_type;
  43. using member_type = T_member;
  44. member_type member;
  45. template<typename X_member>
  46. constexpr getter_member_func_t(X_member&& p_member)
  47. : member(std::forward<X_member>(p_member))
  48. { };
  49. cpphibernate_copyable(getter_member_func_t, delete);
  50. cpphibernate_moveable(getter_member_func_t, default);
  51. template<typename X_dataset>
  52. constexpr decltype(auto) operator()(X_dataset&& data) const
  53. { return (std::forward<X_dataset>(data).*member)(); }
  54. };
  55. /* getter_lambda_t */
  56. template<typename T_lambda, typename T_dataset, typename T_value>
  57. struct getter_lambda_t
  58. : public getter_t<T_dataset, T_value>
  59. {
  60. using base_type = getter_t<T_dataset, T_value>;
  61. using dataset_type = typename base_type::dataset_type;
  62. using value_type = typename base_type::value_type;
  63. using lambda_type = T_lambda;
  64. lambda_type lambda;
  65. template<typename X_lambda>
  66. constexpr getter_lambda_t(X_lambda&& p_lambda)
  67. : lambda(std::forward<X_lambda>(p_lambda))
  68. { }
  69. cpphibernate_copyable(getter_lambda_t, delete);
  70. cpphibernate_moveable(getter_lambda_t, default);
  71. template<typename X_dataset>
  72. constexpr decltype(auto) operator()(X_dataset&& data) const
  73. { return lambda(std::forward<X_dataset>(data)); }
  74. };
  75. /* is_getter_impl */
  76. template<typename T, typename = void>
  77. struct is_getter_impl
  78. : public mp::c_false_t
  79. { };
  80. template<typename T>
  81. struct is_getter_impl<T, mp::enable_if<
  82. mp::is_base_of<getter_t<typename T::dataset_type, typename T::value_type>, T>>>
  83. : public mp::c_true_t
  84. { };
  85. }
  86. /* meta */
  87. template<typename T>
  88. struct is_getter :
  89. public __impl::is_getter_impl<T>
  90. { };
  91. /* make */
  92. template<typename T_dataset, typename T_value>
  93. constexpr decltype(auto) make_getter_member_var(T_value T_dataset::* member)
  94. {
  95. using getter_type = __impl::getter_member_var_t<T_dataset, T_value, T_value T_dataset::*>;
  96. return getter_type(member);
  97. }
  98. template<typename T_dataset, typename T_value>
  99. constexpr decltype(auto) make_getter_member_func(T_value (T_dataset::*member)())
  100. {
  101. using getter_type = __impl::getter_member_func_t<T_dataset, T_value, T_value (T_dataset::*)()>;
  102. return getter_type(member);
  103. }
  104. template<typename T_dataset, typename T_value>
  105. constexpr decltype(auto) make_getter_member_func(T_value (T_dataset::*member)() const)
  106. {
  107. using getter_type = __impl::getter_member_func_t<const T_dataset, T_value, T_value (T_dataset::*)() const>;
  108. return getter_type(member);
  109. }
  110. template<typename T_lambda, typename T_wrapped_dataset, typename T_wrapped_value>
  111. constexpr decltype(auto) make_getter_lambda(T_lambda&& lambda, T_wrapped_dataset&&, T_wrapped_value&&)
  112. {
  113. using getter_type = __impl::getter_lambda_t<T_lambda, misc::decay_unwrap_t<T_wrapped_dataset>, misc::decay_unwrap_t<T_wrapped_value>>;
  114. return getter_type(std::forward<T_lambda>(lambda));
  115. }
  116. /* operations */
  117. namespace __impl
  118. {
  119. /* getter_make_impl */
  120. struct getter_make_impl
  121. {
  122. template<typename T_dataset, typename T_value>
  123. constexpr decltype(auto) operator()(T_value T_dataset::*member) const
  124. { return make_getter_member_var(member); }
  125. template<typename T_dataset, typename T_value>
  126. constexpr decltype(auto) operator()(T_value (T_dataset::*member)(void)) const
  127. { return make_getter_member_func(member); }
  128. template<typename T_dataset, typename T_value>
  129. constexpr decltype(auto) operator()(T_value (T_dataset::*member)(void) const) const
  130. { return make_getter_member_func(member); }
  131. template<typename T_func, typename T_dataset, typename T_value>
  132. constexpr decltype(auto) operator()(T_func&& func, hana::type<T_dataset>&& wrapped_dataset, hana::type<T_value>&& wrapped_value) const
  133. { return make_getter_lambda(std::forward<T_func>(func), std::forward<hana::type<T_dataset>>(wrapped_dataset), std::forward<hana::type<T_value>>(wrapped_value)); }
  134. template<typename T_getter>
  135. constexpr auto operator()(T_getter&& getter) const
  136. -> mp::enable_if<is_getter<T_getter>, T_getter>
  137. { return std::forward<T_getter>(getter); }
  138. };
  139. }
  140. namespace getter
  141. {
  142. constexpr decltype(auto) make = __impl::getter_make_impl { };
  143. }
  144. }
  145. end_namespace_cpphibernate_schema