From 18ad3b16595c856df936a84304f47c923f160ca3 Mon Sep 17 00:00:00 2001 From: Jarryd Beck Date: Mon, 13 Oct 2014 20:52:06 +1100 Subject: [PATCH] exception on parse error --- src/cxxopts.hpp | 207 +++++++++++++++++++++++++++--------------------- src/example.cpp | 6 ++ 2 files changed, 122 insertions(+), 91 deletions(-) diff --git a/src/cxxopts.hpp b/src/cxxopts.hpp index d64bc3e..989fec9 100644 --- a/src/cxxopts.hpp +++ b/src/cxxopts.hpp @@ -28,6 +28,8 @@ THE SOFTWARE. #include #include +#include + namespace cxxopts { class Value @@ -41,97 +43,6 @@ namespace cxxopts has_arg() const = 0; }; - namespace values - { - template - void - parse_value(const std::string& text, T& value) - { - std::istringstream is(text); - if (!(is >> value)) - { - } - - if (!is.eof()) - { - } - } - - template - void - parse_value(const std::string& text, std::vector& value) - { - T v; - parse_value(text, v); - value.push_back(v); - } - - template - struct value_has_arg - { - static constexpr bool value = true; - }; - - template <> - struct value_has_arg - { - static constexpr bool value = false; - }; - - template - class default_value : public Value - { - public: - default_value() - : m_result(std::make_shared()) - , m_store(m_result.get()) - { - } - - default_value(T* t) - : m_store(t) - { - } - - void - parse(const std::string& text) const - { - parse_value(text, *m_store); - } - - bool - has_arg() const - { - return value_has_arg::value; - } - - 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 - std::shared_ptr - value() - { - return std::make_shared>(); - } - class OptionException : public std::exception { public: @@ -238,6 +149,120 @@ namespace cxxopts } }; + class argument_incorrect_type : public OptionParseException + { + public: + argument_incorrect_type + ( + const std::string& arg + ) + : OptionParseException( + u8"Argument ‘" + arg + u8"’ failed to parse" + ) + { + } + }; + + namespace values + { + template + void + parse_value(const std::string& text, T& value) + { + std::istringstream is(text); + if (!(is >> value)) + { + std::cerr << "cannot parse empty value" << std::endl; + throw argument_incorrect_type(text); + } + + if (!is.eof()) + { + throw argument_incorrect_type(text); + } + } + + template + void + parse_value(const std::string& text, std::vector& value) + { + T v; + parse_value(text, v); + value.push_back(v); + } + + void + parse_value(const std::string& text, bool& value) + { + value = true; + } + + template + struct value_has_arg + { + static constexpr bool value = true; + }; + + template <> + struct value_has_arg + { + static constexpr bool value = false; + }; + + template + class default_value : public Value + { + public: + default_value() + : m_result(std::make_shared()) + , m_store(m_result.get()) + { + } + + default_value(T* t) + : m_store(t) + { + } + + void + parse(const std::string& text) const + { + parse_value(text, *m_store); + } + + bool + has_arg() const + { + return value_has_arg::value; + } + + 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 + std::shared_ptr + value() + { + return std::make_shared>(); + } + class OptionAdder; class OptionDetails diff --git a/src/example.cpp b/src/example.cpp index fa0e322..18b75cd 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -43,6 +43,7 @@ int main(int argc, char* argv[]) ("long-description", "thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace") ("help", "Print help") + ("int", "An integer", cxxopts::value()) ; options.parse_positional("positional"); @@ -80,6 +81,11 @@ int main(int argc, char* argv[]) << std::endl; } + if (options.count("int")) + { + std::cout << "int = " << options["int"].as() << std::endl; + } + std::cout << "Arguments remain = " << argc << std::endl; } catch (const cxxopts::OptionException& e)