summaryrefslogtreecommitdiff
path: root/absl/strings/substitute.h
diff options
context:
space:
mode:
authorGravatar Andy Soffer <asoffer@google.com>2022-10-14 11:18:49 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2022-10-14 11:19:40 -0700
commit5631e52ed71b4fe01e0cb9146b6ad10ef216b8b0 (patch)
tree67a8c5fa19c5b6319a693fbf0a403e370e78c5ec /absl/strings/substitute.h
parentf073fe8ee5dcb0aa18c893198747062f2f51ab59 (diff)
Support stringification of user-defined types in AbslStringify in absl::Substitute.
We are also moving some internals into an internal header. `HasAbslStringify` was not previously in an internal namespace but was intended to be and has now been moved to an internal namespace. This is in adherence to our compatibility guidelines which wave requirements for APIs within their first 30 days of public release (See https://abseil.io/about/compatibility for details). PiperOrigin-RevId: 481190705 Change-Id: I4c0c348f269ea8d76ea3d4bd5a2c41cce475dc04
Diffstat (limited to 'absl/strings/substitute.h')
-rw-r--r--absl/strings/substitute.h31
1 files changed, 20 insertions, 11 deletions
diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h
index 692fd03c..5c3f6eff 100644
--- a/absl/strings/substitute.h
+++ b/absl/strings/substitute.h
@@ -55,6 +55,8 @@
// * bool (Printed as "true" or "false")
// * pointer types other than char* (Printed as "0x<lower case hex string>",
// except that null is printed as "NULL")
+// * user-defined types via the `AbslStringify()` customization point. See the
+// documentation for `absl::StrCat` for an explanation on how to use this.
//
// If an invalid format string is provided, Substitute returns an empty string
// and SubstituteAndAppend does not change the provided output string.
@@ -79,6 +81,7 @@
#include "absl/base/port.h"
#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
+#include "absl/strings/internal/stringify_sink.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
@@ -102,14 +105,14 @@ class Arg {
// Overloads for string-y things
//
// Explicitly overload `const char*` so the compiler doesn't cast to `bool`.
- Arg(const char* value) // NOLINT(runtime/explicit)
+ Arg(const char* value) // NOLINT(google-explicit-constructor)
: piece_(absl::NullSafeStringView(value)) {}
template <typename Allocator>
Arg( // NOLINT
const std::basic_string<char, std::char_traits<char>, Allocator>&
value) noexcept
: piece_(value) {}
- Arg(absl::string_view value) // NOLINT(runtime/explicit)
+ Arg(absl::string_view value) // NOLINT(google-explicit-constructor)
: piece_(value) {}
// Overloads for primitives
@@ -119,7 +122,7 @@ class Arg {
// probably using them as 8-bit integers and would probably prefer an integer
// representation. However, we can't really know, so we make the caller decide
// what to do.
- Arg(char value) // NOLINT(runtime/explicit)
+ Arg(char value) // NOLINT(google-explicit-constructor)
: piece_(scratch_, 1) {
scratch_[0] = value;
}
@@ -133,12 +136,12 @@ class Arg {
static_cast<size_t>(
numbers_internal::FastIntToBuffer(value, scratch_) -
scratch_)) {}
- Arg(int value) // NOLINT(runtime/explicit)
+ Arg(int value) // NOLINT(google-explicit-constructor)
: piece_(scratch_,
static_cast<size_t>(
numbers_internal::FastIntToBuffer(value, scratch_) -
scratch_)) {}
- Arg(unsigned int value) // NOLINT(runtime/explicit)
+ Arg(unsigned int value) // NOLINT(google-explicit-constructor)
: piece_(scratch_,
static_cast<size_t>(
numbers_internal::FastIntToBuffer(value, scratch_) -
@@ -163,17 +166,23 @@ class Arg {
static_cast<size_t>(
numbers_internal::FastIntToBuffer(value, scratch_) -
scratch_)) {}
- Arg(float value) // NOLINT(runtime/explicit)
+ Arg(float value) // NOLINT(google-explicit-constructor)
: piece_(scratch_, numbers_internal::SixDigitsToBuffer(value, scratch_)) {
}
- Arg(double value) // NOLINT(runtime/explicit)
+ Arg(double value) // NOLINT(google-explicit-constructor)
: piece_(scratch_, numbers_internal::SixDigitsToBuffer(value, scratch_)) {
}
- Arg(bool value) // NOLINT(runtime/explicit)
+ Arg(bool value) // NOLINT(google-explicit-constructor)
: piece_(value ? "true" : "false") {}
- Arg(Hex hex); // NOLINT(runtime/explicit)
- Arg(Dec dec); // NOLINT(runtime/explicit)
+ template <typename T, typename = typename std::enable_if<
+ strings_internal::HasAbslStringify<T>::value>::type>
+ Arg( // NOLINT(google-explicit-constructor)
+ const T& v, strings_internal::StringifySink&& sink = {})
+ : piece_(strings_internal::ExtractStringification(sink, v)) {}
+
+ Arg(Hex hex); // NOLINT(google-explicit-constructor)
+ Arg(Dec dec); // NOLINT(google-explicit-constructor)
// vector<bool>::reference and const_reference require special help to convert
// to `Arg` because it requires two user defined conversions.
@@ -188,7 +197,7 @@ class Arg {
// `void*` values, with the exception of `char*`, are printed as
// "0x<hex value>". However, in the case of `nullptr`, "NULL" is printed.
- Arg(const void* value); // NOLINT(runtime/explicit)
+ Arg(const void* value); // NOLINT(google-explicit-constructor)
// Normal enums are already handled by the integer formatters.
// This overload matches only scoped enums.