Export of internal Abseil changes
-- 034c30a00c64d93b9fcbc9d99a0a33801544d741 by Gennadiy Rozental <rogeeff@google.com>: Split private handle interfaces accessor into a separate target with private visibility. PiperOrigin-RevId: 310391488 -- 6f6ca869309b17900b90849e08488ce7f7b0193a by Derek Mauro <dmauro@google.com>: Remove __CLANG_SUPPORT_DYN_ANNOTATION__, which is a symbol defined by us to be true in all builds PiperOrigin-RevId: 310385325 -- ed5c1880c86973c000e826a3006b38e53ab3ed52 by Samuel Benzaquen <sbenza@google.com>: Add tests to exercise extreme width and precision, and fix the overflows from it. PiperOrigin-RevId: 310224957 GitOrigin-RevId: 034c30a00c64d93b9fcbc9d99a0a33801544d741 Change-Id: I6c89a3c89ae92fa617c696044148ce9a79bcdda8
This commit is contained in:
parent
bd317cae3b
commit
a35ef8a62c
17 changed files with 214 additions and 99 deletions
|
|
@ -704,6 +704,31 @@ TEST_F(FormatConvertTest, FloatRound) {
|
|||
"1837869002408041296803276054561138153076171875");
|
||||
}
|
||||
|
||||
// We don't actually store the results. This is just to exercise the rest of the
|
||||
// machinery.
|
||||
struct NullSink {
|
||||
friend void AbslFormatFlush(NullSink *sink, string_view str) {}
|
||||
};
|
||||
|
||||
template <typename... T>
|
||||
bool FormatWithNullSink(absl::string_view fmt, const T &... a) {
|
||||
NullSink sink;
|
||||
FormatArgImpl args[] = {FormatArgImpl(a)...};
|
||||
return FormatUntyped(&sink, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
|
||||
}
|
||||
|
||||
TEST_F(FormatConvertTest, ExtremeWidthPrecision) {
|
||||
for (const char *fmt : {"f"}) {
|
||||
for (double d : {1e-100, 1.0, 1e100}) {
|
||||
constexpr int max = std::numeric_limits<int>::max();
|
||||
EXPECT_TRUE(FormatWithNullSink(std::string("%.*") + fmt, max, d));
|
||||
EXPECT_TRUE(FormatWithNullSink(std::string("%1.*") + fmt, max, d));
|
||||
EXPECT_TRUE(FormatWithNullSink(std::string("%*") + fmt, max, d));
|
||||
EXPECT_TRUE(FormatWithNullSink(std::string("%*.*") + fmt, max, max, d));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(FormatConvertTest, LongDouble) {
|
||||
#ifdef _MSC_VER
|
||||
// MSVC has a different rounding policy than us so we can't test our
|
||||
|
|
|
|||
|
|
@ -440,8 +440,10 @@ struct Padding {
|
|||
int right_spaces;
|
||||
};
|
||||
|
||||
Padding ExtraWidthToPadding(int total_size, const FormatState &state) {
|
||||
int missing_chars = std::max(state.conv.width() - total_size, 0);
|
||||
Padding ExtraWidthToPadding(size_t total_size, const FormatState &state) {
|
||||
if (state.conv.width() < 0 || state.conv.width() <= total_size)
|
||||
return {0, 0, 0};
|
||||
int missing_chars = state.conv.width() - total_size;
|
||||
if (state.conv.has_left_flag()) {
|
||||
return {0, 0, missing_chars};
|
||||
} else if (state.conv.has_zero_flag()) {
|
||||
|
|
@ -462,8 +464,8 @@ void FinalPrint(absl::string_view data, int trailing_zeros,
|
|||
}
|
||||
|
||||
auto padding =
|
||||
ExtraWidthToPadding((state.sign_char != '\0' ? 1 : 0) +
|
||||
static_cast<int>(data.size()) + trailing_zeros,
|
||||
ExtraWidthToPadding((state.sign_char != '\0' ? 1 : 0) + data.size() +
|
||||
static_cast<size_t>(trailing_zeros),
|
||||
state);
|
||||
|
||||
state.sink->Append(padding.left_spaces, ' ');
|
||||
|
|
@ -536,8 +538,9 @@ void FormatFFast(Int v, int exp, const FormatState &state) {
|
|||
// worry about anything after the `.`.
|
||||
void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) {
|
||||
BinaryToDecimal::RunConversion(v, exp, [&](BinaryToDecimal btd) {
|
||||
const int total_digits =
|
||||
btd.TotalDigits() + (state.ShouldPrintDot() ? state.precision + 1 : 0);
|
||||
const size_t total_digits =
|
||||
btd.TotalDigits() +
|
||||
(state.ShouldPrintDot() ? static_cast<size_t>(state.precision) + 1 : 0);
|
||||
|
||||
const auto padding = ExtraWidthToPadding(
|
||||
total_digits + (state.sign_char != '\0' ? 1 : 0), state);
|
||||
|
|
@ -562,8 +565,9 @@ void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) {
|
|||
// This one is guaranteed to be < 1.0, so we don't have to worry about integral
|
||||
// digits.
|
||||
void FormatFNegativeExpSlow(uint128 v, int exp, const FormatState &state) {
|
||||
const int total_digits =
|
||||
/* 0 */ 1 + (state.ShouldPrintDot() ? state.precision + 1 : 0);
|
||||
const size_t total_digits =
|
||||
/* 0 */ 1 +
|
||||
(state.ShouldPrintDot() ? static_cast<size_t>(state.precision) + 1 : 0);
|
||||
auto padding =
|
||||
ExtraWidthToPadding(total_digits + (state.sign_char ? 1 : 0), state);
|
||||
padding.zeros += 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue