arguments.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. #include <map>
  3. #include <string>
  4. #include <vector>
  5. namespace program {
  6. template <typename Impl>
  7. class Arguments {
  8. protected:
  9. struct Option;
  10. struct Positional;
  11. template <typename, typename> struct WithDefault;
  12. public:
  13. Arguments() = default;
  14. Arguments(int argc, char const * const * const argv);
  15. auto option(std::string const &name, std::string const &description = "");
  16. auto option(std::string const &name, char abbrev,
  17. std::string const &description = "");
  18. auto argument(size_t index, std::string const &name,
  19. std::string const &description = "");
  20. private:
  21. void usage() const;
  22. private:
  23. // Metadata variables
  24. bool primed_{false};
  25. std::map<std::string, std::string> option_descriptions;
  26. std::map<std::string, std::string> positional_descriptions;
  27. std::map<std::string, std::string> option_name_mapping;
  28. std::map<size_t, std::string> argument_names;
  29. // Data variables
  30. std::string program;
  31. size_t optional_from{std::numeric_limits<size_t>::max()};
  32. std::map<std::string, std::vector<std::string>> options;
  33. std::vector<std::string> arguments;
  34. };
  35. template <typename Impl>
  36. template <typename B, typename V>
  37. struct Arguments<Impl>::WithDefault {
  38. B impl;
  39. V default_value;
  40. template <typename T> operator T() const { return impl ?: T(default_value); }
  41. };
  42. template <typename Impl>
  43. struct Arguments<Impl>::Option {
  44. Arguments<Impl> *self;
  45. std::string name;
  46. char abbrev;
  47. std::string description;
  48. template <typename T> auto operator=(T &&value);
  49. template <typename T> operator T() const;
  50. bool primed() const;
  51. explicit operator bool() const;
  52. };
  53. template <typename Impl>
  54. struct Arguments<Impl>::Positional {
  55. Arguments<Impl> *self;
  56. size_t index;
  57. bool is_optional;
  58. std::string name;
  59. std::string description;
  60. template <typename T> auto operator=(T &&value);
  61. template <typename T> operator T() const;
  62. bool primed() const;
  63. explicit operator bool() const;
  64. };
  65. }
  66. #include "arguments_impl.hpp"
  67. #define TYPED_MAIN(tname) \
  68. int typed_main(tname const &args); \
  69. int main(int argc, char const * const * const argv) try { \
  70. return typed_main(tname(argc, argv)); \
  71. } catch(program::ProgramArgumentsError const &pae) { \
  72. std::cerr << "Error in program argument handling: " << pae.what() << "\n"; \
  73. } \
  74. int typed_main(tname const &args)