80 const std::string name = ion_name.substr(0, ion_name.find_first_of(
"\r\n"));
81 if (name.empty()) {
return 0; }
84 auto toCharge = [&name](std::string::size_type begin, std::string::size_type end,
bool negative,
int& out) {
85 if (end <= begin || (end - begin) > 10) {
return false; }
87 for (std::string::size_type i = begin; i < end; ++i) { value = value * 10 + (name[i] -
'0'); }
88 if (negative) { value = -value; }
89 if (value < (
long long)INT_MIN || value > (
long long)INT_MAX) {
return false; }
98 const std::string::size_type caret = name.rfind(
'^');
99 if (caret != std::string::npos)
101 std::string::size_type c = caret + 1;
102 const bool negative = (c < name.size() && name[c] ==
'-');
103 if (c < name.size() && (name[c] ==
'+' || name[c] ==
'-')) { ++c; }
104 std::string::size_type end = c;
105 while (end < name.size() && std::isdigit((
unsigned char)name[end])) { ++end; }
107 const bool token_ends = (end == name.size() || name[end] ==
'/' || name[end] ==
'*');
109 if (token_ends && toCharge(c, end, negative, value)) {
return value; }
112 const char last = name.back();
115 if (last ==
'+' || last ==
'-')
117 std::string::size_type run = name.size();
118 while (run > 0 && name[run - 1] == last) { --run; }
119 const int count = (int)(name.size() - run);
120 return (last ==
'-') ? -count : count;
127 if (std::isdigit((
unsigned char)last) && name.find_first_of(
"/*") == std::string::npos)
129 std::string::size_type d = name.size();
130 while (d > 0 && std::isdigit((
unsigned char)name[d - 1])) { --d; }
132 if (d > 0 && (name[d - 1] ==
'+' || name[d - 1] ==
'-') && toCharge(d, name.size(), name[d - 1] ==
'-', value))
182 if (ion_name.empty() || std::isalpha((
unsigned char)ion_name[0]) == 0) {
return 0; }
183 std::string::size_type end = 1;
184 while (end < ion_name.size() && std::isdigit((
unsigned char)ion_name[end])) { ++end; }
185 if (end == 1) {
return 0; }
187 if (end - 1 > 9) {
return 0; }
189 for (std::string::size_type i = 1; i < end; ++i) { value = value * 10 + (
UInt)(ion_name[i] -
'0'); }