| 865 | |
| 866 | template <typename T> |
| 867 | void |
| 868 | integer_parser(const std::string& text, T& value) |
| 869 | { |
| 870 | parser_tool::IntegerDesc int_desc = parser_tool::SplitInteger(text); |
| 871 | |
| 872 | using US = typename std::make_unsigned<T>::type; |
| 873 | constexpr bool is_signed = std::numeric_limits<T>::is_signed; |
| 874 | |
| 875 | const bool negative = int_desc.negative.length() > 0; |
| 876 | const uint8_t base = int_desc.base.length() > 0 ? 16 : 10; |
| 877 | const std::string & value_match = int_desc.value; |
| 878 | |
| 879 | US result = 0; |
| 880 | |
| 881 | for (char ch : value_match) |
| 882 | { |
| 883 | US digit = 0; |
| 884 | |
| 885 | if (ch >= '0' && ch <= '9') |
| 886 | { |
| 887 | digit = static_cast<US>(ch - '0'); |
| 888 | } |
| 889 | else if (base == 16 && ch >= 'a' && ch <= 'f') |
| 890 | { |
| 891 | digit = static_cast<US>(ch - 'a' + 10); |
| 892 | } |
| 893 | else if (base == 16 && ch >= 'A' && ch <= 'F') |
| 894 | { |
| 895 | digit = static_cast<US>(ch - 'A' + 10); |
| 896 | } |
| 897 | else |
| 898 | { |
| 899 | throw_or_mimic<argument_incorrect_type>(text); |
| 900 | } |
| 901 | |
| 902 | const US next = static_cast<US>(result * base + digit); |
| 903 | if (result > next) |
| 904 | { |
| 905 | throw_or_mimic<argument_incorrect_type>(text); |
| 906 | } |
| 907 | |
| 908 | result = next; |
| 909 | } |
| 910 | |
| 911 | detail::check_signed_range<T>(negative, result, text); |
| 912 | |
| 913 | if (negative) |
| 914 | { |
| 915 | checked_negate<T>(value, result, text, std::integral_constant<bool, is_signed>()); |
| 916 | } |
| 917 | else |
| 918 | { |
| 919 | value = static_cast<T>(result); |
| 920 | } |
| 921 | } |
| 922 | |
| 923 | template <typename T> |
| 924 | void stringstream_parser(const std::string& text, T& value) |
no test coverage detected