Commit ad2d1a6b5fd3fbb7bb0e7bc11f28a427494aea45

Authored by Long Deng
Committed by GitHub
1 parent c74846a8

Add iterator (#126) and easily print-out (#223) to ParseResult (#313)

* Add iterator (#126) and easily print-out (#223) to ParseResult
include/cxxopts.hpp
... ... @@ -1457,14 +1457,76 @@ namespace cxxopts
1457 1457 class ParseResult
1458 1458 {
1459 1459 public:
  1460 + class Iterator
  1461 + {
  1462 + public:
  1463 + using iterator_category = std::forward_iterator_tag;
  1464 + using value_type = KeyValue;
  1465 + using difference_type = void;
  1466 + using pointer = const KeyValue*;
  1467 + using reference = const KeyValue&;
  1468 +
  1469 + Iterator() = default;
  1470 + Iterator(const Iterator&) = default;
  1471 +
  1472 + Iterator(const ParseResult *pr, bool end=false)
  1473 + : m_pr(pr)
  1474 + , m_iter(end? pr->m_defaults.end(): pr->m_sequential.begin())
  1475 + {
  1476 + }
  1477 +
  1478 + Iterator& operator++()
  1479 + {
  1480 + ++m_iter;
  1481 + if(m_iter == m_pr->m_sequential.end())
  1482 + {
  1483 + m_iter = m_pr->m_defaults.begin();
  1484 + return *this;
  1485 + }
  1486 + return *this;
  1487 + }
  1488 +
  1489 + Iterator operator++(int)
  1490 + {
  1491 + Iterator retval = *this;
  1492 + ++(*this);
  1493 + return retval;
  1494 + }
  1495 +
  1496 + bool operator==(const Iterator& other) const
  1497 + {
  1498 + return m_iter == other.m_iter;
  1499 + }
  1500 +
  1501 + bool operator!=(const Iterator& other) const
  1502 + {
  1503 + return !(*this == other);
  1504 + }
  1505 +
  1506 + const KeyValue& operator*()
  1507 + {
  1508 + return *m_iter;
  1509 + }
  1510 +
  1511 + const KeyValue* operator->()
  1512 + {
  1513 + return m_iter.operator->();
  1514 + }
  1515 +
  1516 + private:
  1517 + const ParseResult* m_pr;
  1518 + std::vector<KeyValue>::const_iterator m_iter;
  1519 + };
1460 1520  
1461 1521 ParseResult() = default;
1462 1522 ParseResult(const ParseResult&) = default;
1463 1523  
1464   - ParseResult(NameHashMap&& keys, ParsedHashMap&& values, std::vector<KeyValue> sequential, std::vector<std::string>&& unmatched_args)
  1524 + ParseResult(NameHashMap&& keys, ParsedHashMap&& values, std::vector<KeyValue> sequential,
  1525 + std::vector<KeyValue> default_opts, std::vector<std::string>&& unmatched_args)
1465 1526 : m_keys(std::move(keys))
1466 1527 , m_values(std::move(values))
1467 1528 , m_sequential(std::move(sequential))
  1529 + , m_defaults(std::move(default_opts))
1468 1530 , m_unmatched(std::move(unmatched_args))
1469 1531 {
1470 1532 }
... ... @@ -1472,6 +1534,18 @@ namespace cxxopts
1472 1534 ParseResult& operator=(ParseResult&&) = default;
1473 1535 ParseResult& operator=(const ParseResult&) = default;
1474 1536  
  1537 + Iterator
  1538 + begin() const
  1539 + {
  1540 + return Iterator(this);
  1541 + }
  1542 +
  1543 + Iterator
  1544 + end() const
  1545 + {
  1546 + return Iterator(this, true);
  1547 + }
  1548 +
1475 1549 size_t
1476 1550 count(const std::string& o) const
1477 1551 {
... ... @@ -1523,10 +1597,32 @@ namespace cxxopts
1523 1597 return m_unmatched;
1524 1598 }
1525 1599  
  1600 + const std::vector<KeyValue>&
  1601 + defaults() const
  1602 + {
  1603 + return m_defaults;
  1604 + }
  1605 +
  1606 + const std::string
  1607 + arguments_string() const
  1608 + {
  1609 + std::string result;
  1610 + for(const auto& kv: m_sequential)
  1611 + {
  1612 + result += kv.key() + " = " + kv.value() + "\n";
  1613 + }
  1614 + for(const auto& kv: m_defaults)
  1615 + {
  1616 + result += kv.key() + " = " + kv.value() + " " + "(default)" + "\n";
  1617 + }
  1618 + return result;
  1619 + }
  1620 +
1526 1621 private:
1527 1622 NameHashMap m_keys{};
1528 1623 ParsedHashMap m_values{};
1529 1624 std::vector<KeyValue> m_sequential{};
  1625 + std::vector<KeyValue> m_defaults{};
1530 1626 std::vector<std::string> m_unmatched{};
1531 1627 };
1532 1628  
... ... @@ -1607,6 +1703,7 @@ namespace cxxopts
1607 1703 const PositionalList& m_positional;
1608 1704  
1609 1705 std::vector<KeyValue> m_sequential{};
  1706 + std::vector<KeyValue> m_defaults{};
1610 1707 bool m_allow_unrecognised;
1611 1708  
1612 1709 ParsedHashMap m_parsed{};
... ... @@ -2053,6 +2150,7 @@ OptionParser::parse_default(const std::shared_ptr&lt;OptionDetails&gt;&amp; details)
2053 2150 // TODO: remove the duplicate code here
2054 2151 auto& store = m_parsed[details->hash()];
2055 2152 store.parse_default(details);
  2153 + m_defaults.emplace_back(details->long_name(), details->value().get_default_value());
2056 2154 }
2057 2155  
2058 2156 inline
... ... @@ -2350,7 +2448,7 @@ OptionParser::parse(int argc, const char* const* argv)
2350 2448  
2351 2449 finalise_aliases();
2352 2450  
2353   - ParseResult parsed(std::move(m_keys), std::move(m_parsed), std::move(m_sequential), std::move(unmatched));
  2451 + ParseResult parsed(std::move(m_keys), std::move(m_parsed), std::move(m_sequential), std::move(m_defaults), std::move(unmatched));
2354 2452 return parsed;
2355 2453 }
2356 2454  
... ...
src/example.cpp
... ... @@ -63,6 +63,8 @@ parse(int argc, const char* argv[])
63 63 ("float", "A floating point number", cxxopts::value<float>())
64 64 ("vector", "A list of doubles", cxxopts::value<std::vector<double>>())
65 65 ("option_that_is_too_long_for_the_help", "A very long option")
  66 + ("l,list", "List all parsed arguments (including default values)")
  67 + ("range", "Use range-for to list arguments")
66 68 #ifdef CXXOPTS_USE_UNICODE
67 69 ("unicode", u8"A help option with non-ascii: à. Here the size of the"
68 70 " string should be correct")
... ... @@ -83,6 +85,22 @@ parse(int argc, const char* argv[])
83 85 exit(0);
84 86 }
85 87  
  88 + if(result.count("list"))
  89 + {
  90 + if(result.count("range"))
  91 + {
  92 + for(const auto &kv: result)
  93 + {
  94 + std::cout << kv.key() << " = " << kv.value() << std::endl;
  95 + }
  96 + }
  97 + else
  98 + {
  99 + std::cout << result.arguments_string() << std::endl;
  100 + }
  101 + exit(0);
  102 + }
  103 +
86 104 if (apple)
87 105 {
88 106 std::cout << "Saw option ‘a’ " << result.count("a") << " times " <<
... ...