|
- #pragma once
-
- #include <cpputils/misc/type_helper.h>
-
- #include <cppargs/parser/parser.h>
- #include <cppargs/options/member.h>
- #include <cppargs/misc/option_parser.h>
-
- #include <cppargs/group/member_group.inl>
-
- namespace cppargs
- {
-
- template<typename T_instance, typename T_object, typename T_value>
- constexpr decltype(auto) member_parser_base::make_member_option(const option_meta& meta, T_value T_object::*member)
- {
- static_assert(std::is_base_of<T_object, T_instance>::value, "Member pointer must be in the instance type.");
-
- using instance_type = T_instance;
- using value_type = T_value;
-
- auto predicate = [member](instance_type& instance, context& c)
- {
- using executor_type = option_parser<value_type>;
- executor_type { c, instance.*member } ( );
- };
-
- using predicate_type = decltype(predicate);
- using member_predicate_option_type = member_predicate_option<instance_type, value_type, predicate_type>;
- return std::make_unique<member_predicate_option_type>(
- option_meta::prepare_arguments<T_value>(meta),
- std::move(predicate));
- }
-
- template<typename T_instance, typename... T_args>
- constexpr decltype(auto) member_parser_base::make_group(const group_meta& meta, T_args&&... args)
- {
- using owner_instance_type = T_instance;
- using my_instance_type = T_instance;
-
- auto predicate = [](owner_instance_type* instance)
- { return instance; };
-
- using predicate_type = decltype(predicate);
- using group_type = member_group<owner_instance_type, my_instance_type, predicate_type>;
- return std::make_unique<group_type>(meta, std::move(predicate), std::forward<T_args>(args)...);
- }
-
- template<typename T_instance, typename T_object, typename T_value, typename... T_args>
- constexpr decltype(auto) member_parser_base::make_member_group(const group_meta& meta, T_value T_object::*member, T_args&&... args)
- {
- using owner_instance_type = T_instance;
- using my_instance_type = T_value;
-
- auto predicate = [member](owner_instance_type* instance)
- {
- if (!instance)
- throw std::runtime_error("unable to resolve instance for sub group: no instance assigned");
- return &(instance->*member);
- };
-
- using predicate_type = decltype(predicate);
- using group_type = member_group<owner_instance_type, my_instance_type, predicate_type>;
- return std::make_unique<group_type>(meta, std::move(predicate), std::forward<T_args>(args)...);
- }
-
- template<typename T_instance>
- template<typename... T_args>
- member_parser<T_instance>::member_parser(
- option_ptr_type&& p_default,
- T_args&&... args)
- : base_type (std::move(p_default), _group)
- , _group (make_base_group(std::forward<T_args>(args)...))
- { update_map(); }
-
- template<typename T_instance>
- void member_parser<T_instance>::parse(instance_type& instance, int argc, char const * argv[]) const
- {
- auto lambda = [this]() { _instance = nullptr; };
- auto cleanup = std::make_unique<decltype(lambda)>(std::move(lambda));
- _instance = &instance;
- base_type::parse(argc, argv);
- }
-
- }
|