Commit 18ad3b16595c856df936a84304f47c923f160ca3

Authored by Jarryd Beck
1 parent 65c13302

exception on parse error

src/cxxopts.hpp
@@ -28,6 +28,8 @@ THE SOFTWARE. @@ -28,6 +28,8 @@ THE SOFTWARE.
28 #include <exception> 28 #include <exception>
29 #include <sstream> 29 #include <sstream>
30 30
  31 +#include <iostream>
  32 +
31 namespace cxxopts 33 namespace cxxopts
32 { 34 {
33 class Value 35 class Value
@@ -41,97 +43,6 @@ namespace cxxopts @@ -41,97 +43,6 @@ namespace cxxopts
41 has_arg() const = 0; 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 class OptionException : public std::exception 46 class OptionException : public std::exception
136 { 47 {
137 public: 48 public:
@@ -238,6 +149,120 @@ namespace cxxopts @@ -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 class OptionAdder; 266 class OptionAdder;
242 267
243 class OptionDetails 268 class OptionDetails
src/example.cpp
@@ -43,6 +43,7 @@ int main(int argc, char* argv[]) @@ -43,6 +43,7 @@ int main(int argc, char* argv[])
43 ("long-description", 43 ("long-description",
44 "thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace") 44 "thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace")
45 ("help", "Print help") 45 ("help", "Print help")
  46 + ("int", "An integer", cxxopts::value<int>())
46 ; 47 ;
47 48
48 options.parse_positional("positional"); 49 options.parse_positional("positional");
@@ -80,6 +81,11 @@ int main(int argc, char* argv[]) @@ -80,6 +81,11 @@ int main(int argc, char* argv[])
80 << std::endl; 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 std::cout << "Arguments remain = " << argc << std::endl; 89 std::cout << "Arguments remain = " << argc << std::endl;
84 90
85 } catch (const cxxopts::OptionException& e) 91 } catch (const cxxopts::OptionException& e)