15 #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_
16 #define ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_
27 #include <type_traits>
29 #include "absl/base/port.h"
30 #include "absl/meta/type_traits.h"
31 #include "absl/numeric/int128.h"
32 #include "absl/strings/internal/str_format/extension.h"
33 #include "absl/strings/string_view.h"
39 class FormatCountCapture;
42 template <absl::FormatConversionCharSet C>
48 template <
typename T,
typename =
void>
53 std::declval<const T&>(),
54 std::declval<const FormatConversionSpec&>(),
55 std::declval<FormatSink*>()))>>
63 std::declval<const FormatConversionSpec&>(),
64 std::declval<FormatSink*>())) {
65 using FormatConversionSpecT =
69 auto fcs =
conv.
Wrap<FormatConversionSpecT>();
92 decltype(
reinterpret_cast<uintptr_t>(std::declval<T*>())) = 0>
98 template <FormatConversionCharSet C>
103 template <FormatConversionCharSet C>
108 template <FormatConversionCharSet C>
125 #if defined(ABSL_HAVE_STD_STRING_VIEW) && !defined(ABSL_USES_STD_STRING_VIEW)
131 #endif // ABSL_HAVE_STD_STRING_VIEW && !ABSL_USES_STD_STRING_VIEW
136 FormatSinkImpl*
sink);
138 template <
class AbslCord,
typename std::enable_if<std::is_same<
144 size_t space_remaining = 0;
147 if (
width >= 0) space_remaining =
static_cast<size_t>(
width);
149 size_t to_write =
value.size();
155 space_remaining =
Excess(to_write, space_remaining);
157 if (space_remaining > 0 && !is_left)
sink->
Append(space_remaining,
' ');
160 if (piece.size() > to_write) {
161 piece.remove_suffix(piece.size() - to_write);
164 to_write -= piece.size();
172 if (space_remaining > 0 && is_left)
sink->
Append(space_remaining,
' ');
239 template <
typename T>
245 template <
typename T>
249 std::ostringstream oss;
251 if (!oss)
return {
false};
258 template <
class T =
int>
264 if (
conv.conversion_char() !=
265 str_format_internal::FormatConversionCharInternal::n) {
268 *v2.p_ =
static_cast<int>(
sink->size());
273 template <
class T =
int>
283 template <
typename Arg>
287 return arg.dispatcher_(
arg.data_, {},
out);
290 template <
typename Arg>
296 template <
typename Arg>
298 return arg.dispatcher_;
302 template <
typename Arg>
306 std::declval<const Arg&>(),
307 std::declval<const FormatConversionSpecImpl&>(),
308 std::declval<FormatSinkImpl*>())){});
326 template <
typename T>
328 : std::integral_constant<bool, (sizeof(T) <= kInlinedSpace) &&
329 (std::is_integral<T>::value ||
330 std::is_floating_point<T>::value ||
331 std::is_pointer<T>::value ||
332 std::is_same<VoidPtr, T>::value)> {};
334 enum StoragePolicy { ByPointer, ByVolatilePointer, ByValue };
335 template <typename T>
336 struct storage_policy
337 : std::integral_constant<StoragePolicy,
338 (std::is_volatile<T>::value
340 : (store_by_value<T>::value ? ByValue
351 template <typename T, typename = void>
353 static constexpr bool kHasUserDefined =
354 str_format_internal::HasUserDefinedConvert<T>::value;
355 using type = typename std::conditional<
356 !kHasUserDefined && std::is_convertible<T, const char*>::value,
358 typename std::conditional<!kHasUserDefined &&
359 std::is_convertible<T, VoidPtr>::value,
360 VoidPtr, const T&>::type>::type;
362 template <typename T>
364 typename std::enable_if<
365 !str_format_internal::HasUserDefinedConvert<T>::value &&
366 std::is_enum<T>::value>::type> {
367 using type = typename std::underlying_type<T>::type;
371 template <typename T>
372 explicit FormatArgImpl(const T& value) {
373 using D = typename DecayType<T>::type;
375 std::is_same<D, const T&>::value || storage_policy<D>::value == ByValue,
376 "Decayed types must be stored by value");
377 Init(static_cast<D>(value));
381 friend struct str_format_internal::FormatArgImplFriend;
382 template <typename T, StoragePolicy = storage_policy<T>::value>
385 template <typename T>
386 struct Manager<T, ByPointer> {
387 static Data SetValue(const T& value) {
389 data.ptr = std::addressof(value);
393 static const T& Value(Data arg) { return *static_cast<const T*>(arg.ptr); }
396 template <typename T>
397 struct Manager<T, ByVolatilePointer> {
398 static Data SetValue(const T& value) {
400 data.volatile_ptr = &value;
404 static const T& Value(Data arg) {
405 return *static_cast<const T*>(arg.volatile_ptr);
409 template <typename T>
410 struct Manager<T, ByValue> {
411 static Data SetValue(const T& value) {
413 memcpy(data.buf, &value, sizeof(value));
417 static T Value(Data arg) {
419 memcpy(&value, arg.buf, sizeof(T));
424 template <typename T>
425 void Init(const T& value) {
426 data_ = Manager<T>::SetValue(value);
427 dispatcher_ = &Dispatch<T>;
430 template <typename T>
431 static int ToIntVal(const T& val) {
432 using CommonType = typename std::conditional<std::is_signed<T>::value,
433 int64_t, uint64_t>::type;
434 if (static_cast<CommonType>(val) >
435 static_cast<CommonType>((std::numeric_limits<int>::max)())) {
438 static_cast<CommonType
>(val) <
442 return static_cast<int>(val);
445 template <
typename T>
452 template <
typename T>
460 template <
typename T>
465 template <
typename T>
470 return ToInt<T>(
arg,
static_cast<int*
>(
out), std::is_integral<T>(),
474 spec.conversion_char()))) {
487 #define ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(T, E) \
488 E template bool FormatArgImpl::Dispatch<T>(Data, FormatConversionSpecImpl, \
491 #define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(...) \
492 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(str_format_internal::VoidPtr, \
494 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(bool, __VA_ARGS__); \
495 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(char, __VA_ARGS__); \
496 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(signed char, __VA_ARGS__); \
497 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned char, __VA_ARGS__); \
498 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(short, __VA_ARGS__); \
499 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned short, \
501 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(int, __VA_ARGS__); \
502 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned int, __VA_ARGS__); \
503 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long, __VA_ARGS__); \
504 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned long, \
506 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long long, \
508 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned long long, \
510 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(int128, __VA_ARGS__); \
511 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(uint128, __VA_ARGS__); \
512 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(float, __VA_ARGS__); \
513 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(double, __VA_ARGS__); \
514 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long double, __VA_ARGS__); \
515 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(const char*, __VA_ARGS__); \
516 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::string, __VA_ARGS__); \
517 ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(string_view, __VA_ARGS__)
526 #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_