Commit 18ad3b16595c856df936a84304f47c923f160ca3

Authored by Jarryd Beck
1 parent 65c13302

exception on parse error

src/cxxopts.hpp
... ... @@ -28,6 +28,8 @@ THE SOFTWARE.
28 28 #include <exception>
29 29 #include <sstream>
30 30  
  31 +#include <iostream>
  32 +
31 33 namespace cxxopts
32 34 {
33 35 class Value
... ... @@ -41,97 +43,6 @@ namespace cxxopts
41 43 has_arg() const = 0;
42 44 };
43 45  
44   - namespace values
45   - {
46   - template <typename T>
47   - void
48   - parse_value(const std::string& text, T& value)
49   - {
50   - std::istringstream is(text);
51   - if (!(is >> value))
52   - {
53   - }
54   -
55   - if (!is.eof())
56   - {
57   - }
58   - }
59   -
60   - template <typename T>
61   - void
62   - parse_value(const std::string& text, std::vector<T>& value)
63   - {
64   - T v;
65   - parse_value(text, v);
66   - value.push_back(v);
67   - }
68   -
69   - template <typename T>
70   - struct value_has_arg
71   - {
72   - static constexpr bool value = true;
73   - };
74   -
75   - template <>
76   - struct value_has_arg<bool>
77   - {
78   - static constexpr bool value = false;
79   - };
80   -
81   - template <typename T>
82   - class default_value : public Value
83   - {
84   - public:
85   - default_value()
86   - : m_result(std::make_shared<T>())
87   - , m_store(m_result.get())
88   - {
89   - }
90   -
91   - default_value(T* t)
92   - : m_store(t)
93   - {
94   - }
95   -
96   - void
97   - parse(const std::string& text) const
98   - {
99   - parse_value(text, *m_store);
100   - }
101   -
102   - bool
103   - has_arg() const
104   - {
105   - return value_has_arg<T>::value;
106   - }
107   -
108   - const T&
109   - get() const
110   - {
111   - if (m_store == nullptr)
112   - {
113   - return *m_result;
114   - }
115   - else
116   - {
117   - return *m_store;
118   - }
119   - }
120   -
121   - private:
122   - std::shared_ptr<T> m_result;
123   - T* m_store;
124   - };
125   -
126   - }
127   -
128   - template <typename T>
129   - std::shared_ptr<Value>
130   - value()
131   - {
132   - return std::make_shared<values::default_value<T>>();
133   - }
134   -
135 46 class OptionException : public std::exception
136 47 {
137 48 public:
... ... @@ -238,6 +149,120 @@ namespace cxxopts
238 149 }
239 150 };
240 151  
  152 + class argument_incorrect_type : public OptionParseException
  153 + {
  154 + public:
  155 + argument_incorrect_type
  156 + (
  157 + const std::string& arg
  158 + )
  159 + : OptionParseException(
  160 + u8"Argument โ€˜" + arg + u8"โ€™ failed to parse"
  161 + )
  162 + {
  163 + }
  164 + };
  165 +
  166 + namespace values
  167 + {
  168 + template <typename T>
  169 + void
  170 + parse_value(const std::string& text, T& value)
  171 + {
  172 + std::istringstream is(text);
  173 + if (!(is >> value))
  174 + {
  175 + std::cerr << "cannot parse empty value" << std::endl;
  176 + throw argument_incorrect_type(text);
  177 + }
  178 +
  179 + if (!is.eof())
  180 + {
  181 + throw argument_incorrect_type(text);
  182 + }
  183 + }
  184 +
  185 + template <typename T>
  186 + void
  187 + parse_value(const std::string& text, std::vector<T>& value)
  188 + {
  189 + T v;
  190 + parse_value(text, v);
  191 + value.push_back(v);
  192 + }
  193 +
  194 + void
  195 + parse_value(const std::string& text, bool& value)
  196 + {
  197 + value = true;
  198 + }
  199 +
  200 + template <typename T>
  201 + struct value_has_arg
  202 + {
  203 + static constexpr bool value = true;
  204 + };
  205 +
  206 + template <>
  207 + struct value_has_arg<bool>
  208 + {
  209 + static constexpr bool value = false;
  210 + };
  211 +
  212 + template <typename T>
  213 + class default_value : public Value
  214 + {
  215 + public:
  216 + default_value()
  217 + : m_result(std::make_shared<T>())
  218 + , m_store(m_result.get())
  219 + {
  220 + }
  221 +
  222 + default_value(T* t)
  223 + : m_store(t)
  224 + {
  225 + }
  226 +
  227 + void
  228 + parse(const std::string& text) const
  229 + {
  230 + parse_value(text, *m_store);
  231 + }
  232 +
  233 + bool
  234 + has_arg() const
  235 + {
  236 + return value_has_arg<T>::value;
  237 + }
  238 +
  239 + const T&
  240 + get() const
  241 + {
  242 + if (m_store == nullptr)
  243 + {
  244 + return *m_result;
  245 + }
  246 + else
  247 + {
  248 + return *m_store;
  249 + }
  250 + }
  251 +
  252 + private:
  253 + std::shared_ptr<T> m_result;
  254 + T* m_store;
  255 + };
  256 +
  257 + }
  258 +
  259 + template <typename T>
  260 + std::shared_ptr<Value>
  261 + value()
  262 + {
  263 + return std::make_shared<values::default_value<T>>();
  264 + }
  265 +
241 266 class OptionAdder;
242 267  
243 268 class OptionDetails
... ...
src/example.cpp
... ... @@ -43,6 +43,7 @@ int main(int argc, char* argv[])
43 43 ("long-description",
44 44 "thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace")
45 45 ("help", "Print help")
  46 + ("int", "An integer", cxxopts::value<int>())
46 47 ;
47 48  
48 49 options.parse_positional("positional");
... ... @@ -80,6 +81,11 @@ int main(int argc, char* argv[])
80 81 << std::endl;
81 82 }
82 83  
  84 + if (options.count("int"))
  85 + {
  86 + std::cout << "int = " << options["int"].as<int>() << std::endl;
  87 + }
  88 +
83 89 std::cout << "Arguments remain = " << argc << std::endl;
84 90  
85 91 } catch (const cxxopts::OptionException& e)
... ...