Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

181 строка
6.0 KiB

  1. #pragma once
  2. #include <cppmp/core/modifier.h>
  3. #include <cppmp/traits/lambda_traits.h>
  4. #include "getter.h"
  5. namespace cppmp
  6. {
  7. namespace __impl
  8. {
  9. /* tag_getter */
  10. struct tag_getter
  11. { };
  12. /* getter_builder - default */
  13. template<typename X, typename>
  14. struct getter_builder
  15. {
  16. template<typename... T_args>
  17. static constexpr decltype(auto) apply(T_args&&...)
  18. { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_getter(...)!"); }
  19. };
  20. /* getter_builder - redirect existing getter */
  21. template<typename T_getter>
  22. struct getter_builder<
  23. list<T_getter>,
  24. enable_if_t<is_getter_v<decay_t<T_getter>>>>
  25. {
  26. static constexpr decltype(auto) apply(T_getter&& getter)
  27. { return std::forward<T_getter>(getter); }
  28. };
  29. /* getter_builder - member variable */
  30. template<typename T_object, typename T_value>
  31. struct getter_builder<
  32. list<T_value T_object::*>,
  33. void>
  34. {
  35. struct getter_member_var
  36. : public tag_getter
  37. {
  38. using object_type = T_object;
  39. using value_type = T_value;
  40. using member_type = value_type object_type::*;
  41. member_type member;
  42. constexpr getter_member_var(member_type p_member)
  43. : member(p_member)
  44. { }
  45. constexpr getter_member_var(getter_member_var&&) = default;
  46. constexpr getter_member_var(const getter_member_var&) = default;
  47. constexpr getter_member_var& operator = (getter_member_var&&) = default;
  48. constexpr getter_member_var& operator = (const getter_member_var&) = default;
  49. template<typename X_object>
  50. constexpr decltype(auto) operator()(X_object&& obj) const
  51. { return std::forward<X_object>(obj).*member; }
  52. };
  53. using object_type = T_object;
  54. using value_type = T_value;
  55. using member_type = value_type object_type::*;
  56. static constexpr decltype(auto) apply(member_type&& getter)
  57. { return getter_member_var(std::forward<member_type>(getter)); }
  58. };
  59. /* getter_builder - member function */
  60. template<typename T_object, typename T_value, typename T_member>
  61. struct getter_builder_member_func
  62. {
  63. struct getter_member_func
  64. : public tag_getter
  65. {
  66. using object_type = T_object;
  67. using value_type = T_value;
  68. using member_type = T_member;
  69. member_type member;
  70. constexpr getter_member_func(member_type p_member)
  71. : member(p_member)
  72. { }
  73. constexpr getter_member_func(getter_member_func&&) = default;
  74. constexpr getter_member_func(const getter_member_func&) = default;
  75. constexpr getter_member_func& operator = (getter_member_func&&) = default;
  76. constexpr getter_member_func& operator = (const getter_member_func&) = default;
  77. template<typename X_object>
  78. constexpr decltype(auto) operator()(X_object&& obj) const
  79. { return (std::forward<X_object>(obj).*member)(); }
  80. };
  81. using object_type = T_object;
  82. using value_type = T_value;
  83. using member_type = T_member;
  84. static constexpr decltype(auto) apply(member_type&& getter)
  85. { return getter_member_func(std::forward<member_type>(getter)); }
  86. };
  87. template<typename T_object, typename T_value>
  88. struct getter_builder<
  89. list<T_value (T_object::*)()>,
  90. void>
  91. : public getter_builder_member_func<T_object, T_value, T_value (T_object::*)()>
  92. { };
  93. template<typename T_object, typename T_value>
  94. struct getter_builder<
  95. list<T_value (T_object::*)() const>,
  96. void>
  97. : public getter_builder_member_func<T_object, T_value, T_value (T_object::*)() const>
  98. { };
  99. /* getter_builder - lambda/static */
  100. template<typename T_lambda>
  101. struct getter_builder<
  102. list<T_lambda>,
  103. enable_if_t<
  104. is_valid_v<lambda_traits<decay_t<T_lambda>>>
  105. && lambda_traits<decay_t<T_lambda>>::argument_count_v == 1
  106. && !is_void_v<typename lambda_traits<decay_t<T_lambda>>::return_type>>>
  107. {
  108. struct getter_lambda
  109. : public tag_getter
  110. {
  111. using lambda_type = T_lambda;
  112. using lambda_traits_type = lambda_traits<lambda_type>;
  113. using object_type = decay_t<typename lambda_traits_type::template argument_t<0>>;
  114. using value_type = decay_t<typename lambda_traits_type::return_type>;
  115. lambda_type lambda;
  116. constexpr getter_lambda(lambda_type&& p_lambda)
  117. : lambda(std::forward<lambda_type>(p_lambda))
  118. { }
  119. constexpr getter_lambda(getter_lambda&&) = default;
  120. constexpr getter_lambda(const getter_lambda&) = default;
  121. constexpr getter_lambda& operator = (getter_lambda&&) = default;
  122. constexpr getter_lambda& operator = (const getter_lambda&) = default;
  123. template<typename X_object>
  124. constexpr decltype(auto) operator()(X_object&& obj) const
  125. { return lambda(std::forward<X_object>(obj)); }
  126. };
  127. using lambda_type = T_lambda;
  128. static constexpr decltype(auto) apply(lambda_type&& lambda)
  129. { return getter_lambda(std::forward<lambda_type>(lambda)); }
  130. };
  131. }
  132. /* is_getter */
  133. template<typename T>
  134. struct is_getter
  135. : public is_base_of<__impl::tag_getter, T>
  136. { };
  137. }