@@ -153,7 +153,7 @@ class Option
153153 {
154154 setDefault (defaultValue);
155155 d->type = getType<T>();
156- defaulted = true ;
156+ d-> defaulted = true ;
157157 }
158158 return *this ;
159159 }
@@ -170,80 +170,37 @@ class Option
170170
171171 std::vector<std::string>::const_iterator match (std::vector<std::string>::const_iterator argument, std::vector<std::string>::const_iterator end)
172172 {
173- std::vector<std::string>::const_iterator returnPosition = argument;
174173 KeyValue keyValue = getKeyValue (*argument);
175174
176- if (isLongNameArgument (keyValue.key ) || isShortNameArgument (keyValue.key ))
175+ if (keyValue.key .empty ())
176+ {
177+ if (isPositional ())
178+ {
179+ if (setValue (*argument))
180+ ++argument;
181+ }
182+ }
183+ else if (keyValue.key == longName () || keyValue.key == shortName ())
177184 {
178- ++argument;
179-
180185 if (d->type == Type::Bool)
181- *d->valueBinding .b = true ;
182- else
183186 {
184- if (keyValue.value .empty ())
185- {
186- if (argument == end)
187- throw (std::logic_error (" Missing value for option '" + longName () + " '" ));
188- else
189- {
190- keyValue.value = *argument;
191- ++argument;
192- }
193- }
194-
195- class ValueParseError : public std ::logic_error
196- {
197- public:
198- ValueParseError () :
199- std::logic_error (" ..." )
200- {
201-
202- }
203- };
187+ if (setValue (*argument))
188+ ++argument;
189+ }
190+ else if (keyValue.value .empty ())
191+ {
192+ std::vector<std::string>::const_iterator it = argument+1 ;
204193
205- try
206- {
207- switch (d->type )
208- {
209- case Type::Double:
210- if (isDouble (*argument))
211- *d->valueBinding .d = std::stod (*argument);
212- else
213- throw (ValueParseError ());
214- break ;
215- case Type::Integer:
216- if (isInteger (*argument))
217- *d->valueBinding .i = std::stoi (*argument);
218- else
219- throw (ValueParseError ());
220- break ;
221- case Type::LongLong:
222- if (isLongLong (*argument))
223- *d->valueBinding .l = std::stol (*argument);
224- else
225- throw (ValueParseError ());
226- break ;
227- case Type::String:
228- *d->valueBinding .s = *argument;
229- break ;
230- case Type::Undefined:
231- throw (std::logic_error (" Bind value is undefined" ));
232- break ;
233- case Type::Bool:
234- throw (std::logic_error (" Bool option should not be handled here" ));
235- break ;
236- }
237-
238- returnPosition = argument;
239- }
240- catch (ValueParseError&)
241- {
242- }
194+ if (it == end)
195+ throw (std::logic_error (" Missing value for option '" + longName () + " '" ));
196+ else if (setValue (*it))
197+ argument += 2 ;
243198 }
199+ else if (setValue (keyValue.value ))
200+ ++argument;
244201 }
245202
246- return returnPosition ;
203+ return argument ;
247204 }
248205
249206private:
@@ -299,6 +256,61 @@ class Option
299256 template <typename T> void setValueBinding (T*);
300257 template <typename T> Type getType () const ;
301258
259+ bool setValue (std::string value)
260+ {
261+ bool result = true ;
262+
263+ class ValueParseError : public std ::logic_error
264+ {
265+ public:
266+ ValueParseError () :
267+ std::logic_error (" ..." )
268+ {
269+
270+ }
271+ };
272+
273+ try
274+ {
275+ switch (d->type )
276+ {
277+ case Type::Bool:
278+ *d->valueBinding .b = true ;
279+ break ;
280+ case Type::Double:
281+ if (isDouble (value))
282+ *d->valueBinding .d = std::stod (value);
283+ else
284+ throw (ValueParseError ());
285+ break ;
286+ case Type::Integer:
287+ if (isInteger (value))
288+ *d->valueBinding .i = std::stoi (value);
289+ else
290+ throw (ValueParseError ());
291+ break ;
292+ case Type::LongLong:
293+ if (isLongLong (value))
294+ *d->valueBinding .l = std::stoll (value);
295+ else
296+ throw (ValueParseError ());
297+ break ;
298+ case Type::String:
299+ *d->valueBinding .s = value;
300+ break ;
301+ case Type::Undefined:
302+ throw (std::logic_error (" Bind value undefined for option '" + longName () + " '" ));
303+ break ;
304+ }
305+ }
306+ catch (ValueParseError&)
307+ {
308+ result = false ;
309+ }
310+
311+ return result;
312+ }
313+
302314 std::string getName () const
303315 {
304316 return d->longName .empty () ? " [Positional]" : " '" + d->longName + " '" ;
@@ -324,12 +336,14 @@ class Option
324336 KeyValue getKeyValue (std::string argument) const
325337 {
326338 KeyValue keyValue;
327- if (std::regex_match (argument, std::regex (" ^(--|-)[a-zA-Z\\ d]=.*" )))
339+ std::cmatch m;
340+ if (std::regex_match (argument.c_str (), m, std::regex (" ^(--|-)([a-zA-Z\\ d]+)((=(.*))|)" )))
328341 {
329- size_t pos = argument.find_first_of (' =' ) + 1 ;
330- keyValue.key = argument.substr (0 , pos);
331- keyValue.value = argument.substr (pos, argument.size () - pos);
342+ keyValue.key = m.size () > 2 ? std::string (m[2 ]) : " " ;
343+ keyValue.value = m.size () > 4 ? std::string (m[5 ]) : " " ;
332344 }
345+ else
346+ keyValue.value = argument;
333347 return keyValue;
334348 }
335349
@@ -355,17 +369,17 @@ class Option
355369
356370 bool isLongLong (std::string argument) const
357371 {
358- return isNumber (argument) && ( std::stoll (argument) < std::numeric_limits< int >:: min () || std::stoll (argument) > std::numeric_limits< int >:: max ()) ;
372+ return isNumber (argument);
359373 }
360374
361375 bool isDouble (std::string argument) const
362376 {
363- return std::regex_match (argument, std::regex (" ^(-|\\ d )\\ d+(.|,) \\ d+$" ));
377+ return std::regex_match (argument, std::regex (" ^(-|)\\ d+\\ . \\ d+$" ));
364378 }
365379
366380 bool isNumber (std::string argument) const
367381 {
368- return std::regex_match (argument, std::regex (" ^(-|\\ d )\\ d+$" ));
382+ return std::regex_match (argument, std::regex (" ^(-|)\\ d+$" ));
369383 }
370384
371385 bool isLongName (std::string longName) const
0 commit comments