From 4ccc0fce09836a25b474f4b1453146dae2c29f4d Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 17 Jun 2020 14:16:51 -0700 Subject: Export of internal Abseil changes -- 34c0d521b11ed4191ea3e071a864a84e5e5941b7 by Matthew Brown : Release absl::StrFormat custom type extensions - Allows StrFormat methods to be extended to accept types which implement AbslFormatConvert() - NOLINTNEXTLINE(readability-redundant-declaration) used, declarations are required in some compilers. PiperOrigin-RevId: 316963065 -- 4d475b5ad02d41057447d722ad35573fc4f48d1f by Evan Brown : Small fix to previous change: the first overload of insert_iterator_unique wasn't actually being selected. Fix that issue and add tests to verify that it actually works. Note: couldn't use TestInstanceTracker here because that counts instances (and decrements in destructor) rather than counting all constructor calls. PiperOrigin-RevId: 316927690 GitOrigin-RevId: 34c0d521b11ed4191ea3e071a864a84e5e5941b7 Change-Id: If8bbb8317b93af4084ac4cc55b752b99b1581b58 --- absl/strings/internal/str_format/arg.h | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'absl/strings/internal/str_format/arg.h') diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h index d441e87f..3dbc1526 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h @@ -25,10 +25,12 @@ class Cord; class FormatCountCapture; class FormatSink; -namespace str_format_internal { - +template +struct FormatConvertResult; class FormatConversionSpec; +namespace str_format_internal { + template struct HasUserDefinedConvert : std::false_type {}; @@ -39,6 +41,22 @@ struct HasUserDefinedConvert()))>> : std::true_type {}; +void AbslFormatConvert(); // Stops the lexical name lookup +template +auto FormatConvertImpl(const T& v, FormatConversionSpecImpl conv, + FormatSinkImpl* sink) + -> decltype(AbslFormatConvert(v, + std::declval(), + std::declval())) { + using FormatConversionSpecT = + absl::enable_if_t; + using FormatSinkT = + absl::enable_if_t; + auto fcs = conv.Wrap(); + auto fs = sink->Wrap(); + return AbslFormatConvert(v, fcs, &fs); +} + template class StreamedWrapper; @@ -46,6 +64,13 @@ class StreamedWrapper; // then convert it, appending to `sink` and return `true`. // Otherwise fail and return `false`. +// AbslFormatConvert(v, conv, sink) is intended to be found by ADL on 'v' +// as an extension mechanism. These FormatConvertImpl functions are the default +// implementations. +// The ADL search is augmented via the 'Sink*' parameter, which also +// serves as a disambiguator to reject possible unintended 'AbslFormatConvert' +// functions in the namespaces associated with 'v'. + // Raw pointers. struct VoidPtr { VoidPtr() = default; @@ -61,6 +86,11 @@ struct ArgConvertResult { bool value; }; +template +constexpr FormatConversionCharSet ExtractCharSet(FormatConvertResult) { + return C; +} + template constexpr FormatConversionCharSet ExtractCharSet(ArgConvertResult) { return C; -- cgit v1.2.3