diff options
Diffstat (limited to 'absl/strings')
-rw-r--r-- | absl/strings/internal/str_format/arg.cc | 4 | ||||
-rw-r--r-- | absl/strings/internal/str_format/arg.h | 21 | ||||
-rw-r--r-- | absl/strings/internal/str_format/checker.h | 9 | ||||
-rw-r--r-- | absl/strings/internal/str_format/extension.h | 17 |
4 files changed, 29 insertions, 22 deletions
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc index 964f25f7da64..02646addec11 100644 --- a/absl/strings/internal/str_format/arg.cc +++ b/absl/strings/internal/str_format/arg.cc @@ -302,7 +302,7 @@ bool ConvertIntArg(T v, const FormatConversionSpecImpl conv, return ConvertFloatImpl(static_cast<double>(v), conv, sink); default: - return false; + ABSL_INTERNAL_ASSUME(false); } if (conv.is_basic()) { @@ -321,7 +321,6 @@ bool ConvertFloatArg(T v, const FormatConversionSpecImpl conv, inline bool ConvertStringArg(string_view v, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { - if (conv.conversion_char() != FormatConversionCharInternal::s) return false; if (conv.is_basic()) { sink->Append(v); return true; @@ -366,7 +365,6 @@ FormatConvertImpl(const char *v, const FormatConversionSpecImpl conv, // ==================== Raw pointers ==================== ArgConvertResult<FormatConversionCharSetInternal::p> FormatConvertImpl( VoidPtr v, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { - if (conv.conversion_char() != FormatConversionCharInternal::p) return {false}; if (!v.value) { sink->Append("(nil)"); return {true}; diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h index 9a1e5ef276e8..8f79948bd91c 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h @@ -86,10 +86,6 @@ template <class AbslCord, typename std::enable_if<std::is_same< StringConvertResult FormatConvertImpl(const AbslCord& value, FormatConversionSpecImpl conv, FormatSinkImpl* sink) { - if (conv.conversion_char() != FormatConversionCharInternal::s) { - return {false}; - } - bool is_left = conv.has_left_flag(); size_t space_remaining = 0; @@ -249,6 +245,15 @@ struct FormatArgImplFriend { } }; +template <typename Arg> +constexpr FormatConversionCharSet ArgumentToConv() { + return absl::str_format_internal::ExtractCharSet( + decltype(str_format_internal::FormatConvertImpl( + std::declval<const Arg&>(), + std::declval<const FormatConversionSpecImpl&>(), + std::declval<FormatSinkImpl*>())){}); +} + // A type-erased handle to a format argument. class FormatArgImpl { private: @@ -411,9 +416,13 @@ class FormatArgImpl { return ToInt<T>(arg, static_cast<int*>(out), std::is_integral<T>(), std::is_enum<T>()); } - + if (ABSL_PREDICT_FALSE(!Contains(ArgumentToConv<T>(), + spec.conversion_char()))) { + return false; + } return str_format_internal::FormatConvertImpl( - Manager<T>::Value(arg), spec, static_cast<FormatSinkImpl*>(out)) + Manager<T>::Value(arg), spec, + static_cast<FormatSinkImpl*>(out)) .value; } diff --git a/absl/strings/internal/str_format/checker.h b/absl/strings/internal/str_format/checker.h index 73ef05ff44b3..424c51f74f17 100644 --- a/absl/strings/internal/str_format/checker.h +++ b/absl/strings/internal/str_format/checker.h @@ -24,15 +24,6 @@ constexpr bool AllOf(bool b, T... t) { return b && AllOf(t...); } -template <typename Arg> -constexpr FormatConversionCharSet ArgumentToConv() { - return absl::str_format_internal::ExtractCharSet( - decltype(str_format_internal::FormatConvertImpl( - std::declval<const Arg&>(), - std::declval<const FormatConversionSpecImpl&>(), - std::declval<FormatSinkImpl*>())){}); -} - #ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER constexpr bool ContainsChar(const char* chars, char c) { diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index ce78a02aefbb..36e70646d7d1 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -327,12 +327,16 @@ constexpr FormatConversionCharSet FormatConversionCharSetUnion( static_cast<uint64_t>(FormatConversionCharSetUnion(rest...))); } +constexpr uint64_t FormatConversionCharToConvInt(FormatConversionChar c) { + return uint64_t{1} << (1 + static_cast<uint8_t>(c)); +} + constexpr uint64_t FormatConversionCharToConvInt(char conv) { return -#define ABSL_INTERNAL_CHAR_SET_CASE(c) \ - conv == #c[0] ? (uint64_t{1} << (1 + static_cast<uint8_t>( \ - FormatConversionCharInternal::c))) \ - : +#define ABSL_INTERNAL_CHAR_SET_CASE(c) \ + conv == #c[0] \ + ? FormatConversionCharToConvInt(FormatConversionCharInternal::c) \ + : ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) #undef ABSL_INTERNAL_CHAR_SET_CASE conv == '*' @@ -406,6 +410,11 @@ constexpr bool Contains(FormatConversionCharSet set, static_cast<uint64_t>(c); } +// Checks whether all the characters in `c` are contained in `set` +constexpr bool Contains(FormatConversionCharSet set, FormatConversionChar c) { + return (static_cast<uint64_t>(set) & FormatConversionCharToConvInt(c)) != 0; +} + // Return capacity - used, clipped to a minimum of 0. inline size_t Excess(size_t used, size_t capacity) { return used < capacity ? capacity - used : 0; |