Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/jarro2783/cxxopts.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLong Deng <37360259+ldeng-ustc@users.noreply.github.com>2021-11-09 10:49:58 +0300
committerGitHub <noreply@github.com>2021-11-09 10:49:58 +0300
commitad2d1a6b5fd3fbb7bb0e7bc11f28a427494aea45 (patch)
tree17afc4a2a1d01f1de3e00be8bd23b464e4bd02c0
parentc74846a891b3cc3bfa992d588b1295f528d43039 (diff)
Add iterator (#126) and easily print-out (#223) to ParseResult (#313)
* Add iterator (#126) and easily print-out (#223) to ParseResult
-rw-r--r--include/cxxopts.hpp102
-rw-r--r--src/example.cpp18
2 files changed, 118 insertions, 2 deletions
diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp
index 12456a7..d247ba7 100644
--- a/include/cxxopts.hpp
+++ b/include/cxxopts.hpp
@@ -1457,14 +1457,76 @@ namespace cxxopts
class ParseResult
{
public:
+ class Iterator
+ {
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = KeyValue;
+ using difference_type = void;
+ using pointer = const KeyValue*;
+ using reference = const KeyValue&;
+
+ Iterator() = default;
+ Iterator(const Iterator&) = default;
+
+ Iterator(const ParseResult *pr, bool end=false)
+ : m_pr(pr)
+ , m_iter(end? pr->m_defaults.end(): pr->m_sequential.begin())
+ {
+ }
+
+ Iterator& operator++()
+ {
+ ++m_iter;
+ if(m_iter == m_pr->m_sequential.end())
+ {
+ m_iter = m_pr->m_defaults.begin();
+ return *this;
+ }
+ return *this;
+ }
+
+ Iterator operator++(int)
+ {
+ Iterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(const Iterator& other) const
+ {
+ return m_iter == other.m_iter;
+ }
+
+ bool operator!=(const Iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+ const KeyValue& operator*()
+ {
+ return *m_iter;
+ }
+
+ const KeyValue* operator->()
+ {
+ return m_iter.operator->();
+ }
+
+ private:
+ const ParseResult* m_pr;
+ std::vector<KeyValue>::const_iterator m_iter;
+ };
ParseResult() = default;
ParseResult(const ParseResult&) = default;
- ParseResult(NameHashMap&& keys, ParsedHashMap&& values, std::vector<KeyValue> sequential, std::vector<std::string>&& unmatched_args)
+ ParseResult(NameHashMap&& keys, ParsedHashMap&& values, std::vector<KeyValue> sequential,
+ std::vector<KeyValue> default_opts, std::vector<std::string>&& unmatched_args)
: m_keys(std::move(keys))
, m_values(std::move(values))
, m_sequential(std::move(sequential))
+ , m_defaults(std::move(default_opts))
, m_unmatched(std::move(unmatched_args))
{
}
@@ -1472,6 +1534,18 @@ namespace cxxopts
ParseResult& operator=(ParseResult&&) = default;
ParseResult& operator=(const ParseResult&) = default;
+ Iterator
+ begin() const
+ {
+ return Iterator(this);
+ }
+
+ Iterator
+ end() const
+ {
+ return Iterator(this, true);
+ }
+
size_t
count(const std::string& o) const
{
@@ -1523,10 +1597,32 @@ namespace cxxopts
return m_unmatched;
}
+ const std::vector<KeyValue>&
+ defaults() const
+ {
+ return m_defaults;
+ }
+
+ const std::string
+ arguments_string() const
+ {
+ std::string result;
+ for(const auto& kv: m_sequential)
+ {
+ result += kv.key() + " = " + kv.value() + "\n";
+ }
+ for(const auto& kv: m_defaults)
+ {
+ result += kv.key() + " = " + kv.value() + " " + "(default)" + "\n";
+ }
+ return result;
+ }
+
private:
NameHashMap m_keys{};
ParsedHashMap m_values{};
std::vector<KeyValue> m_sequential{};
+ std::vector<KeyValue> m_defaults{};
std::vector<std::string> m_unmatched{};
};
@@ -1607,6 +1703,7 @@ namespace cxxopts
const PositionalList& m_positional;
std::vector<KeyValue> m_sequential{};
+ std::vector<KeyValue> m_defaults{};
bool m_allow_unrecognised;
ParsedHashMap m_parsed{};
@@ -2053,6 +2150,7 @@ OptionParser::parse_default(const std::shared_ptr<OptionDetails>& details)
// TODO: remove the duplicate code here
auto& store = m_parsed[details->hash()];
store.parse_default(details);
+ m_defaults.emplace_back(details->long_name(), details->value().get_default_value());
}
inline
@@ -2350,7 +2448,7 @@ OptionParser::parse(int argc, const char* const* argv)
finalise_aliases();
- ParseResult parsed(std::move(m_keys), std::move(m_parsed), std::move(m_sequential), std::move(unmatched));
+ ParseResult parsed(std::move(m_keys), std::move(m_parsed), std::move(m_sequential), std::move(m_defaults), std::move(unmatched));
return parsed;
}
diff --git a/src/example.cpp b/src/example.cpp
index c21bad6..420220e 100644
--- a/src/example.cpp
+++ b/src/example.cpp
@@ -63,6 +63,8 @@ parse(int argc, const char* argv[])
("float", "A floating point number", cxxopts::value<float>())
("vector", "A list of doubles", cxxopts::value<std::vector<double>>())
("option_that_is_too_long_for_the_help", "A very long option")
+ ("l,list", "List all parsed arguments (including default values)")
+ ("range", "Use range-for to list arguments")
#ifdef CXXOPTS_USE_UNICODE
("unicode", u8"A help option with non-ascii: à. Here the size of the"
" string should be correct")
@@ -83,6 +85,22 @@ parse(int argc, const char* argv[])
exit(0);
}
+ if(result.count("list"))
+ {
+ if(result.count("range"))
+ {
+ for(const auto &kv: result)
+ {
+ std::cout << kv.key() << " = " << kv.value() << std::endl;
+ }
+ }
+ else
+ {
+ std::cout << result.arguments_string() << std::endl;
+ }
+ exit(0);
+ }
+
if (apple)
{
std::cout << "Saw option ‘a’ " << result.count("a") << " times " <<