diff options
author | Abseil Team <absl-team@google.com> | 2022-09-15 14:29:39 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2022-09-15 14:30:34 -0700 |
commit | ab2e2c4f6062999afaf960759dfccb77f350c702 (patch) | |
tree | a09ca81723521190744e2ec917a9f697cd08254b /absl/strings/internal/str_format/arg.cc | |
parent | d423ac0ef052bd7b6fc53fd1a026a44e1713d993 (diff) | |
download | abseil-ab2e2c4f6062999afaf960759dfccb77f350c702.tar.gz abseil-ab2e2c4f6062999afaf960759dfccb77f350c702.tar.bz2 abseil-ab2e2c4f6062999afaf960759dfccb77f350c702.zip |
Adds support for "%v" in absl::StrFormat and related functions for numeric types, including integer and floating point values. Users may now specify %v and have the format specifier deduced. Integer values will print according to %d specifications, unsigned values will use %u, and floating point values will use %g. Note that %v does not work for `char` due to ambiguity regarding the intended output. Please continue to use %c for `char`.
PiperOrigin-RevId: 474658166
Change-Id: Iecae39263e368b27232db440535f2bf7da8d863c
Diffstat (limited to 'absl/strings/internal/str_format/arg.cc')
-rw-r--r-- | absl/strings/internal/str_format/arg.cc | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc index 007e8e83..b0e06bfb 100644 --- a/absl/strings/internal/str_format/arg.cc +++ b/absl/strings/internal/str_format/arg.cc @@ -278,12 +278,33 @@ bool ConvertIntImplInnerSlow(const IntDigits &as_digits, return true; } +template <typename T, + typename std::enable_if<(std::is_integral<T>::value && + std::is_signed<T>::value) || + std::is_same<T, int128>::value, + int>::type = 0> +constexpr auto ConvertV(T) { + return FormatConversionCharInternal::d; +} + +template <typename T, + typename std::enable_if<(std::is_integral<T>::value && + std::is_unsigned<T>::value) || + std::is_same<T, uint128>::value, + int>::type = 0> +constexpr auto ConvertV(T) { + return FormatConversionCharInternal::u; +} + template <typename T> -bool ConvertIntArg(T v, const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { +bool ConvertIntArg(T v, FormatConversionSpecImpl conv, FormatSinkImpl *sink) { using U = typename MakeUnsigned<T>::type; IntDigits as_digits; + if (conv.conversion_char() == FormatConversionCharInternal::v) { + conv.set_conversion_char(ConvertV(T{})); + } + // This odd casting is due to a bug in -Wswitch behavior in gcc49 which causes // it to complain about a switch/case type mismatch, even though both are // FormatConverionChar. Likely this is because at this point @@ -334,8 +355,11 @@ bool ConvertIntArg(T v, const FormatConversionSpecImpl conv, } template <typename T> -bool ConvertFloatArg(T v, const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { +bool ConvertFloatArg(T v, FormatConversionSpecImpl conv, FormatSinkImpl *sink) { + if (conv.conversion_char() == FormatConversionCharInternal::v) { + conv.set_conversion_char(FormatConversionCharInternal::g); + } + return FormatConversionCharIsFloat(conv.conversion_char()) && ConvertFloatImpl(v, conv, sink); } @@ -413,19 +437,18 @@ FloatingConvertResult FormatConvertImpl(long double v, } // ==================== Chars ==================== -IntegralConvertResult FormatConvertImpl(char v, - const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { +CharConvertResult FormatConvertImpl(char v, const FormatConversionSpecImpl conv, + FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } -IntegralConvertResult FormatConvertImpl(signed char v, - const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { +CharConvertResult FormatConvertImpl(signed char v, + const FormatConversionSpecImpl conv, + FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } -IntegralConvertResult FormatConvertImpl(unsigned char v, - const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { +CharConvertResult FormatConvertImpl(unsigned char v, + const FormatConversionSpecImpl conv, + FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } |