14
14
#include < functional> // std::hash
15
15
#include < iosfwd>
16
16
#include < stdexcept>
17
+ #include < cstdlib> // std::strtol
18
+ #include < cerrno> // errno, ERANGE
17
19
18
20
namespace docopt {
19
21
@@ -58,9 +60,13 @@ namespace docopt {
58
60
59
61
// Throws std::invalid_argument if the type does not match
60
62
bool asBool () const ;
63
+ bool asBoolOr (const bool value) const noexcept ;
61
64
long asLong () const ;
65
+ long asLongOr (const long value) const noexcept ;
62
66
std::string const & asString () const ;
67
+ std::string const & asStringOr (std::string const & value) const noexcept ;
63
68
std::vector<std::string> const & asStringList () const ;
69
+ std::vector<std::string> const & asStringListOr (std::vector<std::string> const & value) const noexcept ;
64
70
65
71
size_t hash () const noexcept ;
66
72
@@ -274,6 +280,16 @@ namespace docopt {
274
280
return variant_.boolValue ;
275
281
}
276
282
283
+ inline
284
+ bool value::asBoolOr (const bool value) const noexcept
285
+ {
286
+ if (!isBool ())
287
+ {
288
+ return value;
289
+ }
290
+ return variant_.boolValue ;
291
+ }
292
+
277
293
inline
278
294
long value::asLong () const
279
295
{
@@ -292,20 +308,68 @@ namespace docopt {
292
308
return variant_.longValue ;
293
309
}
294
310
311
+ inline
312
+ long value::asLongOr (const long value) const noexcept
313
+ {
314
+ // Attempt to convert a string to a long
315
+ if (isString ()) {
316
+ const std::string& str = variant_.strValue ;
317
+ char * str_end;
318
+ const long ret = std::strtol (str.c_str (), &str_end, 10 );
319
+ // Case 1: No Conversion was possible, return given default value
320
+ if (str_end == str.c_str () && ret == 0 )
321
+ {
322
+ return value;
323
+ }
324
+ // Case 2: Parsed value is out of range, return given default value
325
+ if (errno == ERANGE) {
326
+ return value;
327
+ }
328
+ // Case 3: Everything is fine, return parsed value
329
+ return ret;
330
+ }
331
+ if (!isLong ())
332
+ {
333
+ return value;
334
+ }
335
+ return variant_.longValue ;
336
+ }
337
+
295
338
inline
296
339
std::string const & value::asString () const
297
340
{
298
341
throwIfNotKind (Kind::String);
299
342
return variant_.strValue ;
300
343
}
301
344
345
+ inline
346
+ std::string const & value::asStringOr (std::string const & value) const noexcept
347
+ {
348
+ if (!isString ())
349
+ {
350
+ return value;
351
+ }
352
+ return variant_.strValue ;
353
+ }
354
+
355
+
302
356
inline
303
357
std::vector<std::string> const & value::asStringList () const
304
358
{
305
359
throwIfNotKind (Kind::StringList);
306
360
return variant_.strList ;
307
361
}
308
362
363
+ inline
364
+ std::vector<std::string> const & value::asStringListOr (std::vector<std::string> const & value) const noexcept
365
+ {
366
+ if (!isStringList ())
367
+ {
368
+ return value;
369
+ }
370
+ return variant_.strList ;
371
+ }
372
+
309
373
inline
310
374
bool operator ==(value const & v1, value const & v2)
311
375
{
0 commit comments