From 3fed557cf29c2e03e31382d5c2aa1fd609a3b477 Mon Sep 17 00:00:00 2001 From: Jarryd Beck Date: Fri, 27 Oct 2017 07:57:54 +1100 Subject: [PATCH] much closer to working --- include/cxxopts.hpp | 99 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 20 deletions(-) diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index 8afb8dc..e533199 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -908,6 +908,12 @@ namespace cxxopts #endif } + std::shared_ptr + make_storage() const + { + return m_value->clone(); + } + private: String m_desc; std::shared_ptr m_value; @@ -935,14 +941,54 @@ namespace cxxopts std::vector options; }; + class OptionValue + { + public: + void + parse + ( + std::shared_ptr details, + const std::string& text + ) + { + ensure_value(details); + ++m_count; + m_value->parse(text); + } + + void + parse_default(std::shared_ptr details) + { + ensure_value(details); + m_value->parse(); + } + + size_t + count() const + { + return m_count; + } + + private: + void + ensure_value(std::shared_ptr details) + { + if (m_value == nullptr) + { + m_value = details->make_storage(); + } + } + + std::shared_ptr m_value; + size_t m_count = 0; + }; + class ParseResult { public: - template ParseResult( - Iterator, - Iterator, + const std::unordered_map>&, std::vector, int&, char**&); @@ -955,7 +1001,9 @@ namespace cxxopts return 0; } - return iter->second->count(); + auto riter = m_results.find(iter->second); + + return riter->second.count(); } const OptionDetails& @@ -973,6 +1021,9 @@ namespace cxxopts private: + OptionValue& + get_option(std::shared_ptr); + void parse(int& argc, char**& argv); @@ -990,6 +1041,9 @@ namespace cxxopts const std::string& arg = "" ); + void + parse_default(std::shared_ptr details); + void checked_parse_arg ( @@ -1000,10 +1054,12 @@ namespace cxxopts const std::string& name ); - std::unordered_map> m_options; + const std::unordered_map> + &m_options; std::vector m_positional; std::vector::iterator m_next_positional; std::unordered_set m_positional_set; + std::unordered_map, OptionValue> m_results; }; class Options @@ -1084,7 +1140,7 @@ namespace cxxopts String m_help_string; std::string m_positional_help; - std::map> m_options; + std::unordered_map> m_options; std::vector m_positional; std::vector::iterator m_next_positional; std::unordered_set m_positional_set; @@ -1234,22 +1290,17 @@ namespace cxxopts } } -template -ParseResult::ParseResult(Iterator begin, Iterator end, +inline +ParseResult::ParseResult +( + const std::unordered_map>& options, std::vector positional, int& argc, char**& argv ) -: m_positional(std::move(positional)) +: m_options(options) +, m_positional(std::move(positional)) , m_next_positional(m_positional.begin()) { - for (auto current = begin; current != end; ++current) - { - m_options.insert({ - current->first, - std::make_shared(*current->second) - }); - } - parse(argc, argv); } @@ -1318,6 +1369,13 @@ OptionAdder::operator() return *this; } +inline +void +ParseResult::parse_default(std::shared_ptr details) +{ + m_results[details].parse_default(details); +} + inline void ParseResult::parse_option @@ -1327,7 +1385,8 @@ ParseResult::parse_option const std::string& arg ) { - value->parse(arg); + auto& result = m_results[value]; + result.parse(value, arg); } inline @@ -1436,7 +1495,7 @@ inline ParseResult Options::parse(int& argc, char**& argv) { - ParseResult result(m_options.begin(), m_options.end(), m_positional, argc, argv); + ParseResult result(m_options, m_positional, argc, argv); return result; } @@ -1573,7 +1632,7 @@ ParseResult::parse(int& argc, char**& argv) auto& value = detail->value(); if(!detail->count() && value.has_default()){ - detail->parse_default(); + parse_default(detail); } }