|
- #pragma once
-
- #include <cppmp/core/modifier.h>
- #include <cppmp/traits/lambda_traits.h>
-
- #include "getter.h"
-
- namespace cppmp
- {
-
- namespace __impl
- {
-
- /* tag_getter */
-
- struct tag_getter
- { };
-
- /* getter_builder - default */
-
- template<typename X, typename>
- struct getter_builder
- {
- template<typename... T_args>
- static constexpr decltype(auto) apply(T_args&&...)
- { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_getter(...)!"); }
- };
-
- /* getter_builder - redirect existing getter */
-
- template<typename T_getter>
- struct getter_builder<
- list<T_getter>,
- enable_if_t<is_getter_v<decay_t<T_getter>>>>
- {
- static constexpr decltype(auto) apply(T_getter&& getter)
- { return std::forward<T_getter>(getter); }
- };
-
- /* getter_builder - member variable */
-
- template<typename T_object, typename T_value>
- struct getter_builder<
- list<T_value T_object::*>,
- void>
- {
- struct getter_member_var
- : public tag_getter
- {
- using object_type = T_object;
- using value_type = T_value;
- using member_type = value_type object_type::*;
-
- member_type member;
-
- constexpr getter_member_var(member_type p_member)
- : member(p_member)
- { }
-
- constexpr getter_member_var(getter_member_var&&) = default;
- constexpr getter_member_var(const getter_member_var&) = default;
-
- constexpr getter_member_var& operator = (getter_member_var&&) = default;
- constexpr getter_member_var& operator = (const getter_member_var&) = default;
-
- template<typename X_object>
- constexpr decltype(auto) operator()(X_object&& obj) const
- { return std::forward<X_object>(obj).*member; }
- };
-
- using object_type = T_object;
- using value_type = T_value;
- using member_type = value_type object_type::*;
-
- static constexpr decltype(auto) apply(member_type&& getter)
- { return getter_member_var(std::forward<member_type>(getter)); }
- };
-
- /* getter_builder - member function */
-
- template<typename T_object, typename T_value, typename T_member>
- struct getter_builder_member_func
- {
- struct getter_member_func
- : public tag_getter
- {
- using object_type = T_object;
- using value_type = T_value;
- using member_type = T_member;
-
- member_type member;
-
- constexpr getter_member_func(member_type p_member)
- : member(p_member)
- { }
-
- constexpr getter_member_func(getter_member_func&&) = default;
- constexpr getter_member_func(const getter_member_func&) = default;
-
- constexpr getter_member_func& operator = (getter_member_func&&) = default;
- constexpr getter_member_func& operator = (const getter_member_func&) = default;
-
- template<typename X_object>
- constexpr decltype(auto) operator()(X_object&& obj) const
- { return (std::forward<X_object>(obj).*member)(); }
- };
-
- using object_type = T_object;
- using value_type = T_value;
- using member_type = T_member;
-
- static constexpr decltype(auto) apply(member_type&& getter)
- { return getter_member_func(std::forward<member_type>(getter)); }
- };
-
- template<typename T_object, typename T_value>
- struct getter_builder<
- list<T_value (T_object::*)()>,
- void>
- : public getter_builder_member_func<T_object, T_value, T_value (T_object::*)()>
- { };
-
- template<typename T_object, typename T_value>
- struct getter_builder<
- list<T_value (T_object::*)() const>,
- void>
- : public getter_builder_member_func<T_object, T_value, T_value (T_object::*)() const>
- { };
-
- /* getter_builder - lambda/static */
-
- template<typename T_lambda>
- struct getter_builder<
- list<T_lambda>,
- enable_if_t<
- is_valid_v<lambda_traits<decay_t<T_lambda>>>
- && lambda_traits<decay_t<T_lambda>>::argument_count_v == 1
- && !is_void_v<typename lambda_traits<decay_t<T_lambda>>::return_type>>>
- {
- struct getter_lambda
- : public tag_getter
- {
- using lambda_type = T_lambda;
- using lambda_traits_type = lambda_traits<lambda_type>;
- using object_type = decay_t<typename lambda_traits_type::template argument_t<0>>;
- using value_type = decay_t<typename lambda_traits_type::return_type>;
-
- lambda_type lambda;
-
- constexpr getter_lambda(lambda_type&& p_lambda)
- : lambda(std::forward<lambda_type>(p_lambda))
- { }
-
- constexpr getter_lambda(getter_lambda&&) = default;
- constexpr getter_lambda(const getter_lambda&) = default;
-
- constexpr getter_lambda& operator = (getter_lambda&&) = default;
- constexpr getter_lambda& operator = (const getter_lambda&) = default;
-
- template<typename X_object>
- constexpr decltype(auto) operator()(X_object&& obj) const
- { return lambda(std::forward<X_object>(obj)); }
- };
-
- using lambda_type = T_lambda;
-
- static constexpr decltype(auto) apply(lambda_type&& lambda)
- { return getter_lambda(std::forward<lambda_type>(lambda)); }
- };
-
- }
-
- /* is_getter */
-
- template<typename T>
- struct is_getter
- : public is_base_of<__impl::tag_getter, T>
- { };
-
- }
|