arguments.h 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 argument(size_t index, std::string const &name, std::string const &description = "");
  17. private:
  18. void usage() const;
  19. private:
  20. // Metadata variables
  21. bool primed_{false};
  22. std::map<std::string, std::string> option_descriptions;
  23. std::map<std::string, std::string> positional_descriptions;
  24. std::map<std::string, std::string> option_name_mapping;
  25. std::map<size_t, std::string> argument_names;
  26. // Data variables
  27. std::string program;
  28. size_t optional_from{std::numeric_limits<size_t>::max()};
  29. std::map<std::string, std::string> options;
  30. std::vector<std::string> arguments;
  31. };
  32. template <typename Impl>
  33. template <typename B, typename V>
  34. struct Arguments<Impl>::WithDefault {
  35. B impl;
  36. V default_value;
  37. template <typename T> operator T() const { return impl ?: T(default_value); }
  38. };
  39. template <typename Impl>
  40. struct Arguments<Impl>::Option {
  41. Arguments<Impl> *self;
  42. std::string name;
  43. char abbrev;
  44. std::string description;
  45. template <typename T> auto operator=(T &&value);
  46. template <typename T> operator T() const;
  47. bool primed() const;
  48. explicit operator bool() const;
  49. };
  50. template <typename Impl>
  51. struct Arguments<Impl>::Positional {
  52. Arguments<Impl> *self;
  53. size_t index;
  54. bool is_optional;
  55. std::string name;
  56. std::string description;
  57. template <typename T> auto operator=(T &&value);
  58. template <typename T> operator T() const;
  59. bool primed() const;
  60. explicit operator bool() const;
  61. };
  62. }
  63. #include "arguments_impl.hpp"
  64. #define TYPED_MAIN(tname) \
  65. int typed_main(tname const &args); \
  66. int main(int argc, char const * const * const argv) { \
  67. return typed_main(tname(argc, argv)); \
  68. } \
  69. int typed_main(tname const &args)