選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

86 行
3.3 KiB

  1. #pragma once
  2. #include <cpputils/misc/type_helper.h>
  3. #include <cppargs/parser/parser.h>
  4. #include <cppargs/options/member.h>
  5. #include <cppargs/misc/option_parser.h>
  6. #include <cppargs/group/member_group.inl>
  7. namespace cppargs
  8. {
  9. template<typename T_instance, typename T_object, typename T_value>
  10. constexpr decltype(auto) member_parser_base::make_member_option(const option_meta& meta, T_value T_object::*member)
  11. {
  12. static_assert(std::is_base_of<T_object, T_instance>::value, "Member pointer must be in the instance type.");
  13. using instance_type = T_instance;
  14. using value_type = T_value;
  15. auto predicate = [member](instance_type& instance, context& c)
  16. {
  17. using executor_type = option_parser<value_type>;
  18. executor_type { c, instance.*member } ( );
  19. };
  20. using predicate_type = decltype(predicate);
  21. using member_predicate_option_type = member_predicate_option<instance_type, value_type, predicate_type>;
  22. return std::make_unique<member_predicate_option_type>(
  23. option_meta::prepare_arguments<T_value>(meta),
  24. std::move(predicate));
  25. }
  26. template<typename T_instance, typename... T_args>
  27. constexpr decltype(auto) member_parser_base::make_group(const group_meta& meta, T_args&&... args)
  28. {
  29. using owner_instance_type = T_instance;
  30. using my_instance_type = T_instance;
  31. auto predicate = [](owner_instance_type* instance)
  32. { return instance; };
  33. using predicate_type = decltype(predicate);
  34. using group_type = member_group<owner_instance_type, my_instance_type, predicate_type>;
  35. return std::make_unique<group_type>(meta, std::move(predicate), std::forward<T_args>(args)...);
  36. }
  37. template<typename T_instance, typename T_object, typename T_value, typename... T_args>
  38. constexpr decltype(auto) member_parser_base::make_member_group(const group_meta& meta, T_value T_object::*member, T_args&&... args)
  39. {
  40. using owner_instance_type = T_instance;
  41. using my_instance_type = T_value;
  42. auto predicate = [member](owner_instance_type* instance)
  43. {
  44. if (!instance)
  45. throw std::runtime_error("unable to resolve instance for sub group: no instance assigned");
  46. return &(instance->*member);
  47. };
  48. using predicate_type = decltype(predicate);
  49. using group_type = member_group<owner_instance_type, my_instance_type, predicate_type>;
  50. return std::make_unique<group_type>(meta, std::move(predicate), std::forward<T_args>(args)...);
  51. }
  52. template<typename T_instance>
  53. template<typename... T_args>
  54. member_parser<T_instance>::member_parser(
  55. option_ptr_type&& p_default,
  56. T_args&&... args)
  57. : base_type (std::move(p_default), _group)
  58. , _group (make_base_group(std::forward<T_args>(args)...))
  59. { update_map(); }
  60. template<typename T_instance>
  61. void member_parser<T_instance>::parse(instance_type& instance, int argc, char const * argv[]) const
  62. {
  63. auto lambda = [this]() { _instance = nullptr; };
  64. auto cleanup = std::make_unique<decltype(lambda)>(std::move(lambda));
  65. _instance = &instance;
  66. base_type::parse(argc, argv);
  67. }
  68. }