From 97d072ae2dff2ed0c95dc039ab40192413b3f7d0 Mon Sep 17 00:00:00 2001 From: Jarryd Beck Date: Thu, 2 Oct 2014 16:38:13 +1000 Subject: [PATCH] basically working --- src/cxxopts.cpp | 16 +++-- src/cxxopts.hpp | 152 +++++++++++++++++++++++++++--------------------- src/main.cpp | 2 +- 3 files changed, 93 insertions(+), 77 deletions(-) diff --git a/src/cxxopts.cpp b/src/cxxopts.cpp index bacfc34..c458121 100644 --- a/src/cxxopts.cpp +++ b/src/cxxopts.cpp @@ -38,7 +38,7 @@ OptionAdder::operator() if (s.length() != 0) { - auto in = m_options.m_short.insert(std::make_pair(s.str(), option)); + auto in = m_options.m_options.insert(std::make_pair(s.str(), option)); if (!in.second) { @@ -48,7 +48,7 @@ OptionAdder::operator() if (l.length() != 0) { - auto in = m_options.m_long.insert(std::make_pair(l, option)); + auto in = m_options.m_options.insert(std::make_pair(l, option)); if (!in.second) { @@ -67,9 +67,7 @@ Options::parse_option const std::string& arg ) { - auto& v = m_parsed[name]; - value->parse("", v.value); - ++v.count; + value->parse(arg); } void @@ -121,9 +119,9 @@ Options::parse(int& argc, char**& argv) for (int i = 0; i != s.size(); ++i) { std::string name(1, s[i]); - auto iter = m_short.find(name); + auto iter = m_options.find(name); - if (iter == m_short.end()) + if (iter == m_options.end()) { throw option_not_exists_exception(name); } @@ -155,9 +153,9 @@ Options::parse(int& argc, char**& argv) { std::string name = result[1]; - auto iter = m_long.find(name); + auto iter = m_options.find(name); - if (iter == m_long.end()) + if (iter == m_options.end()) { throw option_not_exists_exception(name); } diff --git a/src/cxxopts.hpp b/src/cxxopts.hpp index 93048dc..e25345d 100644 --- a/src/cxxopts.hpp +++ b/src/cxxopts.hpp @@ -14,7 +14,7 @@ namespace cxxopts public: virtual void - parse(const std::string& text, any& result) const = 0; + parse(const std::string& text) const = 0; virtual bool has_arg() const = 0; @@ -22,56 +22,73 @@ namespace cxxopts namespace values { + template + void + parse_value(const std::string& text, T& value) + { + std::istringstream is(text); + is >> value; + } + + template + bool + value_has_arg(bool*) + { + return false; + } + + template + bool + value_has_arg(T*) + { + return true; + } + template class default_value : public Value { - void - parse(const std::string& text, any& result) const + public: + default_value() + : m_result(std::make_shared()) + , m_store(m_result.get()) { - T t; - std::istringstream is(text); - is >> t; - result = t; + } + + default_value(T* t) + : m_store(t) + { + } + + void + parse(const std::string& text) const + { + parse_value(text, *m_store); } bool has_arg() const { - return true; + return value_has_arg(m_store); } + + const T& + get() const + { + if (m_store == nullptr) + { + return *m_result; + } + else + { + return *m_store; + } + } + + private: + std::shared_ptr m_result; + T* m_store; }; - template <> - class default_value : public Value - { - void - parse(const std::string& text, any& result) const - { - result = true; - } - - bool - has_arg() const - { - return false; - } - }; - - template <> - class default_value : public Value - { - void - parse(const std::string& text, any& result) const - { - result = text; - } - - bool - has_arg() const - { - return true; - } - }; } template @@ -205,7 +222,8 @@ namespace cxxopts std::shared_ptr value ) : m_desc(description) - , m_parser(value) + , m_value(value) + , m_count(0) { } @@ -218,29 +236,33 @@ namespace cxxopts bool has_arg() const { - return m_parser->has_arg(); + return m_value->has_arg(); } void - parse(const std::string& text, boost::any& arg) + parse(const std::string& text) { - m_parser->parse(text, arg); + m_value->parse(text); + ++m_count; + } + + int + count() const + { + return m_count; + } + + template + const T& + as() const + { + return dynamic_cast&>(*m_value).get(); } private: std::string m_desc; - std::shared_ptr m_parser; - }; - - struct ParsedOption - { - boost::any value; - int count; - - ParsedOption() - : count(0) - { - } + std::shared_ptr m_value; + int m_count; }; class Options @@ -256,27 +278,26 @@ namespace cxxopts int count(const std::string& o) const { - auto iter = m_parsed.find(o); - - if (iter == m_parsed.end()) + auto iter = m_options.find(o); + if (iter == m_options.end()) { return 0; } - return iter->second.count; + return iter->second->count(); } - const boost::any& + const OptionDetails& operator[](const std::string& option) const { - auto iter = m_parsed.find(option); + auto iter = m_options.find(option); - if (iter == m_parsed.end()) + if (iter == m_options.end()) { throw option_not_present_exception(option); } - return iter->second.value; + return *iter->second; } private: @@ -301,10 +322,7 @@ namespace cxxopts ); - std::map> m_short; - std::map> m_long; - - std::map m_parsed; + std::map> m_options; }; class OptionAdder diff --git a/src/main.cpp b/src/main.cpp index 52bac6a..99d3b8a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,7 +48,7 @@ int main(int argc, char* argv[]) if (options.count("f")) { - std::cout << "File = " << boost::any_cast(options["f"]) + std::cout << "File = " << options["f"].as() << std::endl; }