basically working

This commit is contained in:
Jarryd Beck 2014-10-02 16:38:13 +10:00
parent 70d458e90b
commit 97d072ae2d
3 changed files with 93 additions and 77 deletions

View File

@ -38,7 +38,7 @@ OptionAdder::operator()
if (s.length() != 0) 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) if (!in.second)
{ {
@ -48,7 +48,7 @@ OptionAdder::operator()
if (l.length() != 0) 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) if (!in.second)
{ {
@ -67,9 +67,7 @@ Options::parse_option
const std::string& arg const std::string& arg
) )
{ {
auto& v = m_parsed[name]; value->parse(arg);
value->parse("", v.value);
++v.count;
} }
void void
@ -121,9 +119,9 @@ Options::parse(int& argc, char**& argv)
for (int i = 0; i != s.size(); ++i) for (int i = 0; i != s.size(); ++i)
{ {
std::string name(1, s[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); throw option_not_exists_exception(name);
} }
@ -155,9 +153,9 @@ Options::parse(int& argc, char**& argv)
{ {
std::string name = result[1]; 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); throw option_not_exists_exception(name);
} }

View File

@ -14,7 +14,7 @@ namespace cxxopts
public: public:
virtual void virtual void
parse(const std::string& text, any& result) const = 0; parse(const std::string& text) const = 0;
virtual bool virtual bool
has_arg() const = 0; has_arg() const = 0;
@ -22,56 +22,73 @@ namespace cxxopts
namespace values namespace values
{ {
template <typename T>
void
parse_value(const std::string& text, T& value)
{
std::istringstream is(text);
is >> value;
}
template <typename T>
bool
value_has_arg(bool*)
{
return false;
}
template <typename T>
bool
value_has_arg(T*)
{
return true;
}
template <typename T> template <typename T>
class default_value : public Value class default_value : public Value
{ {
void public:
parse(const std::string& text, any& result) const default_value()
: m_result(std::make_shared<T>())
, m_store(m_result.get())
{ {
T t; }
std::istringstream is(text);
is >> t; default_value(T* t)
result = t; : m_store(t)
{
}
void
parse(const std::string& text) const
{
parse_value(text, *m_store);
} }
bool bool
has_arg() const 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<T> m_result;
T* m_store;
}; };
template <>
class default_value<bool> : public Value
{
void
parse(const std::string& text, any& result) const
{
result = true;
}
bool
has_arg() const
{
return false;
}
};
template <>
class default_value<std::string> : public Value
{
void
parse(const std::string& text, any& result) const
{
result = text;
}
bool
has_arg() const
{
return true;
}
};
} }
template <typename T> template <typename T>
@ -205,7 +222,8 @@ namespace cxxopts
std::shared_ptr<const Value> value std::shared_ptr<const Value> value
) )
: m_desc(description) : m_desc(description)
, m_parser(value) , m_value(value)
, m_count(0)
{ {
} }
@ -218,29 +236,33 @@ namespace cxxopts
bool bool
has_arg() const has_arg() const
{ {
return m_parser->has_arg(); return m_value->has_arg();
} }
void 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 <typename T>
const T&
as() const
{
return dynamic_cast<const values::default_value<T>&>(*m_value).get();
} }
private: private:
std::string m_desc; std::string m_desc;
std::shared_ptr<const Value> m_parser; std::shared_ptr<const Value> m_value;
}; int m_count;
struct ParsedOption
{
boost::any value;
int count;
ParsedOption()
: count(0)
{
}
}; };
class Options class Options
@ -256,27 +278,26 @@ namespace cxxopts
int int
count(const std::string& o) const count(const std::string& o) const
{ {
auto iter = m_parsed.find(o); auto iter = m_options.find(o);
if (iter == m_options.end())
if (iter == m_parsed.end())
{ {
return 0; return 0;
} }
return iter->second.count; return iter->second->count();
} }
const boost::any& const OptionDetails&
operator[](const std::string& option) const 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); throw option_not_present_exception(option);
} }
return iter->second.value; return *iter->second;
} }
private: private:
@ -301,10 +322,7 @@ namespace cxxopts
); );
std::map<std::string, std::shared_ptr<OptionDetails>> m_short; std::map<std::string, std::shared_ptr<OptionDetails>> m_options;
std::map<std::string, std::shared_ptr<OptionDetails>> m_long;
std::map<std::string, ParsedOption> m_parsed;
}; };
class OptionAdder class OptionAdder

View File

@ -48,7 +48,7 @@ int main(int argc, char* argv[])
if (options.count("f")) if (options.count("f"))
{ {
std::cout << "File = " << boost::any_cast<std::string>(options["f"]) std::cout << "File = " << options["f"].as<std::string>()
<< std::endl; << std::endl;
} }