diff options
Diffstat (limited to 'absl/strings')
-rw-r--r-- | absl/strings/internal/str_format/bind.cc | 41 | ||||
-rw-r--r-- | absl/strings/internal/str_format/bind.h | 32 |
2 files changed, 39 insertions, 34 deletions
diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc index 33e86415..c4eddd17 100644 --- a/absl/strings/internal/str_format/bind.cc +++ b/absl/strings/internal/str_format/bind.cc @@ -103,15 +103,15 @@ class ConverterConsumer { }; template <typename Converter> -bool ConvertAll(const UntypedFormatSpecImpl& format, - absl::Span<const FormatArgImpl> args, - const Converter& converter) { - const ParsedFormatBase* pc = format.parsed_conversion(); - if (pc) - return pc->ProcessFormat(ConverterConsumer<Converter>(converter, args)); - - return ParseFormatString(format.str(), - ConverterConsumer<Converter>(converter, args)); +bool ConvertAll(const UntypedFormatSpecImpl format, + absl::Span<const FormatArgImpl> args, Converter converter) { + if (format.has_parsed_conversion()) { + return format.parsed_conversion()->ProcessFormat( + ConverterConsumer<Converter>(converter, args)); + } else { + return ParseFormatString(format.str(), + ConverterConsumer<Converter>(converter, args)); + } } class DefaultConverter { @@ -158,7 +158,7 @@ bool BindWithPack(const UnboundConversion* props, return ArgContext(pack).Bind(props, bound); } -std::string Summarize(const UntypedFormatSpecImpl& format, +std::string Summarize(const UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args) { typedef SummarizingConverter Converter; std::string out; @@ -167,23 +167,18 @@ std::string Summarize(const UntypedFormatSpecImpl& format, // flush. FormatSinkImpl sink(&out); if (!ConvertAll(format, args, Converter(&sink))) { - sink.Flush(); - out.clear(); + return ""; } } return out; } bool FormatUntyped(FormatRawSinkImpl raw_sink, - const UntypedFormatSpecImpl& format, + const UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args) { FormatSinkImpl sink(raw_sink); using Converter = DefaultConverter; - if (!ConvertAll(format, args, Converter(&sink))) { - sink.Flush(); - return false; - } - return true; + return ConvertAll(format, args, Converter(&sink)); } std::ostream& Streamable::Print(std::ostream& os) const { @@ -191,14 +186,16 @@ std::ostream& Streamable::Print(std::ostream& os) const { return os; } -std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl& format, +std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args) { size_t orig = out->size(); - if (!FormatUntyped(out, format, args)) out->resize(orig); + if (ABSL_PREDICT_FALSE(!FormatUntyped(out, format, args))) { + out->erase(orig); + } return *out; } -int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format, +int FprintF(std::FILE* output, const UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args) { FILERawSink sink(output); if (!FormatUntyped(&sink, format, args)) { @@ -216,7 +213,7 @@ int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format, return static_cast<int>(sink.count()); } -int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl& format, +int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args) { BufferRawSink sink(output, size ? size - 1 : 0); if (!FormatUntyped(&sink, format, args)) { diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h index 9d3d67c6..a503b19b 100644 --- a/absl/strings/internal/str_format/bind.h +++ b/absl/strings/internal/str_format/bind.h @@ -33,13 +33,21 @@ class UntypedFormatSpecImpl { public: UntypedFormatSpecImpl() = delete; - explicit UntypedFormatSpecImpl(string_view s) : str_(s), pc_() {} + explicit UntypedFormatSpecImpl(string_view s) + : data_(s.data()), size_(s.size()) {} explicit UntypedFormatSpecImpl( const str_format_internal::ParsedFormatBase* pc) - : pc_(pc) {} - string_view str() const { return str_; } + : data_(pc), size_(~size_t{}) {} + + bool has_parsed_conversion() const { return size_ == ~size_t{}; } + + string_view str() const { + assert(!has_parsed_conversion()); + return string_view(static_cast<const char*>(data_), size_); + } const str_format_internal::ParsedFormatBase* parsed_conversion() const { - return pc_; + assert(has_parsed_conversion()); + return static_cast<const str_format_internal::ParsedFormatBase*>(data_); } template <typename T> @@ -48,8 +56,8 @@ class UntypedFormatSpecImpl { } private: - string_view str_; - const str_format_internal::ParsedFormatBase* pc_; + const void* data_; + size_t size_; }; template <typename T, typename...> @@ -144,28 +152,28 @@ class Streamable { }; // for testing -std::string Summarize(const UntypedFormatSpecImpl& format, +std::string Summarize(UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args); bool BindWithPack(const UnboundConversion* props, absl::Span<const FormatArgImpl> pack, BoundConversion* bound); bool FormatUntyped(FormatRawSinkImpl raw_sink, - const UntypedFormatSpecImpl& format, + UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args); -std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl& format, +std::string& AppendPack(std::string* out, UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args); -inline std::string FormatPack(const UntypedFormatSpecImpl& format, +inline std::string FormatPack(const UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args) { std::string out; AppendPack(&out, format, args); return out; } -int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format, +int FprintF(std::FILE* output, UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args); -int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl& format, +int SnprintF(char* output, size_t size, UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args); // Returned by Streamed(v). Converts via '%s' to the string created |