1414#include  < functional> //  std::hash
1515#include  < iosfwd> 
1616#include  < stdexcept> 
17+ #include  < cstdlib> //  std::strtol
18+ #include  < cerrno> //  errno, ERANGE
1719
1820namespace  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