diff --git a/README.md b/README.md index 83f7ee5..6103003 100644 --- a/README.md +++ b/README.md @@ -316,6 +316,40 @@ Optional arguments: You may also get the help message in string via `program.help().str()`. +#### Adding a description and an epilog to help + +`ArgumentParser::add_description` will add text before the detailed argument +information. `ArgumentParser::add_epilog` will add text after all other help output. + +```cpp +argparse::ArgumentParser program("main"); + +program.add_argument("thing") + .help("Thing to use."); +program.add_description("Forward a thing to the next member."); +program.add_epilog("Possible things include betingalw, chiz, and res."); + +program.parse_args(argc, argv); + +std::cout << program << std::endl; +``` + +```bash +$ ./main --help +Usage: main thing + +Forward a thing to the next member. + +Positional arguments: +thing Thing to use. + +Optional arguments: +-h --help shows help message and exits [default: false] +-v --version prints version information and exits [default: false] + +Possible things include betingalw, chiz, and res. +``` + ### List of Arguments ArgumentParser objects usually associate a single command-line argument with a single action to be taken. The ```.nargs``` associates a different number of command-line arguments with a single action. When using ```nargs(N)```, N arguments from the command line will be gathered together into a list. diff --git a/include/argparse/argparse.hpp b/include/argparse/argparse.hpp index db99c16..4b05057 100644 --- a/include/argparse/argparse.hpp +++ b/include/argparse/argparse.hpp @@ -518,13 +518,6 @@ public: void validate() const { if (auto expected = maybe_nargs()) { if (m_is_optional) { - if (m_is_used && m_values.size() != *expected && !m_is_repeatable && - !m_default_value.has_value()) { - std::stringstream stream; - stream << m_used_name << ": expected " << *expected - << " argument(s). " << m_values.size() << " provided."; - throw std::runtime_error(stream.str()); - } // TODO: check if an implicit value was programmed for this argument if (!m_is_used && !m_default_value.has_value() && m_is_required) { std::stringstream stream; @@ -910,11 +903,11 @@ public: // Call add_argument with variadic number of string arguments template Argument &add_argument(Targs... f_args) { using array_of_sv = std::array; - auto argument = m_optional_arguments.emplace(cend(m_optional_arguments), - array_of_sv{f_args...}); + auto argument = m_optional_arguments.emplace( + std::cend(m_optional_arguments), array_of_sv{f_args...}); if (!argument->m_is_optional) { - m_positional_arguments.splice(cend(m_positional_arguments), + m_positional_arguments.splice(std::cend(m_positional_arguments), m_optional_arguments, argument); } @@ -928,13 +921,13 @@ public: ArgumentParser &add_parents(const Targs &...f_args) { for (const ArgumentParser &parent_parser : {std::ref(f_args)...}) { for (const auto &argument : parent_parser.m_positional_arguments) { - auto it = m_positional_arguments.insert(cend(m_positional_arguments), - argument); + auto it = m_positional_arguments.insert( + std::cend(m_positional_arguments), argument); index_argument(it); } for (const auto &argument : parent_parser.m_optional_arguments) { - auto it = - m_optional_arguments.insert(cend(m_optional_arguments), argument); + auto it = m_optional_arguments.insert(std::cend(m_optional_arguments), + argument); index_argument(it); } }