about summary refs log tree commit diff
path: root/absl/strings/internal/str_format
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/internal/str_format')
-rw-r--r--absl/strings/internal/str_format/bind.cc41
-rw-r--r--absl/strings/internal/str_format/bind.h32
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 33e8641558ab..c4eddd17ddbe 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 9d3d67c63470..a503b19bb675 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