exception on parse error

This commit is contained in:
Jarryd Beck 2014-10-13 20:52:06 +11:00
parent 65c13302b4
commit 18ad3b1659
2 changed files with 122 additions and 91 deletions

View File

@ -28,6 +28,8 @@ THE SOFTWARE.
#include <exception>
#include <sstream>
#include <iostream>
namespace cxxopts
{
class Value
@ -41,97 +43,6 @@ namespace cxxopts
has_arg() const = 0;
};
namespace values
{
template <typename T>
void
parse_value(const std::string& text, T& value)
{
std::istringstream is(text);
if (!(is >> value))
{
}
if (!is.eof())
{
}
}
template <typename T>
void
parse_value(const std::string& text, std::vector<T>& value)
{
T v;
parse_value(text, v);
value.push_back(v);
}
template <typename T>
struct value_has_arg
{
static constexpr bool value = true;
};
template <>
struct value_has_arg<bool>
{
static constexpr bool value = false;
};
template <typename T>
class default_value : public Value
{
public:
default_value()
: m_result(std::make_shared<T>())
, 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<T>::value;
}
const T&
get() const
{
if (m_store == nullptr)
{
return *m_result;
}
else
{
return *m_store;
}
}
private:
std::shared_ptr<T> m_result;
T* m_store;
};
}
template <typename T>
std::shared_ptr<Value>
value()
{
return std::make_shared<values::default_value<T>>();
}
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 <typename T>
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 <typename T>
void
parse_value(const std::string& text, std::vector<T>& value)
{
T v;
parse_value(text, v);
value.push_back(v);
}
void
parse_value(const std::string& text, bool& value)
{
value = true;
}
template <typename T>
struct value_has_arg
{
static constexpr bool value = true;
};
template <>
struct value_has_arg<bool>
{
static constexpr bool value = false;
};
template <typename T>
class default_value : public Value
{
public:
default_value()
: m_result(std::make_shared<T>())
, 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<T>::value;
}
const T&
get() const
{
if (m_store == nullptr)
{
return *m_result;
}
else
{
return *m_store;
}
}
private:
std::shared_ptr<T> m_result;
T* m_store;
};
}
template <typename T>
std::shared_ptr<Value>
value()
{
return std::make_shared<values::default_value<T>>();
}
class OptionAdder;
class OptionDetails

View File

@ -43,6 +43,7 @@ int main(int argc, char* argv[])
("long-description",
"thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace")
("help", "Print help")
("int", "An integer", cxxopts::value<int>())
;
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<int>() << std::endl;
}
std::cout << "Arguments remain = " << argc << std::endl;
} catch (const cxxopts::OptionException& e)