diff options
Diffstat (limited to 'absl/strings/numbers.cc')
-rw-r--r-- | absl/strings/numbers.cc | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index c4f21030..b57d9e82 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -34,6 +34,7 @@ #include "absl/base/config.h" #include "absl/base/internal/endian.h" #include "absl/base/internal/raw_logging.h" +#include "absl/base/nullability.h" #include "absl/base/optimization.h" #include "absl/numeric/bits.h" #include "absl/numeric/int128.h" @@ -45,7 +46,7 @@ namespace absl { ABSL_NAMESPACE_BEGIN -bool SimpleAtof(absl::string_view str, float* out) { +bool SimpleAtof(absl::string_view str, absl::Nonnull<float*> out) { *out = 0.0; str = StripAsciiWhitespace(str); // std::from_chars doesn't accept an initial +, but SimpleAtof does, so if one @@ -76,7 +77,7 @@ bool SimpleAtof(absl::string_view str, float* out) { return true; } -bool SimpleAtod(absl::string_view str, double* out) { +bool SimpleAtod(absl::string_view str, absl::Nonnull<double*> out) { *out = 0.0; str = StripAsciiWhitespace(str); // std::from_chars doesn't accept an initial +, but SimpleAtod does, so if one @@ -107,7 +108,7 @@ bool SimpleAtod(absl::string_view str, double* out) { return true; } -bool SimpleAtob(absl::string_view str, bool* out) { +bool SimpleAtob(absl::string_view str, absl::Nonnull<bool*> out) { ABSL_RAW_CHECK(out != nullptr, "Output pointer must not be nullptr."); if (EqualsIgnoreCase(str, "true") || EqualsIgnoreCase(str, "t") || EqualsIgnoreCase(str, "yes") || EqualsIgnoreCase(str, "y") || @@ -166,7 +167,7 @@ constexpr uint64_t kDivisionBy100Mul = 10486u; constexpr uint64_t kDivisionBy100Div = 1 << 20; // Encode functions write the ASCII output of input `n` to `out_str`. -inline char* EncodeHundred(uint32_t n, char* out_str) { +inline char* EncodeHundred(uint32_t n, absl::Nonnull<char*> out_str) { int num_digits = static_cast<int>(n - 10) >> 8; uint32_t div10 = (n * kDivisionBy10Mul) / kDivisionBy10Div; uint32_t mod10 = n - 10u * div10; @@ -176,7 +177,7 @@ inline char* EncodeHundred(uint32_t n, char* out_str) { return out_str + 2 + num_digits; } -inline char* EncodeTenThousand(uint32_t n, char* out_str) { +inline char* EncodeTenThousand(uint32_t n, absl::Nonnull<char*> out_str) { // We split lower 2 digits and upper 2 digits of n into 2 byte consecutive // blocks. 123 -> [\0\1][\0\23]. We divide by 10 both blocks // (it's 1 division + zeroing upper bits), and compute modulo 10 as well "in @@ -232,8 +233,8 @@ inline uint64_t PrepareEightDigits(uint32_t i) { return tens; } -inline ABSL_ATTRIBUTE_ALWAYS_INLINE char* EncodeFullU32(uint32_t n, - char* out_str) { +inline ABSL_ATTRIBUTE_ALWAYS_INLINE absl::Nonnull<char*> EncodeFullU32( + uint32_t n, absl::Nonnull<char*> out_str) { if (n < 10) { *out_str = static_cast<char>('0' + n); return out_str + 1; @@ -282,7 +283,7 @@ inline ABSL_ATTRIBUTE_ALWAYS_INLINE char* EncodeFullU64(uint64_t i, } // namespace -void numbers_internal::PutTwoDigits(uint32_t i, char* buf) { +void numbers_internal::PutTwoDigits(uint32_t i, absl::Nonnull<char*> buf) { assert(i < 100); uint32_t base = kTwoZeroBytes; uint32_t div10 = (i * kDivisionBy10Mul) / kDivisionBy10Div; @@ -291,13 +292,15 @@ void numbers_internal::PutTwoDigits(uint32_t i, char* buf) { little_endian::Store16(buf, static_cast<uint16_t>(base)); } -char* numbers_internal::FastIntToBuffer(uint32_t n, char* out_str) { +absl::Nonnull<char*> numbers_internal::FastIntToBuffer( + uint32_t n, absl::Nonnull<char*> out_str) { out_str = EncodeFullU32(n, out_str); *out_str = '\0'; return out_str; } -char* numbers_internal::FastIntToBuffer(int32_t i, char* buffer) { +absl::Nonnull<char*> numbers_internal::FastIntToBuffer( + int32_t i, absl::Nonnull<char*> buffer) { uint32_t u = static_cast<uint32_t>(i); if (i < 0) { *buffer++ = '-'; @@ -311,13 +314,15 @@ char* numbers_internal::FastIntToBuffer(int32_t i, char* buffer) { return buffer; } -char* numbers_internal::FastIntToBuffer(uint64_t i, char* buffer) { +absl::Nonnull<char*> numbers_internal::FastIntToBuffer( + uint64_t i, absl::Nonnull<char*> buffer) { buffer = EncodeFullU64(i, buffer); *buffer = '\0'; return buffer; } -char* numbers_internal::FastIntToBuffer(int64_t i, char* buffer) { +absl::Nonnull<char*> numbers_internal::FastIntToBuffer( + int64_t i, absl::Nonnull<char*> buffer) { uint64_t u = static_cast<uint64_t>(i); if (i < 0) { *buffer++ = '-'; @@ -538,7 +543,8 @@ static ExpDigits SplitToSix(const double value) { // Helper function for fast formatting of floating-point. // The result is the same as "%g", a.k.a. "%.6g". -size_t numbers_internal::SixDigitsToBuffer(double d, char* const buffer) { +size_t numbers_internal::SixDigitsToBuffer(double d, + absl::Nonnull<char*> const buffer) { static_assert(std::numeric_limits<float>::is_iec559, "IEEE-754/IEC-559 support only"); @@ -685,9 +691,10 @@ static const int8_t kAsciiToInt[256] = { 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36}; // Parse the sign and optional hex or oct prefix in text. -inline bool safe_parse_sign_and_base(absl::string_view* text /*inout*/, - int* base_ptr /*inout*/, - bool* negative_ptr /*output*/) { +inline bool safe_parse_sign_and_base( + absl::Nonnull<absl::string_view*> text /*inout*/, + absl::Nonnull<int*> base_ptr /*inout*/, + absl::Nonnull<bool*> negative_ptr /*output*/) { if (text->data() == nullptr) { return false; } @@ -972,7 +979,7 @@ ABSL_CONST_INIT const IntType LookupTables<IntType>::kVminOverBase[] = template <typename IntType> inline bool safe_parse_positive_int(absl::string_view text, int base, - IntType* value_p) { + absl::Nonnull<IntType*> value_p) { IntType value = 0; const IntType vmax = std::numeric_limits<IntType>::max(); assert(vmax > 0); @@ -1009,7 +1016,7 @@ inline bool safe_parse_positive_int(absl::string_view text, int base, template <typename IntType> inline bool safe_parse_negative_int(absl::string_view text, int base, - IntType* value_p) { + absl::Nonnull<IntType*> value_p) { IntType value = 0; const IntType vmin = std::numeric_limits<IntType>::min(); assert(vmin < 0); @@ -1053,8 +1060,8 @@ inline bool safe_parse_negative_int(absl::string_view text, int base, // Input format based on POSIX.1-2008 strtol // http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtol.html template <typename IntType> -inline bool safe_int_internal(absl::string_view text, IntType* value_p, - int base) { +inline bool safe_int_internal(absl::string_view text, + absl::Nonnull<IntType*> value_p, int base) { *value_p = 0; bool negative; if (!safe_parse_sign_and_base(&text, &base, &negative)) { @@ -1068,8 +1075,8 @@ inline bool safe_int_internal(absl::string_view text, IntType* value_p, } template <typename IntType> -inline bool safe_uint_internal(absl::string_view text, IntType* value_p, - int base) { +inline bool safe_uint_internal(absl::string_view text, + absl::Nonnull<IntType*> value_p, int base) { *value_p = 0; bool negative; if (!safe_parse_sign_and_base(&text, &base, &negative) || negative) { @@ -1103,27 +1110,33 @@ ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] = "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; -bool safe_strto32_base(absl::string_view text, int32_t* value, int base) { +bool safe_strto32_base(absl::string_view text, absl::Nonnull<int32_t*> value, + int base) { return safe_int_internal<int32_t>(text, value, base); } -bool safe_strto64_base(absl::string_view text, int64_t* value, int base) { +bool safe_strto64_base(absl::string_view text, absl::Nonnull<int64_t*> value, + int base) { return safe_int_internal<int64_t>(text, value, base); } -bool safe_strto128_base(absl::string_view text, int128* value, int base) { +bool safe_strto128_base(absl::string_view text, absl::Nonnull<int128*> value, + int base) { return safe_int_internal<absl::int128>(text, value, base); } -bool safe_strtou32_base(absl::string_view text, uint32_t* value, int base) { +bool safe_strtou32_base(absl::string_view text, absl::Nonnull<uint32_t*> value, + int base) { return safe_uint_internal<uint32_t>(text, value, base); } -bool safe_strtou64_base(absl::string_view text, uint64_t* value, int base) { +bool safe_strtou64_base(absl::string_view text, absl::Nonnull<uint64_t*> value, + int base) { return safe_uint_internal<uint64_t>(text, value, base); } -bool safe_strtou128_base(absl::string_view text, uint128* value, int base) { +bool safe_strtou128_base(absl::string_view text, absl::Nonnull<uint128*> value, + int base) { return safe_uint_internal<absl::uint128>(text, value, base); } |