in-place conversion of (sub)string to double. Requires no heap.
| 459 | |
| 460 | // in-place conversion of (sub)string to double. Requires no heap. |
| 461 | static double myStod(const std::string& str, std::string::const_iterator from, std::string::const_iterator to, int base) |
| 462 | { |
| 463 | double result = 0.; |
| 464 | bool positivesign = true; |
| 465 | std::string::const_iterator it; |
| 466 | if ('+' == *from) { |
| 467 | it = from + 1; |
| 468 | } else if ('-' == *from) { |
| 469 | it = from + 1; |
| 470 | positivesign = false; |
| 471 | } else |
| 472 | it = from; |
| 473 | const std::size_t decimalsep = str.find('.', it-str.begin()); |
| 474 | int distance; |
| 475 | if (std::string::npos == decimalsep) { |
| 476 | distance = to - it; |
| 477 | } else if (decimalsep > (to - str.begin())) |
| 478 | return 0.; // error handling?? |
| 479 | else |
| 480 | distance = int(decimalsep)-(from - str.begin()); |
| 481 | auto digitval = [&](char c) { |
| 482 | if ((10 < base) && (c > '9')) |
| 483 | return 10 + std::tolower(c) - 'a'; |
| 484 | return c - '0'; |
| 485 | }; |
| 486 | for (; it!=to; ++it) { |
| 487 | if ('.' == *it) |
| 488 | continue; |
| 489 | --distance; |
| 490 | result += digitval(*it)* std::pow(base, distance); |
| 491 | } |
| 492 | return positivesign ? result : -result; |
| 493 | } |
| 494 | |
| 495 | // Assuming a limited support of built-in hexadecimal floats (see C99, C++17) that is a fall-back implementation. |
| 496 | // Performance has been optimized WRT to heap activity, however the calculation part is not optimized. |
no test coverage detected