|
- #pragma once
-
- #include <cppargs/group/member_group.h>
-
- namespace cppargs
- {
-
- template<typename T_instance, typename T_arg>
- struct member_verify_and_forward
- {
- template<typename T, typename T_enable = void>
- struct check
- {
- template<typename X>
- constexpr X&& operator()(X&& x) const
- { static_assert(sizeof(X) == -1, "invalid group or option type"); }
- };
-
- template<typename T>
- struct check<
- std::unique_ptr<T>,
- utl::mp::enable_if<utl::mp::is_base_of<member_owned_group<T_instance>, T>>>
- {
- template<typename X>
- constexpr X&& operator()(X&& x) const
- { return std::forward<X>(x); }
- };
-
- template<typename T>
- struct check<
- std::unique_ptr<T>,
- utl::mp::enable_if<utl::mp::is_base_of<member_option<T_instance>, T>>>
- {
- template<typename X>
- constexpr X&& operator()(X&& x) const
- { return std::forward<X>(x); }
- };
-
- template<typename X>
- constexpr decltype(auto) operator()(X&& x) const
- { return check<T_arg> { } (std::forward<X>(x)); }
- };
-
- template<
- typename T_owner_instance,
- typename T_my_instance,
- typename T_resolve_instance_pred>
- template<
- typename... T_args>
- member_group<T_owner_instance, T_my_instance, T_resolve_instance_pred>
- ::member_group(
- const group_meta& p_meta,
- resolve_instance_pred_type&& p_pred,
- T_args&&... p_args)
- : group (p_meta, member_verify_and_forward<T_my_instance, T_args> { } (std::forward<T_args>(p_args))...)
- , _predicate(p_pred)
- {
- for (auto& o : _options)
- {
- auto* x = dynamic_cast<member_option_type*>(o.get());
- if (!x)
- throw std::runtime_error("option of member group is not a suitable member option");
- x->_owner = this;
- }
-
- for (auto& g : _groups)
- {
- auto* x = dynamic_cast<sub_owned_group_type*>(g.get());
- if (!x)
- throw std::runtime_error("group of member group is not a suitable member group");
- x->_owner = this;
- }
- }
-
- template<
- typename T_owner_instance,
- typename T_my_instance,
- typename T_resolve_instance_pred>
- T_my_instance* member_group<T_owner_instance, T_my_instance, T_resolve_instance_pred>
- ::instance() const
- {
- T_owner_instance * owner_inst = nullptr;
- if (this->_owner)
- owner_inst = this->_owner->instance();
- auto* ret = _predicate(owner_inst);
- return ret;
- }
-
- }
|