summaryrefslogtreecommitdiff
path: root/absl/strings/numbers.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/numbers.cc')
-rw-r--r--absl/strings/numbers.cc69
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);
}