arguments.h 2.6 KB

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