From a0b5e3273bf6780b83c6e7fab23a5a92d6a005b7 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 10 Oct 2022 13:38:18 -0700 Subject: [PATCH] Adds documentation for stringification extension PiperOrigin-RevId: 480166410 Change-Id: Ie915e98747ffda0d1f0e5a72383f5dd9fc940970 --- absl/strings/str_cat.h | 37 +++++++++++++++++++++++++++++++++++++ absl/strings/str_format.h | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index 6ee88f14..8a63be0d 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -77,6 +77,43 @@ struct AlphaNumBuffer { size_t size; }; +//------------------------------------------------------------------------------ +// StrCat Extension +//------------------------------------------------------------------------------ +// +// AbslStringify() +// +// A simple customization API for formatting user-defined types using +// absl::StrCat(). The API relies on detecting an overload in the +// user-defined type's namespace of a free (non-member) `AbslStringify()` +// function as a friend definition with the following signature: +// +// template +// void AbslStringify(Sink& sink, const X& value); +// +// An `AbslStringify()` overload for a type should only be declared in the same +// file and namespace as said type. +// +// Note that AbslStringify() also supports use with absl::StrFormat(). +// +// Example: +// +// struct Point { +// // To add formatting support to `Point`, we simply need to add a free +// // (non-member) function `AbslStringify()`. This method specifies how +// // Point should be printed when absl::StrCat() is called on it. You can add +// // such a free function using a friend declaration within the body of the +// // class. The sink parameter is a templated type to avoid requiring +// // dependencies. +// template friend void AbslStringify(Sink& +// sink, const Point& p) { +// absl::Format(&sink, "(%v, %v)", p.x, p.y); +// } +// +// int x; +// int y; +// }; + class StringifySink { public: void Append(size_t count, char ch); diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index ffbcb9af..43d86186 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -570,6 +570,41 @@ ABSL_MUST_USE_RESULT inline bool FormatUntyped( // StrFormat Extensions //------------------------------------------------------------------------------ // +// AbslStringify() +// +// A simpler customization API for formatting user-defined types using +// absl::StrFormat(). The API relies on detecting an overload in the +// user-defined type's namespace of a free (non-member) `AbslStringify()` +// function as a friend definition with the following signature: +// +// template +// void AbslStringify(Sink& sink, const X& value); +// +// An `AbslStringify()` overload for a type should only be declared in the same +// file and namespace as said type. +// +// Note that unlike with AbslFormatConvert(), AbslStringify() does not allow +// customization of allowed conversion characters. AbslStringify() uses `%v` as +// the underlying conversion specififer. Additionally, AbslStringify() supports +// use with absl::StrCat while AbslFormatConvert() does not. +// +// Example: +// +// struct Point { +// // To add formatting support to `Point`, we simply need to add a free +// // (non-member) function `AbslStringify()`. This method prints in the +// // request format using the underlying `%v` specifier. You can add such a +// // free function using a friend declaration within the body of the class. +// // The sink parameter is a templated type to avoid requiring dependencies. +// template +// friend void AbslStringify(Sink& sink, const Point& p) { +// absl::Format(&sink, "(%v, %v)", p.x, p.y); +// } +// +// int x; +// int y; +// }; +// // AbslFormatConvert() // // The StrFormat library provides a customization API for formatting @@ -616,9 +651,9 @@ ABSL_MUST_USE_RESULT inline bool FormatUntyped( // AbslFormatConvert(const Point& p, const absl::FormatConversionSpec& spec, // absl::FormatSink* s) { // if (spec.conversion_char() == absl::FormatConversionChar::s) { -// s->Append(absl::StrCat("x=", p.x, " y=", p.y)); +// absl::Format(s, "x=%vy=%v", p.x, p.y); // } else { -// s->Append(absl::StrCat(p.x, ",", p.y)); +// absl::Format(s, "%v,%v", p.x, p.y); // } // return {true}; // }