35 #include <simplecpp.h>
59 for (std::size_t i = s.size() - 1U; i > 0U; --i) {
61 if (c ==
'u' || c ==
'U')
63 else if (c ==
'l' || c ==
'L') {
68 }
else if (i > 2U && c ==
'4' && s[i-1] ==
'6' && s[i-2] ==
'i')
76 std::ostringstream ostr;
78 if (std::isnan(mDoubleValue))
80 if (std::isinf(mDoubleValue))
81 return (mDoubleValue > 0) ?
"inf.0" :
"-inf.0";
84 ostr << std::fixed << mDoubleValue;
87 std::string ret(ostr.str());
88 std::string::size_type pos = ret.size() - 1U;
89 while (ret[pos] ==
'0')
94 return ret.substr(0, pos+1);
98 ostr << static_cast<biguint>(mIntValue) <<
"U";
111 if (mType < v.
mType) {
114 }
else if (mType == v.
mType) {
119 mDoubleValue = mIntValue;
164 throw InternalError(
nullptr,
"Internal Error: Division by zero");
166 throw InternalError(
nullptr,
"Internal Error: Division overflow");
171 throw InternalError(
nullptr,
"Internal Error: Division by zero");
199 throw InternalError(
nullptr,
"Internal Error: Division by zero");
201 throw InternalError(
nullptr,
"Internal Error: Division overflow");
206 throw InternalError(
nullptr,
"Internal Error: Division by zero");
240 if ((
unsigned long long)mIntValue < (
unsigned long long)v.
mIntValue)
242 if ((
unsigned long long)mIntValue > (
unsigned long long)v.
mIntValue)
267 throw InternalError(
nullptr,
"Shift operand is not integer");
279 throw InternalError(
nullptr,
"Shift operand is not integer");
294 const biguint ret = std::stoull(str,
nullptr, 16);
296 }
catch (
const std::out_of_range& ) {
297 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigUNumber: out_of_range: " + str);
298 }
catch (
const std::invalid_argument& ) {
299 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigUNumber: invalid_argument: " + str);
306 const biguint ret = std::stoull(str,
nullptr, 8);
308 }
catch (
const std::out_of_range& ) {
309 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigUNumber: out_of_range: " + str);
310 }
catch (
const std::invalid_argument& ) {
311 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigUNumber: invalid_argument: " + str);
318 for (std::string::size_type i = str[0] ==
'0'?2:3; i < str.length(); i++) {
319 if (str[i] !=
'1' && str[i] !=
'0')
335 if (doubleval > (
double)std::numeric_limits<biguint>::max())
336 return std::numeric_limits<biguint>::max();
342 return simplecpp::characterLiteralToLL(str);
346 const biguint ret = std::stoull(str, &idx, 10);
347 if (idx != str.size()) {
348 const std::string s = str.substr(idx);
350 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigUNumber: input was not completely consumed: " + str);
353 }
catch (
const std::out_of_range& ) {
354 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigUNumber: out_of_range: " + str);
355 }
catch (
const std::invalid_argument& ) {
356 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigUNumber: invalid_argument: " + str);
362 return std::accumulate(str.cbegin(), str.cend(), uint32_t(), [](uint32_t v,
char c) {
373 const biguint ret = std::stoull(str,
nullptr, 16);
375 }
catch (
const std::out_of_range& ) {
376 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigNumber: out_of_range: " + str);
377 }
catch (
const std::invalid_argument& ) {
378 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigNumber: invalid_argument: " + str);
385 const biguint ret = std::stoull(str,
nullptr, 8);
387 }
catch (
const std::out_of_range& ) {
388 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigNumber: out_of_range: " + str);
389 }
catch (
const std::invalid_argument& ) {
390 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigNumber: invalid_argument: " + str);
397 for (std::string::size_type i = str[0] ==
'0'?2:3; i < str.length(); i++) {
398 if (str[i] !=
'1' && str[i] !=
'0')
414 if (doubleval > (
double)std::numeric_limits<bigint>::max())
415 return std::numeric_limits<bigint>::max();
416 if (doubleval < (
double)std::numeric_limits<bigint>::min())
417 return std::numeric_limits<bigint>::min();
418 return static_cast<bigint>(doubleval);
422 return simplecpp::characterLiteralToLL(str);
426 const biguint ret = std::stoull(str, &idx, 10);
427 if (idx != str.size()) {
428 const std::string s = str.substr(idx);
430 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigNumber: input was not completely consumed: " + str);
433 }
catch (
const std::out_of_range& ) {
434 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigNumber: out_of_range: " + str);
435 }
catch (
const std::invalid_argument& ) {
436 throw InternalError(
nullptr,
"Internal Error. MathLib::toBigNumber: invalid_argument: " + str);
441 static double myStod(
const std::string& str, std::string::const_iterator from, std::string::const_iterator to,
int base)
444 bool positivesign =
true;
445 std::string::const_iterator it;
448 }
else if (
'-' == *from) {
450 positivesign =
false;
453 const std::size_t decimalsep = str.find(
'.', it-str.begin());
455 if (std::string::npos == decimalsep) {
457 }
else if (decimalsep > (to - str.begin()))
460 distance = int(decimalsep)-(from - str.begin());
461 auto digitval = [&](
char c) {
462 if ((10 < base) && (c >
'9'))
463 return 10 + std::tolower(c) -
'a';
466 for (; it!=to; ++it) {
470 result += digitval(*it)* std::pow(base, distance);
472 return positivesign ? result : -result;
479 const std::size_t p = str.find_first_of(
"pP",3);
480 const double factor1 =
myStod(str, str.cbegin() + 2, str.cbegin()+p, 16);
481 const bool suffix = (str.back() ==
'f') || (str.back() ==
'F') || (str.back() ==
'l') || (str.back() ==
'L');
482 const double exponent =
myStod(str, str.cbegin() + p + 1, suffix ? str.cend()-1:str.cend(), 10);
483 const double factor2 = std::pow(2, exponent);
484 return factor1 * factor2;
491 return simplecpp::characterLiteralToLL(str);
492 }
catch (
const std::exception& e) {
493 throw InternalError(
nullptr,
"Internal Error. MathLib::toDoubleNumber: characterLiteralToLL(" + str +
") => " + e.what());
498 #ifdef _LIBCPP_VERSION
502 return std::strtod(str.c_str(),
nullptr);
507 std::istringstream istr(str);
508 istr.imbue(std::locale::classic());
511 throw InternalError(
nullptr,
"Internal Error. MathLib::toDoubleNumber: conversion failed: " + str);
517 throw InternalError(
nullptr,
"Internal Error. MathLib::toDoubleNumber: input was not completely consumed: " + str);
522 template<> std::string MathLib::toString<double>(
double value)
524 std::ostringstream result;
525 result.precision(12);
527 std::string s = result.
str();
530 if (s.find_first_of(
".e") == std::string::npos)
545 START, BASE_DIGITS1, LEADING_DECIMAL, TRAILING_DECIMAL, BASE_DIGITS2, E, MANTISSA_PLUSMINUS, MANTISSA_DIGITS, SUFFIX_F, SUFFIX_L, SUFFIX_LITERAL_LEADER, SUFFIX_LITERAL
546 } state = State::START;
547 std::string::const_iterator it = str.cbegin();
548 if (
'+' == *it ||
'-' == *it)
550 for (; it != str.cend(); ++it) {
554 state = State::LEADING_DECIMAL;
555 else if (std::isdigit(
static_cast<unsigned char>(*it)))
556 state = State::BASE_DIGITS1;
560 case State::LEADING_DECIMAL:
561 if (std::isdigit(
static_cast<unsigned char>(*it)))
562 state = State::BASE_DIGITS2;
566 case State::BASE_DIGITS1:
567 if (*it==
'e' || *it==
'E')
570 state = State::TRAILING_DECIMAL;
571 else if (!std::isdigit(
static_cast<unsigned char>(*it)))
574 case State::TRAILING_DECIMAL:
575 if (*it==
'e' || *it==
'E')
577 else if (*it==
'f' || *it==
'F')
578 state = State::SUFFIX_F;
579 else if (*it==
'l' || *it==
'L')
580 state = State::SUFFIX_L;
582 state = State::SUFFIX_LITERAL_LEADER;
583 else if (std::isdigit(
static_cast<unsigned char>(*it)))
584 state = State::BASE_DIGITS2;
588 case State::BASE_DIGITS2:
589 if (*it==
'e' || *it==
'E')
591 else if (*it==
'f' || *it==
'F')
592 state = State::SUFFIX_F;
593 else if (*it==
'l' || *it==
'L')
594 state = State::SUFFIX_L;
596 state = State::SUFFIX_LITERAL_LEADER;
597 else if (!std::isdigit(
static_cast<unsigned char>(*it)))
601 if (*it==
'+' || *it==
'-')
602 state = State::MANTISSA_PLUSMINUS;
603 else if (std::isdigit(
static_cast<unsigned char>(*it)))
604 state = State::MANTISSA_DIGITS;
608 case State::MANTISSA_PLUSMINUS:
609 if (!std::isdigit(
static_cast<unsigned char>(*it)))
612 state = State::MANTISSA_DIGITS;
614 case State::MANTISSA_DIGITS:
615 if (*it==
'f' || *it==
'F')
616 state = State::SUFFIX_F;
617 else if (*it==
'l' || *it==
'L')
618 state = State::SUFFIX_L;
619 else if (!std::isdigit(
static_cast<unsigned char>(*it)))
623 case State::SUFFIX_LITERAL:
624 case State::SUFFIX_LITERAL_LEADER:
625 state = State::SUFFIX_LITERAL;
627 case State::SUFFIX_F:
629 case State::SUFFIX_L:
633 return (state==State::BASE_DIGITS2 || state==State::MANTISSA_DIGITS || state==State::TRAILING_DECIMAL || state==State::SUFFIX_F || state==State::SUFFIX_L || (state==State::SUFFIX_LITERAL));
640 return (str[0] ==
'-');
650 static bool isValidIntegerSuffixIt(std::string::const_iterator it, std::string::const_iterator end,
bool supportMicrosoftExtensions=
true)
652 enum class Status { START, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_UZ, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU, SUFFIX_I, SUFFIX_I6, SUFFIX_I64, SUFFIX_UI, SUFFIX_UI6, SUFFIX_UI64, SUFFIX_Z, SUFFIX_LITERAL_LEADER, SUFFIX_LITERAL } state = Status::START;
653 for (; it != end; ++it) {
656 if (*it ==
'u' || *it ==
'U')
657 state = Status::SUFFIX_U;
658 else if (*it ==
'l' || *it ==
'L')
659 state = Status::SUFFIX_L;
660 else if (*it ==
'z' || *it ==
'Z')
661 state = Status::SUFFIX_Z;
662 else if (supportMicrosoftExtensions && (*it ==
'i' || *it ==
'I'))
663 state = Status::SUFFIX_I;
665 state = Status::SUFFIX_LITERAL_LEADER;
669 case Status::SUFFIX_U:
670 if (*it ==
'l' || *it ==
'L')
671 state = Status::SUFFIX_UL;
672 else if (*it ==
'z' || *it ==
'Z')
673 state = Status::SUFFIX_UZ;
674 else if (supportMicrosoftExtensions && (*it ==
'i' || *it ==
'I'))
675 state = Status::SUFFIX_UI;
679 case Status::SUFFIX_UL:
680 if (*it ==
'l' || *it ==
'L')
681 state = Status::SUFFIX_ULL;
685 case Status::SUFFIX_L:
686 if (*it ==
'u' || *it ==
'U')
687 state = Status::SUFFIX_LU;
688 else if (*it ==
'l' || *it ==
'L')
689 state = Status::SUFFIX_LL;
693 case Status::SUFFIX_LU:
695 case Status::SUFFIX_LL:
696 if (*it ==
'u' || *it ==
'U')
697 state = Status::SUFFIX_LLU;
701 case Status::SUFFIX_I:
703 state = Status::SUFFIX_I6;
707 case Status::SUFFIX_I6:
709 state = Status::SUFFIX_I64;
713 case Status::SUFFIX_UI:
715 state = Status::SUFFIX_UI6;
719 case Status::SUFFIX_UI6:
721 state = Status::SUFFIX_UI64;
725 case Status::SUFFIX_Z:
726 if (*it ==
'u' || *it ==
'U')
727 state = Status::SUFFIX_UZ;
732 case Status::SUFFIX_LITERAL:
733 case Status::SUFFIX_LITERAL_LEADER:
734 state = Status::SUFFIX_LITERAL;
740 return ((state == Status::SUFFIX_U) ||
741 (state == Status::SUFFIX_L) ||
742 (state == Status::SUFFIX_Z) ||
743 (state == Status::SUFFIX_UL) ||
744 (state == Status::SUFFIX_UZ) ||
745 (state == Status::SUFFIX_LU) ||
746 (state == Status::SUFFIX_LL) ||
747 (state == Status::SUFFIX_ULL) ||
748 (state == Status::SUFFIX_LLU) ||
749 (state == Status::SUFFIX_I64) ||
750 (state == Status::SUFFIX_UI64) ||
751 (state == Status::SUFFIX_LITERAL));
774 START, OCTAL_PREFIX, DIGITS
775 } state = Status::START;
778 std::string::const_iterator it = str.cbegin();
779 if (
'+' == *it ||
'-' == *it)
781 for (; it != str.cend(); ++it) {
785 state = Status::OCTAL_PREFIX;
789 case Status::OCTAL_PREFIX:
791 state = Status::DIGITS;
797 state = Status::DIGITS;
803 return state == Status::DIGITS;
809 START, HEX_0, HEX_X, DIGIT
810 } state = Status::START;
813 std::string::const_iterator it = str.cbegin();
814 if (
'+' == *it ||
'-' == *it)
816 for (; it != str.cend(); ++it) {
820 state = Status::HEX_0;
825 if (*it ==
'x' || *it ==
'X')
826 state = Status::HEX_X;
831 if (isxdigit(
static_cast<unsigned char>(*it)))
832 state = Status::DIGIT;
837 if (isxdigit(
static_cast<unsigned char>(*it)))
844 return Status::DIGIT == state;
850 START, HEX_0, HEX_X, WHOLE_NUMBER_DIGIT, POINT, FRACTION, EXPONENT_P, EXPONENT_SIGN, EXPONENT_DIGITS, EXPONENT_SUFFIX
851 } state = Status::START;
854 std::string::const_iterator it = str.cbegin();
855 if (
'+' == *it ||
'-' == *it)
857 for (; it != str.cend(); ++it) {
861 state = Status::HEX_0;
866 if (*it ==
'x' || *it ==
'X')
867 state = Status::HEX_X;
872 if (isxdigit(
static_cast<unsigned char>(*it)))
873 state = Status::WHOLE_NUMBER_DIGIT;
875 state = Status::POINT;
879 case Status::WHOLE_NUMBER_DIGIT:
880 if (isxdigit(
static_cast<unsigned char>(*it)))
883 state = Status::FRACTION;
884 else if (*it==
'p' || *it==
'P')
885 state = Status::EXPONENT_P;
890 case Status::FRACTION:
891 if (isxdigit(
static_cast<unsigned char>(*it)))
892 state = Status::FRACTION;
893 else if (*it ==
'p' || *it ==
'P')
894 state = Status::EXPONENT_P;
898 case Status::EXPONENT_P:
899 if (isdigit(
static_cast<unsigned char>(*it)))
900 state = Status::EXPONENT_DIGITS;
901 else if (*it ==
'+' || *it ==
'-')
902 state = Status::EXPONENT_SIGN;
906 case Status::EXPONENT_SIGN:
907 if (isdigit(
static_cast<unsigned char>(*it)))
908 state = Status::EXPONENT_DIGITS;
912 case Status::EXPONENT_DIGITS:
913 if (isdigit(
static_cast<unsigned char>(*it)))
915 else if (*it ==
'f' || *it ==
'F' || *it ==
'l' || *it ==
'L')
916 state = Status::EXPONENT_SUFFIX;
920 case Status::EXPONENT_SUFFIX:
924 return (Status::EXPONENT_DIGITS == state) || (Status::EXPONENT_SUFFIX == state);
940 START, GNU_BIN_PREFIX_0, GNU_BIN_PREFIX_B, DIGIT
941 } state = Status::START;
944 std::string::const_iterator it = str.cbegin();
945 if (
'+' == *it ||
'-' == *it)
947 for (; it != str.cend(); ++it) {
951 state = Status::GNU_BIN_PREFIX_0;
955 case Status::GNU_BIN_PREFIX_0:
956 if (*it ==
'b' || *it ==
'B')
957 state = Status::GNU_BIN_PREFIX_B;
961 case Status::GNU_BIN_PREFIX_B:
962 if (*it ==
'0' || *it ==
'1')
963 state = Status::DIGIT;
968 if (*it ==
'0' || *it ==
'1')
975 return state == Status::DIGIT;
982 } state = Status::START;
985 std::string::const_iterator it = str.cbegin();
986 if (
'+' == *it ||
'-' == *it)
988 for (; it != str.cend(); ++it) {
991 if (isdigit(
static_cast<unsigned char>(*it)))
992 state = Status::DIGIT;
997 if (isdigit(
static_cast<unsigned char>(*it)))
998 state = Status::DIGIT;
1004 return state == Status::DIGIT;
1019 bool isUnsigned =
false;
1020 unsigned int longState = 0;
1021 for (std::size_t i = 1U; i <
value.size(); ++i) {
1023 if (c ==
'u' || c ==
'U')
1025 else if (c ==
'L' || c ==
'l')
1030 return isUnsigned ?
"U" :
"";
1032 return isUnsigned ?
"UL" :
"L";
1034 return isUnsigned ?
"ULL" :
"LL";
1038 static std::string
intsuffix(
const std::string & first,
const std::string & second)
1042 if (suffix1 ==
"ULL" || suffix2 ==
"ULL")
1044 if (suffix1 ==
"LL" || suffix2 ==
"LL")
1046 if (suffix1 ==
"UL" || suffix2 ==
"UL")
1048 if (suffix1 ==
"L" || suffix2 ==
"L")
1050 if (suffix1 ==
"U" || suffix2 ==
"U")
1053 return suffix1.empty() ? suffix2 : suffix1;
1056 std::string
MathLib::add(
const std::string & first,
const std::string & second)
1058 #ifdef TEST_MATHLIB_VALUE
1069 while (d1 > 100000.0 * d2 &&
toString(d1+d2)==first && ++count<5)
1071 while (d2 > 100000.0 * d1 &&
toString(d1+d2)==second && ++count<5)
1080 #ifdef TEST_MATHLIB_VALUE
1087 if (first == second)
1094 while (d1 > 100000.0 * d2 &&
toString(d1-d2)==first && ++count<5)
1096 while (d2 > 100000.0 * d1 &&
toString(d1-d2)==second && ++count<5)
1105 #ifdef TEST_MATHLIB_VALUE
1112 throw InternalError(
nullptr,
"Internal Error: Division by zero");
1113 if (a == std::numeric_limits<bigint>::min() && std::abs(b)<=1)
1114 throw InternalError(
nullptr,
"Internal Error: Division overflow");
1128 #ifdef TEST_MATHLIB_VALUE
1138 std::string
MathLib::mod(
const std::string &first,
const std::string &second)
1140 #ifdef TEST_MATHLIB_VALUE
1146 throw InternalError(
nullptr,
"Internal Error: Division by zero");
1181 throw InternalError(
nullptr, std::string(
"Unexpected action '") + action +
"' in MathLib::calculate(). Please report this to Cppcheck developers.");
1205 return tok.substr(1, tok.length() - 1);
1218 return !
isEqual(first, second);
1255 if (str.empty() || (!std::isdigit(
static_cast<unsigned char>(str[0])) && (str[0] !=
'.' && str[0] !=
'-' && str[0] !=
'+')))
1261 for (
const char i : str) {
1262 if (std::isdigit(
static_cast<unsigned char>(i)) && i !=
'0')
1264 if (i ==
'p' || i ==
'P' || (!isHex && (i ==
'E' || i ==
'e')))
1266 if (isHex && isxdigit(i) && i !=
'0')
1274 return (c >=
'0' && c <=
'7');
1279 if (iPos == 0 || iPos >= iCode.size() || iCode[iPos] !=
'\'')
1281 std::string::size_type i = iPos - 1;
1282 while (std::isxdigit(iCode[i])) {
enum MathLib::value::Type mType
value shiftLeft(const value &v) const
value shiftRight(const value &v) const
int compare(const value &v) const
value(const std::string &s)
void promote(const value &v)
double getDoubleValue() const
static value calc(char op, const value &v1, const value &v2)
static bool isValidIntegerSuffix(const std::string &str, bool supportMicrosoftExtensions=true)
Only used in unit tests.
static std::string toString(T value)=delete
static biguint toBigUNumber(const std::string &str)
for conversion of numeric literals - for atoi-like conversions please use strToInt()
static bool isLessEqual(const std::string &first, const std::string &second)
static std::string divide(const std::string &first, const std::string &second)
static bool isDigitSeparator(const std::string &iCode, std::string::size_type iPos)
static bool isOct(const std::string &str)
Does the string represent an octal number? In case leading or trailing white space is provided,...
static bool isEqual(const std::string &first, const std::string &second)
static std::string sin(const std::string &tok)
static bool isGreaterEqual(const std::string &first, const std::string &second)
static const int bigint_bits
static bool isOctalDigit(char c)
Return true if given character is 0,1,2,3,4,5,6 or 7.
static bool isNotEqual(const std::string &first, const std::string &second)
static std::string subtract(const std::string &first, const std::string &second)
static bigint toBigNumber(const std::string &str)
for conversion of numeric literals - for atoi-like conversions please use strToInt()
static std::string calculate(const std::string &first, const std::string &second, char action)
static std::string cos(const std::string &tok)
static bool isDecimalFloat(const std::string &str)
static bool isGreater(const std::string &first, const std::string &second)
static bool isFloat(const std::string &str)
static unsigned int encodeMultiChar(const std::string &str)
static bool isDec(const std::string &str)
static bool isBin(const std::string &str)
Does the string represent a binary number? In case leading or trailing white space is provided,...
static std::string mod(const std::string &first, const std::string &second)
static std::string add(const std::string &first, const std::string &second)
static bool isIntHex(const std::string &str)
static bool isNullValue(const std::string &str)
Does the string represent the numerical value of 0? In case leading or trailing white space is provid...
static std::string abs(const std::string &tok)
static bool isNegative(const std::string &str)
static bool isFloatHex(const std::string &str)
static bool isInt(const std::string &str)
static bool isLess(const std::string &first, const std::string &second)
static std::string multiply(const std::string &first, const std::string &second)
static double toDoubleNumber(const std::string &str)
for conversion of numeric literals
unsigned long long biguint
static std::string tan(const std::string &tok)
static bool isPositive(const std::string &str)
static std::string getSuffix(const std::string &value)
MathLib::value operator&(const MathLib::value &v1, const MathLib::value &v2)
MathLib::value operator%(const MathLib::value &v1, const MathLib::value &v2)
MathLib::value operator-(const MathLib::value &v1, const MathLib::value &v2)
MathLib::value operator|(const MathLib::value &v1, const MathLib::value &v2)
MathLib::value operator<<(const MathLib::value &v1, const MathLib::value &v2)
MathLib::value operator>>(const MathLib::value &v1, const MathLib::value &v2)
MathLib::value operator*(const MathLib::value &v1, const MathLib::value &v2)
MathLib::value operator/(const MathLib::value &v1, const MathLib::value &v2)
MathLib::value operator^(const MathLib::value &v1, const MathLib::value &v2)
MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2)
static double myStod(const std::string &str, std::string::const_iterator from, std::string::const_iterator to, int base)
static std::string intsuffix(const std::string &first, const std::string &second)
static double floatHexToDoubleNumber(const std::string &str)
static bool isValidIntegerSuffixIt(std::string::const_iterator it, std::string::const_iterator end, bool supportMicrosoftExtensions=true)
Simple container to be thrown when internal error is detected.
static bool isCharLiteral(const std::string &str)