diff options
author | Abseil Team <absl-team@google.com> | 2020-06-17 14:16:51 -0700 |
---|---|---|
committer | Andy Getz <durandal@google.com> | 2020-06-18 16:10:44 -0400 |
commit | 4ccc0fce09836a25b474f4b1453146dae2c29f4d (patch) | |
tree | eb4e2c17bd7a605337192b21af4e9fe694b6e429 /absl/strings/internal/str_format/arg.h | |
parent | 4a851046a0102cd986a5714a1af8deef28a544c4 (diff) | |
download | abseil-4ccc0fce09836a25b474f4b1453146dae2c29f4d.tar.gz abseil-4ccc0fce09836a25b474f4b1453146dae2c29f4d.tar.bz2 abseil-4ccc0fce09836a25b474f4b1453146dae2c29f4d.zip |
Export of internal Abseil changes
--
34c0d521b11ed4191ea3e071a864a84e5e5941b7 by Matthew Brown <matthewbr@google.com>:
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 <ezb@google.com>:
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
Diffstat (limited to 'absl/strings/internal/str_format/arg.h')
-rw-r--r-- | absl/strings/internal/str_format/arg.h | 34 |
1 files changed, 32 insertions, 2 deletions
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 <absl::FormatConversionCharSet C> +struct FormatConvertResult; class FormatConversionSpec; +namespace str_format_internal { + template <typename T, typename = void> struct HasUserDefinedConvert : std::false_type {}; @@ -39,6 +41,22 @@ struct HasUserDefinedConvert<T, void_t<decltype(AbslFormatConvert( std::declval<FormatSink*>()))>> : std::true_type {}; +void AbslFormatConvert(); // Stops the lexical name lookup +template <typename T> +auto FormatConvertImpl(const T& v, FormatConversionSpecImpl conv, + FormatSinkImpl* sink) + -> decltype(AbslFormatConvert(v, + std::declval<const FormatConversionSpec&>(), + std::declval<FormatSink*>())) { + using FormatConversionSpecT = + absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatConversionSpec>; + using FormatSinkT = + absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>; + auto fcs = conv.Wrap<FormatConversionSpecT>(); + auto fs = sink->Wrap<FormatSinkT>(); + return AbslFormatConvert(v, fcs, &fs); +} + template <typename T> 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; @@ -62,6 +87,11 @@ struct ArgConvertResult { }; template <FormatConversionCharSet C> +constexpr FormatConversionCharSet ExtractCharSet(FormatConvertResult<C>) { + return C; +} + +template <FormatConversionCharSet C> constexpr FormatConversionCharSet ExtractCharSet(ArgConvertResult<C>) { return C; } |