File indexing completed on 2025-01-18 09:27:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_
0016 #define ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_
0017
0018 #include <string.h>
0019 #include <wchar.h>
0020
0021 #include <algorithm>
0022 #include <cstddef>
0023 #include <cstdint>
0024 #include <cstdio>
0025 #include <limits>
0026 #include <memory>
0027 #include <sstream>
0028 #include <string>
0029 #include <type_traits>
0030 #include <utility>
0031
0032 #include "absl/base/config.h"
0033 #include "absl/base/optimization.h"
0034 #include "absl/meta/type_traits.h"
0035 #include "absl/numeric/int128.h"
0036 #include "absl/strings/has_absl_stringify.h"
0037 #include "absl/strings/internal/str_format/extension.h"
0038 #include "absl/strings/string_view.h"
0039
0040 #if defined(ABSL_HAVE_STD_STRING_VIEW)
0041 #include <string_view>
0042 #endif
0043
0044 namespace absl {
0045 ABSL_NAMESPACE_BEGIN
0046
0047 class Cord;
0048 class FormatCountCapture;
0049 class FormatSink;
0050
0051 template <absl::FormatConversionCharSet C>
0052 struct FormatConvertResult;
0053 class FormatConversionSpec;
0054
0055 namespace str_format_internal {
0056
0057 template <FormatConversionCharSet C>
0058 struct ArgConvertResult {
0059 bool value;
0060 };
0061
0062 using IntegralConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
0063 FormatConversionCharSetInternal::c,
0064 FormatConversionCharSetInternal::kNumeric,
0065 FormatConversionCharSetInternal::kStar,
0066 FormatConversionCharSetInternal::v)>;
0067 using FloatingConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
0068 FormatConversionCharSetInternal::kFloating,
0069 FormatConversionCharSetInternal::v)>;
0070 using CharConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
0071 FormatConversionCharSetInternal::c,
0072 FormatConversionCharSetInternal::kNumeric,
0073 FormatConversionCharSetInternal::kStar)>;
0074
0075 template <typename T, typename = void>
0076 struct HasUserDefinedConvert : std::false_type {};
0077
0078 template <typename T>
0079 struct HasUserDefinedConvert<T, void_t<decltype(AbslFormatConvert(
0080 std::declval<const T&>(),
0081 std::declval<const FormatConversionSpec&>(),
0082 std::declval<FormatSink*>()))>>
0083 : std::true_type {};
0084
0085
0086
0087
0088 void AbslFormatConvert();
0089 void AbslStringify();
0090
0091 template <typename T>
0092 bool ConvertIntArg(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);
0093
0094
0095
0096
0097
0098 extern template bool ConvertIntArg<char>(char v, FormatConversionSpecImpl conv,
0099 FormatSinkImpl* sink);
0100 extern template bool ConvertIntArg<signed char>(signed char v,
0101 FormatConversionSpecImpl conv,
0102 FormatSinkImpl* sink);
0103 extern template bool ConvertIntArg<unsigned char>(unsigned char v,
0104 FormatConversionSpecImpl conv,
0105 FormatSinkImpl* sink);
0106 extern template bool ConvertIntArg<wchar_t>(wchar_t v,
0107 FormatConversionSpecImpl conv,
0108 FormatSinkImpl* sink);
0109 extern template bool ConvertIntArg<short>(short v,
0110 FormatConversionSpecImpl conv,
0111 FormatSinkImpl* sink);
0112 extern template bool ConvertIntArg<unsigned short>(
0113 unsigned short v, FormatConversionSpecImpl conv,
0114 FormatSinkImpl* sink);
0115 extern template bool ConvertIntArg<int>(int v, FormatConversionSpecImpl conv,
0116 FormatSinkImpl* sink);
0117 extern template bool ConvertIntArg<unsigned int>(unsigned int v,
0118 FormatConversionSpecImpl conv,
0119 FormatSinkImpl* sink);
0120 extern template bool ConvertIntArg<long>(
0121 long v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);
0122 extern template bool ConvertIntArg<unsigned long>(unsigned long v,
0123 FormatConversionSpecImpl conv,
0124 FormatSinkImpl* sink);
0125 extern template bool ConvertIntArg<long long>(long long v,
0126 FormatConversionSpecImpl conv,
0127 FormatSinkImpl* sink);
0128 extern template bool ConvertIntArg<unsigned long long>(
0129 unsigned long long v, FormatConversionSpecImpl conv,
0130 FormatSinkImpl* sink);
0131
0132 template <typename T>
0133 auto FormatConvertImpl(const T& v, FormatConversionSpecImpl conv,
0134 FormatSinkImpl* sink)
0135 -> decltype(AbslFormatConvert(v,
0136 std::declval<const FormatConversionSpec&>(),
0137 std::declval<FormatSink*>())) {
0138 using FormatConversionSpecT =
0139 absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatConversionSpec>;
0140 using FormatSinkT =
0141 absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>;
0142 auto fcs = conv.Wrap<FormatConversionSpecT>();
0143 auto fs = sink->Wrap<FormatSinkT>();
0144 return AbslFormatConvert(v, fcs, &fs);
0145 }
0146
0147 template <typename T>
0148 auto FormatConvertImpl(const T& v, FormatConversionSpecImpl conv,
0149 FormatSinkImpl* sink)
0150 -> std::enable_if_t<std::is_enum<T>::value &&
0151 std::is_void<decltype(AbslStringify(
0152 std::declval<FormatSink&>(), v))>::value,
0153 IntegralConvertResult> {
0154 if (conv.conversion_char() == FormatConversionCharInternal::v) {
0155 using FormatSinkT =
0156 absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>;
0157 auto fs = sink->Wrap<FormatSinkT>();
0158 AbslStringify(fs, v);
0159 return {true};
0160 } else {
0161 return {ConvertIntArg(
0162 static_cast<typename std::underlying_type<T>::type>(v), conv, sink)};
0163 }
0164 }
0165
0166 template <typename T>
0167 auto FormatConvertImpl(const T& v, FormatConversionSpecImpl,
0168 FormatSinkImpl* sink)
0169 -> std::enable_if_t<!std::is_enum<T>::value &&
0170 !std::is_same<T, absl::Cord>::value &&
0171 std::is_void<decltype(AbslStringify(
0172 std::declval<FormatSink&>(), v))>::value,
0173 ArgConvertResult<FormatConversionCharSetInternal::v>> {
0174 using FormatSinkT =
0175 absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>;
0176 auto fs = sink->Wrap<FormatSinkT>();
0177 AbslStringify(fs, v);
0178 return {true};
0179 }
0180
0181 template <typename T>
0182 class StreamedWrapper;
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 struct VoidPtr {
0197 VoidPtr() = default;
0198 template <typename T,
0199 decltype(reinterpret_cast<uintptr_t>(std::declval<T*>())) = 0>
0200 VoidPtr(T* ptr)
0201 : value(ptr ? reinterpret_cast<uintptr_t>(ptr) : 0) {}
0202 uintptr_t value;
0203 };
0204
0205 template <FormatConversionCharSet C>
0206 constexpr FormatConversionCharSet ExtractCharSet(FormatConvertResult<C>) {
0207 return C;
0208 }
0209
0210 template <FormatConversionCharSet C>
0211 constexpr FormatConversionCharSet ExtractCharSet(ArgConvertResult<C>) {
0212 return C;
0213 }
0214
0215 ArgConvertResult<FormatConversionCharSetInternal::p> FormatConvertImpl(
0216 VoidPtr v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);
0217
0218
0219 using StringConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
0220 FormatConversionCharSetInternal::s,
0221 FormatConversionCharSetInternal::v)>;
0222 StringConvertResult FormatConvertImpl(const std::string& v,
0223 FormatConversionSpecImpl conv,
0224 FormatSinkImpl* sink);
0225 StringConvertResult FormatConvertImpl(const std::wstring& v,
0226 FormatConversionSpecImpl conv,
0227 FormatSinkImpl* sink);
0228 StringConvertResult FormatConvertImpl(string_view v,
0229 FormatConversionSpecImpl conv,
0230 FormatSinkImpl* sink);
0231 #if defined(ABSL_HAVE_STD_STRING_VIEW)
0232 StringConvertResult FormatConvertImpl(std::wstring_view v,
0233 FormatConversionSpecImpl conv,
0234 FormatSinkImpl* sink);
0235 #if !defined(ABSL_USES_STD_STRING_VIEW)
0236 inline StringConvertResult FormatConvertImpl(std::string_view v,
0237 FormatConversionSpecImpl conv,
0238 FormatSinkImpl* sink) {
0239 return FormatConvertImpl(absl::string_view(v.data(), v.size()), conv, sink);
0240 }
0241 #endif
0242 #endif
0243
0244 using StringPtrConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
0245 FormatConversionCharSetInternal::s,
0246 FormatConversionCharSetInternal::p)>;
0247 StringPtrConvertResult FormatConvertImpl(const char* v,
0248 FormatConversionSpecImpl conv,
0249 FormatSinkImpl* sink);
0250 StringPtrConvertResult FormatConvertImpl(const wchar_t* v,
0251 FormatConversionSpecImpl conv,
0252 FormatSinkImpl* sink);
0253
0254
0255 StringPtrConvertResult FormatConvertImpl(std::nullptr_t,
0256 FormatConversionSpecImpl conv,
0257 FormatSinkImpl* sink);
0258
0259 template <class AbslCord, typename std::enable_if<std::is_same<
0260 AbslCord, absl::Cord>::value>::type* = nullptr>
0261 StringConvertResult FormatConvertImpl(const AbslCord& value,
0262 FormatConversionSpecImpl conv,
0263 FormatSinkImpl* sink) {
0264 bool is_left = conv.has_left_flag();
0265 size_t space_remaining = 0;
0266
0267 int width = conv.width();
0268 if (width >= 0) space_remaining = static_cast<size_t>(width);
0269
0270 size_t to_write = value.size();
0271
0272 int precision = conv.precision();
0273 if (precision >= 0)
0274 to_write = (std::min)(to_write, static_cast<size_t>(precision));
0275
0276 space_remaining = Excess(to_write, space_remaining);
0277
0278 if (space_remaining > 0 && !is_left) sink->Append(space_remaining, ' ');
0279
0280 for (string_view piece : value.Chunks()) {
0281 if (piece.size() > to_write) {
0282 piece.remove_suffix(piece.size() - to_write);
0283 to_write = 0;
0284 } else {
0285 to_write -= piece.size();
0286 }
0287 sink->Append(piece);
0288 if (to_write == 0) {
0289 break;
0290 }
0291 }
0292
0293 if (space_remaining > 0 && is_left) sink->Append(space_remaining, ' ');
0294 return {true};
0295 }
0296
0297 bool ConvertBoolArg(bool v, FormatSinkImpl* sink);
0298
0299
0300 FloatingConvertResult FormatConvertImpl(float v, FormatConversionSpecImpl conv,
0301 FormatSinkImpl* sink);
0302 FloatingConvertResult FormatConvertImpl(double v, FormatConversionSpecImpl conv,
0303 FormatSinkImpl* sink);
0304 FloatingConvertResult FormatConvertImpl(long double v,
0305 FormatConversionSpecImpl conv,
0306 FormatSinkImpl* sink);
0307
0308
0309 CharConvertResult FormatConvertImpl(char v, FormatConversionSpecImpl conv,
0310 FormatSinkImpl* sink);
0311 CharConvertResult FormatConvertImpl(wchar_t v,
0312 FormatConversionSpecImpl conv,
0313 FormatSinkImpl* sink);
0314
0315
0316 IntegralConvertResult FormatConvertImpl(signed char v,
0317 FormatConversionSpecImpl conv,
0318 FormatSinkImpl* sink);
0319 IntegralConvertResult FormatConvertImpl(unsigned char v,
0320 FormatConversionSpecImpl conv,
0321 FormatSinkImpl* sink);
0322 IntegralConvertResult FormatConvertImpl(short v,
0323 FormatConversionSpecImpl conv,
0324 FormatSinkImpl* sink);
0325 IntegralConvertResult FormatConvertImpl(unsigned short v,
0326 FormatConversionSpecImpl conv,
0327 FormatSinkImpl* sink);
0328 IntegralConvertResult FormatConvertImpl(int v, FormatConversionSpecImpl conv,
0329 FormatSinkImpl* sink);
0330 IntegralConvertResult FormatConvertImpl(unsigned v,
0331 FormatConversionSpecImpl conv,
0332 FormatSinkImpl* sink);
0333 IntegralConvertResult FormatConvertImpl(long v,
0334 FormatConversionSpecImpl conv,
0335 FormatSinkImpl* sink);
0336 IntegralConvertResult FormatConvertImpl(unsigned long v,
0337 FormatConversionSpecImpl conv,
0338 FormatSinkImpl* sink);
0339 IntegralConvertResult FormatConvertImpl(long long v,
0340 FormatConversionSpecImpl conv,
0341 FormatSinkImpl* sink);
0342 IntegralConvertResult FormatConvertImpl(unsigned long long v,
0343 FormatConversionSpecImpl conv,
0344 FormatSinkImpl* sink);
0345 IntegralConvertResult FormatConvertImpl(int128 v, FormatConversionSpecImpl conv,
0346 FormatSinkImpl* sink);
0347 IntegralConvertResult FormatConvertImpl(uint128 v,
0348 FormatConversionSpecImpl conv,
0349 FormatSinkImpl* sink);
0350
0351
0352
0353 template <typename T, enable_if_t<std::is_same<T, bool>::value, int> = 0>
0354 IntegralConvertResult FormatConvertImpl(T v, FormatConversionSpecImpl conv,
0355 FormatSinkImpl* sink) {
0356 if (conv.conversion_char() == FormatConversionCharInternal::v) {
0357 return {ConvertBoolArg(v, sink)};
0358 }
0359
0360 return FormatConvertImpl(static_cast<int>(v), conv, sink);
0361 }
0362
0363
0364
0365 template <typename T>
0366 typename std::enable_if<std::is_enum<T>::value &&
0367 !HasUserDefinedConvert<T>::value &&
0368 !HasAbslStringify<T>::value,
0369 IntegralConvertResult>::type
0370 FormatConvertImpl(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);
0371
0372 template <typename T>
0373 StringConvertResult FormatConvertImpl(const StreamedWrapper<T>& v,
0374 FormatConversionSpecImpl conv,
0375 FormatSinkImpl* out) {
0376 std::ostringstream oss;
0377 oss << v.v_;
0378 if (!oss) return {false};
0379 return str_format_internal::FormatConvertImpl(oss.str(), conv, out);
0380 }
0381
0382
0383
0384 struct FormatCountCaptureHelper {
0385 template <class T = int>
0386 static ArgConvertResult<FormatConversionCharSetInternal::n> ConvertHelper(
0387 const FormatCountCapture& v, FormatConversionSpecImpl conv,
0388 FormatSinkImpl* sink) {
0389 const absl::enable_if_t<sizeof(T) != 0, FormatCountCapture>& v2 = v;
0390
0391 if (conv.conversion_char() !=
0392 str_format_internal::FormatConversionCharInternal::n) {
0393 return {false};
0394 }
0395 *v2.p_ = static_cast<int>(sink->size());
0396 return {true};
0397 }
0398 };
0399
0400 template <class T = int>
0401 ArgConvertResult<FormatConversionCharSetInternal::n> FormatConvertImpl(
0402 const FormatCountCapture& v, FormatConversionSpecImpl conv,
0403 FormatSinkImpl* sink) {
0404 return FormatCountCaptureHelper::ConvertHelper(v, conv, sink);
0405 }
0406
0407
0408
0409 struct FormatArgImplFriend {
0410 template <typename Arg>
0411 static bool ToInt(Arg arg, int* out) {
0412
0413
0414 return arg.dispatcher_(arg.data_, {}, out);
0415 }
0416
0417 template <typename Arg>
0418 static bool Convert(Arg arg, FormatConversionSpecImpl conv,
0419 FormatSinkImpl* out) {
0420 return arg.dispatcher_(arg.data_, conv, out);
0421 }
0422
0423 template <typename Arg>
0424 static typename Arg::Dispatcher GetVTablePtrForTest(Arg arg) {
0425 return arg.dispatcher_;
0426 }
0427 };
0428
0429 template <typename Arg>
0430 constexpr FormatConversionCharSet ArgumentToConv() {
0431 using ConvResult = decltype(str_format_internal::FormatConvertImpl(
0432 std::declval<const Arg&>(),
0433 std::declval<const FormatConversionSpecImpl&>(),
0434 std::declval<FormatSinkImpl*>()));
0435 return absl::str_format_internal::ExtractCharSet(ConvResult{});
0436 }
0437
0438
0439 class FormatArgImpl {
0440 private:
0441 enum { kInlinedSpace = 8 };
0442
0443 using VoidPtr = str_format_internal::VoidPtr;
0444
0445 union Data {
0446 const void* ptr;
0447 const volatile void* volatile_ptr;
0448 char buf[kInlinedSpace];
0449 };
0450
0451 using Dispatcher = bool (*)(Data, FormatConversionSpecImpl, void* out);
0452
0453 template <typename T>
0454 struct store_by_value
0455 : std::integral_constant<bool, (sizeof(T) <= kInlinedSpace) &&
0456 (std::is_integral<T>::value ||
0457 std::is_floating_point<T>::value ||
0458 std::is_pointer<T>::value ||
0459 std::is_same<VoidPtr, T>::value)> {};
0460
0461 enum StoragePolicy { ByPointer, ByVolatilePointer, ByValue };
0462 template <typename T>
0463 struct storage_policy
0464 : std::integral_constant<StoragePolicy,
0465 (std::is_volatile<T>::value
0466 ? ByVolatilePointer
0467 : (store_by_value<T>::value ? ByValue
0468 : ByPointer))> {
0469 };
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479 template <typename T, typename = void>
0480 struct DecayType {
0481 static constexpr bool kHasUserDefined =
0482 str_format_internal::HasUserDefinedConvert<T>::value ||
0483 HasAbslStringify<T>::value;
0484 using type = typename std::conditional<
0485 !kHasUserDefined && std::is_convertible<T, const char*>::value,
0486 const char*,
0487 typename std::conditional<
0488 !kHasUserDefined && std::is_convertible<T, const wchar_t*>::value,
0489 const wchar_t*,
0490 typename std::conditional<
0491 !kHasUserDefined && std::is_convertible<T, VoidPtr>::value,
0492 VoidPtr,
0493 const T&>::type>::type>::type;
0494 };
0495 template <typename T>
0496 struct DecayType<
0497 T, typename std::enable_if<
0498 !str_format_internal::HasUserDefinedConvert<T>::value &&
0499 !HasAbslStringify<T>::value && std::is_enum<T>::value>::type> {
0500 using type = decltype(+typename std::underlying_type<T>::type());
0501 };
0502
0503 public:
0504 template <typename T>
0505 explicit FormatArgImpl(const T& value) {
0506 using D = typename DecayType<T>::type;
0507 static_assert(
0508 std::is_same<D, const T&>::value || storage_policy<D>::value == ByValue,
0509 "Decayed types must be stored by value");
0510 Init(static_cast<D>(value));
0511 }
0512
0513 private:
0514 friend struct str_format_internal::FormatArgImplFriend;
0515 template <typename T, StoragePolicy = storage_policy<T>::value>
0516 struct Manager;
0517
0518 template <typename T>
0519 struct Manager<T, ByPointer> {
0520 static Data SetValue(const T& value) {
0521 Data data;
0522 data.ptr = std::addressof(value);
0523 return data;
0524 }
0525
0526 static const T& Value(Data arg) { return *static_cast<const T*>(arg.ptr); }
0527 };
0528
0529 template <typename T>
0530 struct Manager<T, ByVolatilePointer> {
0531 static Data SetValue(const T& value) {
0532 Data data;
0533 data.volatile_ptr = &value;
0534 return data;
0535 }
0536
0537 static const T& Value(Data arg) {
0538 return *static_cast<const T*>(arg.volatile_ptr);
0539 }
0540 };
0541
0542 template <typename T>
0543 struct Manager<T, ByValue> {
0544 static Data SetValue(const T& value) {
0545 Data data;
0546 memcpy(data.buf, &value, sizeof(value));
0547 return data;
0548 }
0549
0550 static T Value(Data arg) {
0551 T value;
0552 memcpy(&value, arg.buf, sizeof(T));
0553 return value;
0554 }
0555 };
0556
0557 template <typename T>
0558 void Init(const T& value) {
0559 data_ = Manager<T>::SetValue(value);
0560 dispatcher_ = &Dispatch<T>;
0561 }
0562
0563 template <typename T>
0564 static int ToIntVal(const T& val) {
0565 using CommonType = typename std::conditional<std::is_signed<T>::value,
0566 int64_t, uint64_t>::type;
0567 if (static_cast<CommonType>(val) >
0568 static_cast<CommonType>((std::numeric_limits<int>::max)())) {
0569 return (std::numeric_limits<int>::max)();
0570 } else if (std::is_signed<T>::value &&
0571 static_cast<CommonType>(val) <
0572 static_cast<CommonType>((std::numeric_limits<int>::min)())) {
0573 return (std::numeric_limits<int>::min)();
0574 }
0575 return static_cast<int>(val);
0576 }
0577
0578 template <typename T>
0579 static bool ToInt(Data arg, int* out, std::true_type ,
0580 std::false_type) {
0581 *out = ToIntVal(Manager<T>::Value(arg));
0582 return true;
0583 }
0584
0585 template <typename T>
0586 static bool ToInt(Data arg, int* out, std::false_type,
0587 std::true_type ) {
0588 *out = ToIntVal(static_cast<typename std::underlying_type<T>::type>(
0589 Manager<T>::Value(arg)));
0590 return true;
0591 }
0592
0593 template <typename T>
0594 static bool ToInt(Data, int*, std::false_type, std::false_type) {
0595 return false;
0596 }
0597
0598 template <typename T>
0599 static bool Dispatch(Data arg, FormatConversionSpecImpl spec, void* out) {
0600
0601 if (ABSL_PREDICT_FALSE(spec.conversion_char() ==
0602 FormatConversionCharInternal::kNone)) {
0603 return ToInt<T>(arg, static_cast<int*>(out), std::is_integral<T>(),
0604 std::is_enum<T>());
0605 }
0606 if (ABSL_PREDICT_FALSE(!Contains(ArgumentToConv<T>(),
0607 spec.conversion_char()))) {
0608 return false;
0609 }
0610 return str_format_internal::FormatConvertImpl(
0611 Manager<T>::Value(arg), spec,
0612 static_cast<FormatSinkImpl*>(out))
0613 .value;
0614 }
0615
0616 Data data_;
0617 Dispatcher dispatcher_;
0618 };
0619
0620 #define ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(T, E) \
0621 E template bool FormatArgImpl::Dispatch<T>(Data, FormatConversionSpecImpl, \
0622 void*)
0623
0624 #define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_NO_WSTRING_VIEW_(...) \
0625 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(str_format_internal::VoidPtr, \
0626 __VA_ARGS__); \
0627 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(bool, __VA_ARGS__); \
0628 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(char, __VA_ARGS__); \
0629 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(signed char, __VA_ARGS__); \
0630 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned char, __VA_ARGS__); \
0631 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(short, __VA_ARGS__); \
0632 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned short, \
0633 __VA_ARGS__); \
0634 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(int, __VA_ARGS__); \
0635 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned int, __VA_ARGS__); \
0636 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long, __VA_ARGS__); \
0637 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned long, \
0638 __VA_ARGS__); \
0639 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long long, \
0640 __VA_ARGS__); \
0641 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned long long, \
0642 __VA_ARGS__); \
0643 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(int128, __VA_ARGS__); \
0644 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(uint128, __VA_ARGS__); \
0645 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(float, __VA_ARGS__); \
0646 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(double, __VA_ARGS__); \
0647 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long double, __VA_ARGS__); \
0648 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(const char*, __VA_ARGS__); \
0649 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::string, __VA_ARGS__); \
0650 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(string_view, __VA_ARGS__); \
0651 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(const wchar_t*, __VA_ARGS__); \
0652 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::wstring, __VA_ARGS__)
0653
0654 #if defined(ABSL_HAVE_STD_STRING_VIEW)
0655 #define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(...) \
0656 ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_NO_WSTRING_VIEW_( \
0657 __VA_ARGS__); \
0658 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::wstring_view, __VA_ARGS__)
0659 #else
0660 #define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(...) \
0661 ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_NO_WSTRING_VIEW_(__VA_ARGS__)
0662 #endif
0663
0664 ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(extern);
0665
0666
0667 }
0668 ABSL_NAMESPACE_END
0669 }
0670
0671 #endif