From 8ff1374008259719b54a8cb128ef951c02da164c Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 12 Sep 2018 11:03:25 -0700 Subject: Export of internal Abseil changes. -- 821196cfb2a3b943ffdc4c9e75daec92d7ffb28b by Abseil Team : Performance improvements PiperOrigin-RevId: 212668992 -- 704858e2e767016bad27d53eec01d9d48e546b23 by Abseil Team : Low-level Portability enchancements for Abseil Mutex on WebAssembly. Emscripten Pthreads do not use signals, so remove use of pthread_sigmask or other async-signal-safe related handling code. PiperOrigin-RevId: 212527958 -- be3e38cb4d493b755132d20c8c2d1a51e45d5449 by Jon Cohen : Internal change. PiperOrigin-RevId: 212523797 GitOrigin-RevId: 821196cfb2a3b943ffdc4c9e75daec92d7ffb28b Change-Id: I5694e23e4e09364a15dd6fc4e2e3f15e38835687 --- absl/strings/internal/str_format/arg.h | 210 +++++++++++++++------------------ 1 file changed, 98 insertions(+), 112 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 a9562188ea91..3376d48afda2 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h @@ -33,7 +33,7 @@ struct HasUserDefinedConvert : std::false_type {}; template struct HasUserDefinedConvert< T, void_t(), std::declval(), + std::declval(), std::declval(), std::declval()))>> : std::true_type {}; template class StreamedWrapper; @@ -50,25 +50,23 @@ struct VoidPtr { : value(ptr ? reinterpret_cast(ptr) : 0) {} uintptr_t value; }; -ConvertResult FormatConvertImpl(VoidPtr v, const ConversionSpec& conv, +ConvertResult FormatConvertImpl(VoidPtr v, ConversionSpec conv, FormatSinkImpl* sink); // Strings. -ConvertResult FormatConvertImpl(const std::string& v, - const ConversionSpec& conv, +ConvertResult FormatConvertImpl(const std::string& v, ConversionSpec conv, FormatSinkImpl* sink); -ConvertResult FormatConvertImpl(string_view v, - const ConversionSpec& conv, +ConvertResult FormatConvertImpl(string_view v, ConversionSpec conv, FormatSinkImpl* sink); ConvertResult FormatConvertImpl(const char* v, - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink); template ::value>::type* = nullptr, class AbslCordReader = ::CordReader> ConvertResult FormatConvertImpl(const AbslCord& value, - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink) { if (conv.conv().id() != ConversionChar::s) return {false}; @@ -104,51 +102,48 @@ using IntegralConvertResult = using FloatingConvertResult = ConvertResult; // Floats. -FloatingConvertResult FormatConvertImpl(float v, const ConversionSpec& conv, +FloatingConvertResult FormatConvertImpl(float v, ConversionSpec conv, FormatSinkImpl* sink); -FloatingConvertResult FormatConvertImpl(double v, const ConversionSpec& conv, +FloatingConvertResult FormatConvertImpl(double v, ConversionSpec conv, FormatSinkImpl* sink); -FloatingConvertResult FormatConvertImpl(long double v, - const ConversionSpec& conv, +FloatingConvertResult FormatConvertImpl(long double v, ConversionSpec conv, FormatSinkImpl* sink); // Chars. -IntegralConvertResult FormatConvertImpl(char v, const ConversionSpec& conv, +IntegralConvertResult FormatConvertImpl(char v, ConversionSpec conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(signed char v, - const ConversionSpec& conv, +IntegralConvertResult FormatConvertImpl(signed char v, ConversionSpec conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(unsigned char v, - const ConversionSpec& conv, +IntegralConvertResult FormatConvertImpl(unsigned char v, ConversionSpec conv, FormatSinkImpl* sink); // Ints. IntegralConvertResult FormatConvertImpl(short v, // NOLINT - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(unsigned short v, // NOLINT - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(int v, const ConversionSpec& conv, +IntegralConvertResult FormatConvertImpl(int v, ConversionSpec conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(unsigned v, const ConversionSpec& conv, +IntegralConvertResult FormatConvertImpl(unsigned v, ConversionSpec conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(long v, // NOLINT - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(unsigned long v, // NOLINT - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(long long v, // NOLINT - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(unsigned long long v, // NOLINT - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(uint128 v, const ConversionSpec& conv, +IntegralConvertResult FormatConvertImpl(uint128 v, ConversionSpec conv, FormatSinkImpl* sink); template ::value, int> = 0> -IntegralConvertResult FormatConvertImpl(T v, const ConversionSpec& conv, +IntegralConvertResult FormatConvertImpl(T v, ConversionSpec conv, FormatSinkImpl* sink) { return FormatConvertImpl(static_cast(v), conv, sink); } @@ -159,11 +154,11 @@ template typename std::enable_if::value && !HasUserDefinedConvert::value, IntegralConvertResult>::type -FormatConvertImpl(T v, const ConversionSpec& conv, FormatSinkImpl* sink); +FormatConvertImpl(T v, ConversionSpec conv, FormatSinkImpl* sink); template ConvertResult FormatConvertImpl(const StreamedWrapper& v, - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* out) { std::ostringstream oss; oss << v.v_; @@ -176,7 +171,7 @@ ConvertResult FormatConvertImpl(const StreamedWrapper& v, struct FormatCountCaptureHelper { template static ConvertResult ConvertHelper(const FormatCountCapture& v, - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink) { const absl::enable_if_t& v2 = v; @@ -189,7 +184,7 @@ struct FormatCountCaptureHelper { template ConvertResult FormatConvertImpl(const FormatCountCapture& v, - const ConversionSpec& conv, + ConversionSpec conv, FormatSinkImpl* sink) { return FormatCountCaptureHelper::ConvertHelper(v, conv, sink); } @@ -199,20 +194,20 @@ ConvertResult FormatConvertImpl(const FormatCountCapture& v, struct FormatArgImplFriend { template static bool ToInt(Arg arg, int* out) { - if (!arg.vtbl_->to_int) return false; - *out = arg.vtbl_->to_int(arg.data_); - return true; + // A value initialized ConversionSpec has a `none` conv, which tells the + // dispatcher to run the `int` conversion. + return arg.dispatcher_(arg.data_, {}, out); } template - static bool Convert(Arg arg, const str_format_internal::ConversionSpec& conv, + static bool Convert(Arg arg, str_format_internal::ConversionSpec conv, FormatSinkImpl* out) { - return arg.vtbl_->convert(arg.data_, conv, out); + return arg.dispatcher_(arg.data_, conv, out); } template - static const void* GetVTablePtrForTest(Arg arg) { - return arg.vtbl_; + static typename Arg::Dispatcher GetVTablePtrForTest(Arg arg) { + return arg.dispatcher_; } }; @@ -229,11 +224,7 @@ class FormatArgImpl { char buf[kInlinedSpace]; }; - struct VTable { - bool (*convert)(Data, const str_format_internal::ConversionSpec& conv, - FormatSinkImpl* out); - int (*to_int)(Data); - }; + using Dispatcher = bool (*)(Data, ConversionSpec, void* out); template struct store_by_value @@ -253,10 +244,6 @@ class FormatArgImpl { : ByPointer))> { }; - // An instance of an FormatArgImpl::VTable suitable for 'T'. - template - struct TypedVTable; - // To reduce the number of vtables we will decay values before hand. // Anything with a user-defined Convert will get its own vtable. // For everything else: @@ -338,7 +325,10 @@ class FormatArgImpl { }; template - void Init(const T& value); + void Init(const T& value) { + data_ = Manager::SetValue(value); + dispatcher_ = &Dispatch; + } template static int ToIntVal(const T& val) { @@ -355,79 +345,75 @@ class FormatArgImpl { return static_cast(val); } - Data data_; - const VTable* vtbl_; -}; - -template -struct FormatArgImpl::TypedVTable { - private: - static bool ConvertImpl(Data arg, - const str_format_internal::ConversionSpec& conv, - FormatSinkImpl* out) { - return str_format_internal::FormatConvertImpl(Manager::Value(arg), conv, - out) - .value; + template + static bool ToInt(Data arg, int* out, std::true_type /* is_integral */, + std::false_type) { + *out = ToIntVal(Manager::Value(arg)); + return true; } - template - struct ToIntImpl { - static constexpr int (*value)(Data) = nullptr; - }; + template + static bool ToInt(Data arg, int* out, std::false_type, + std::true_type /* is_enum */) { + *out = ToIntVal(static_cast::type>( + Manager::Value(arg))); + return true; + } - template - struct ToIntImpl::value>::type> { - static int Invoke(Data arg) { return ToIntVal(Manager::Value(arg)); } - static constexpr int (*value)(Data) = &Invoke; - }; + template + static bool ToInt(Data, int*, std::false_type, std::false_type) { + return false; + } - template - struct ToIntImpl::value>::type> { - static int Invoke(Data arg) { - return ToIntVal(static_cast::type>( - Manager::Value(arg))); + template + static bool Dispatch(Data arg, ConversionSpec spec, void* out) { + // A `none` conv indicates that we want the `int` conversion. + if (ABSL_PREDICT_FALSE(spec.conv().id() == ConversionChar::none)) { + return ToInt(arg, static_cast(out), std::is_integral(), + std::is_enum()); } - static constexpr int (*value)(Data) = &Invoke; - }; - public: - static constexpr VTable value{&ConvertImpl, ToIntImpl<>::value}; -}; + return str_format_internal::FormatConvertImpl( + Manager::Value(arg), spec, static_cast(out)) + .value; + } -template -constexpr FormatArgImpl::VTable FormatArgImpl::TypedVTable::value; + Data data_; + Dispatcher dispatcher_; +}; -template -void FormatArgImpl::Init(const T& value) { - data_ = Manager::SetValue(value); - vtbl_ = &TypedVTable::value; -} +#define ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(T, E) \ + E template bool FormatArgImpl::Dispatch(Data, ConversionSpec, void*) + +#define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(...) \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(str_format_internal::VoidPtr, \ + __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(bool, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(char, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(signed char, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned char, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(short, __VA_ARGS__); /* NOLINT */ \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned short, /* NOLINT */ \ + __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(int, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned int, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long, __VA_ARGS__); /* NOLINT */ \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned long, /* NOLINT */ \ + __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long long, /* NOLINT */ \ + __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned long long, /* NOLINT */ \ + __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(uint128, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(float, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(double, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long double, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(const char*, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::string, __VA_ARGS__); \ + ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(string_view, __VA_ARGS__) + +ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(extern); -extern template struct FormatArgImpl::TypedVTable; - -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; // NOLINT -extern template struct FormatArgImpl::TypedVTable; // NOLINT -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; // NOLINT -extern template struct FormatArgImpl::TypedVTable; // NOLINT -extern template struct FormatArgImpl::TypedVTable; // NOLINT -extern template struct FormatArgImpl::TypedVTable< - unsigned long long>; // NOLINT -extern template struct FormatArgImpl::TypedVTable; - -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; - -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; -extern template struct FormatArgImpl::TypedVTable; } // namespace str_format_internal } // namespace absl -- cgit 1.4.1