60parse(
const std::string &s) {
61 using UnsignedType =
typename std::make_unsigned<IntegralType>::type;
67 const char *sptr = s.c_str();
70 if (
'-' == *sptr ||
'+' == *sptr) {
71 if (std::numeric_limits<IntegralType>::is_signed) {
74 return Error(
"syntax error: sign not allowed for unsigned types");
78 return Error(
"syntax error: separator not allowed before first digit");
81 UnsignedType radix = 10;
82 if (strncmp(
"0x", sptr, 2) == 0 || strncmp(
"0X", sptr, 2) == 0) {
85 }
else if (strncmp(
"0b", sptr, 2) == 0) {
91 if (radix != 10 &&
'_' == *sptr)
97 for (
size_t i = 0; sptr[i]; ++i) {
99 if (0 == i ||
'_' == sptr[i-1] || !sptr[i+1])
100 return Error(
"syntax error: invalid use of digit separator");
106 const UnsignedType shifted = n * radix;
107 if ((n != 0 && shifted / n != radix) || *digit > std::numeric_limits<UnsignedType>::max() - shifted) {
109 return Error(
"overflow error: less than minimum value for type");
111 return Error(
"overflow error: greater than maximum value for type");
115 n = shifted + *digit;
117 return Error(
"syntax error: invalid digit after parsing " + boost::lexical_cast<std::string>(nDigits) +
118 (1==nDigits ?
" digit" :
" digits"));
122 return Error(
"syntax error: digits expected");
125 if (std::numeric_limits<IntegralType>::is_signed) {
126 const UnsignedType signBit = (UnsignedType)1 << (8*
sizeof(IntegralType) - 1);
128 if (n & signBit && n != signBit)
129 return Error(
"overflow error: less than minimum value for type");
130 return Ok((IntegralType)(~n + 1));
131 }
else if (n & signBit) {
132 return Error(
"overflow error: greater than maximum value for type");
134 return Ok((IntegralType)n);
137 return Ok((IntegralType)n);
Sawyer::Optional< typename std::enable_if< std::is_integral< IntegralType >::value, IntegralType >::type > toDigit(char ch, IntegralType radix=10)
Convert a character to a numeric digit.