Skip to content

Commit c9fe809

Browse files
committed
Add docopt::value::asBoolOr(bool) function
Add docopt::value::asStringOr(string) function Add docopt::value::asLongOr(long) function Add docopt::value::asStringList(StringList) function
1 parent 41f9b84 commit c9fe809

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

docopt_value.h

+64
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <functional> // std::hash
1515
#include <iosfwd>
1616
#include <stdexcept>
17+
#include <cstdlib> // std::strtol
18+
#include <cerrno> // errno, ERANGE
1719

1820
namespace docopt {
1921

@@ -58,9 +60,13 @@ namespace docopt {
5860

5961
// Throws std::invalid_argument if the type does not match
6062
bool asBool() const;
63+
bool asBoolOr(const bool value) const noexcept;
6164
long asLong() const;
65+
long asLongOr(const long value) const noexcept;
6266
std::string const& asString() const;
67+
std::string const& asStringOr(std::string const& value) const noexcept;
6368
std::vector<std::string> const& asStringList() const;
69+
std::vector<std::string> const& asStringListOr(std::vector<std::string> const& value) const noexcept;
6470

6571
size_t hash() const noexcept;
6672

@@ -274,6 +280,16 @@ namespace docopt {
274280
return variant_.boolValue;
275281
}
276282

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+
277293
inline
278294
long value::asLong() const
279295
{
@@ -292,20 +308,68 @@ namespace docopt {
292308
return variant_.longValue;
293309
}
294310

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+
295338
inline
296339
std::string const& value::asString() const
297340
{
298341
throwIfNotKind(Kind::String);
299342
return variant_.strValue;
300343
}
301344

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+
302356
inline
303357
std::vector<std::string> const& value::asStringList() const
304358
{
305359
throwIfNotKind(Kind::StringList);
306360
return variant_.strList;
307361
}
308362

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+
309373
inline
310374
bool operator==(value const& v1, value const& v2)
311375
{

0 commit comments

Comments
 (0)