MCPcopy Create free account
hub / github.com/audacity/audacity / FastStringToInt

Function FastStringToInt

libraries/lib-string-utils/FromChars.cpp:58–122  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

56
57template <typename ResultType>
58FromCharsResult FastStringToInt(
59 const char* first, const char* last, ResultType& value,
60 bool isNegative) noexcept
61{
62 using UnsignedResultType = std::make_unsigned_t<ResultType>;
63
64 const auto availableBytes = last - first;
65
66 if (availableBytes <= 0)
67 return { first, std::errc::invalid_argument };
68
69 UnsignedResultType result = digitToInt(*first);
70
71 if (result > 10)
72 return { first, std::errc::invalid_argument };
73
74 constexpr auto maxSafeDigits = std::numeric_limits<ResultType>::digits10;
75
76 const char* ptr = first;
77 const char* safeLast =
78 first + std::min<decltype(availableBytes)>(availableBytes, maxSafeDigits);
79
80 unsigned d;
81
82 // No integer overflow here
83 while (++ptr < safeLast && (d = digitToInt(*ptr)) <= 9)
84 {
85 result = result * 10 + d;
86 }
87
88 // But here live dragons
89 while (ptr < last && (d = digitToInt(*ptr)) <= 9)
90 {
91 if (!safeMul10Add<UnsignedResultType>(result, result, d))
92 return { ptr, std::errc::result_out_of_range };
93
94 // Even if there were no unsigned overflow,
95 // signed overflow is still possible
96 if constexpr (std::is_signed_v<ResultType>)
97 {
98 const UnsignedResultType max =
99 static_cast<UnsignedResultType>(
100 std::numeric_limits<ResultType>::max()) +
101 (isNegative ? 1 : 0);
102
103 if (result > max)
104 return { ptr, std::errc::result_out_of_range };
105 }
106
107
108 ++ptr;
109 }
110
111 if constexpr (std::is_signed_v<ResultType>)
112 {
113 value = isNegative ?
114 // Unary minus on unsigned type makes MSVC unhappy
115 static_cast<ResultType>(0 - result) :

Callers 1

IntFromCharsFunction · 0.85

Calls 2

digitToIntFunction · 0.85
maxFunction · 0.85

Tested by

no test coverage detected