|
- #pragma once
-
- #include <cppmp/traits/lambda_traits.h>
-
- #include "setter.h"
-
- namespace cppmp
- {
-
- namespace __impl
- {
-
- /* setter_builder - default */
-
- template<typename X, typename>
- struct setter_builder
- {
- using is_default = cppmp::true_t;
-
- template<typename... T_args>
- static constexpr decltype(auto) apply(T_args&&...)
- { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_setter(...)!"); }
- };
-
- /* setter_builder - redirect existing setter */
-
- template<typename T_setter>
- struct setter_builder<
- list<T_setter>,
- enable_if_t<is_setter<decay_t<T_setter>>::value
- >>
- {
- static constexpr decltype(auto) apply(T_setter&& setter)
- { return std::forward<T_setter>(setter); }
- };
-
- /* setter_builder - member variable */
-
- template<typename T_object, typename T_value>
- struct setter_builder<
- list<T_value T_object::*>,
- void>
- {
- struct setter_member_var
- : public tag_setter
- , public tag_setter_member_var
- {
- using object_type = T_object;
- using value_type = T_value;
- using member_type = value_type object_type::*;
-
- member_type member;
-
- inline setter_member_var(member_type p_member)
- : member(p_member)
- { }
-
- inline setter_member_var(setter_member_var&&) = default;
- inline setter_member_var(const setter_member_var&) = default;
-
- inline setter_member_var& operator = (setter_member_var&&) = default;
- inline setter_member_var& operator = (const setter_member_var&) = default;
-
- template<typename X_object, typename X_value>
- constexpr void operator()(X_object&& obj, X_value&& value) const
- { std::forward<X_object>(obj).*member = value; }
- };
-
- using object_type = T_object;
- using value_type = T_value;
- using member_type = value_type object_type::*;
-
- static constexpr decltype(auto) apply(member_type&& setter)
- { return setter_member_var(std::forward<member_type>(setter)); }
- };
-
- /* setter_builder - member function */
-
- template<typename T_object, typename T_value, typename T_member>
- struct setter_builder_member_func
- {
- struct setter_member_func
- : public tag_setter
- , public tag_setter_member_func
- {
- using object_type = T_object;
- using value_type = T_value;
- using member_type = T_member;
-
- member_type member;
-
- inline setter_member_func(member_type p_member)
- : member(p_member)
- { }
-
- inline setter_member_func(setter_member_func&&) = default;
- inline setter_member_func(const setter_member_func&) = default;
-
- inline setter_member_func& operator = (setter_member_func&&) = default;
- inline setter_member_func& operator = (const setter_member_func&) = default;
-
- template<typename X_object, typename X_value>
- constexpr void operator()(X_object&& obj, X_value&& value) const
- { (std::forward<X_object>(obj).*member)(std::forward<X_value>(value)); }
- };
-
- using object_type = T_object;
- using value_type = T_value;
- using member_type = T_member;
-
- static constexpr decltype(auto) apply(member_type&& setter)
- { return setter_member_func(std::forward<member_type>(setter)); }
- };
-
- template<typename T_object, typename T_value>
- struct setter_builder<
- list<void (T_object::*)(T_value)>,
- void>
- : public setter_builder_member_func<T_object, T_value, void (T_object::*)(T_value)>
- { };
-
- template<typename T_object, typename T_value>
- struct setter_builder<
- list<void (T_object::*)(T_value) const>,
- void>
- : public setter_builder_member_func<const T_object, T_value, void (T_object::*)(T_value) const>
- { };
-
- /* setter_builder - lambda/static */
-
- template<typename T_lambda>
- struct setter_builder<
- list<T_lambda>,
- enable_if_t<
- is_valid<lambda_traits<decay_t<T_lambda>>>::value
- && lambda_traits<decay_t<T_lambda>>::argument_count_v == 2>>
- {
- struct setter_lambda
- : public tag_setter
- , public tag_setter_lambda
- {
- using lambda_type = T_lambda;
- using lambda_traits_type = lambda_traits<lambda_type>;
- using object_type = typename lambda_traits_type::template argument_t<0>;
- using value_type = typename lambda_traits_type::template argument_t<1>;
-
- lambda_type lambda;
-
- inline cppmp_constexpr_lambda setter_lambda(lambda_type&& p_lambda)
- : lambda(std::forward<lambda_type>(p_lambda))
- { }
-
- inline cppmp_constexpr_lambda setter_lambda(setter_lambda&&) = default;
- inline cppmp_constexpr_lambda setter_lambda(const setter_lambda&) = default;
-
- inline cppmp_constexpr_lambda setter_lambda& operator = (setter_lambda&&) = default;
- inline cppmp_constexpr_lambda setter_lambda& operator = (const setter_lambda&) = default;
-
- template<typename X_object, typename X_value>
- constexpr void operator()(X_object&& obj, X_value&& value) const
- { lambda(std::forward<X_object>(obj), std::forward<X_value>(value)); }
- };
-
- using lambda_type = T_lambda;
-
- static constexpr decltype(auto) apply(lambda_type&& lambda)
- { return setter_lambda(std::forward<lambda_type>(lambda)); }
- };
-
- }
-
- /* is_setter */
-
- template<typename T>
- struct is_setter
- : public is_base_of<tag_setter, T>
- { };
-
- }
|