14 #ifndef LLVM_SUPPORT_FORMATPROVIDERS_H
15 #define LLVM_SUPPORT_FORMATPROVIDERS_H
24 #include <type_traits>
31 :
public std::integral_constant<
32 bool, is_one_of<T, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
33 int64_t, uint64_t, int, unsigned, long, unsigned long,
34 long long, unsigned long long>::value> {};
38 :
public std::integral_constant<bool, std::is_same<T, char>::value> {};
42 :
public std::integral_constant<bool,
43 is_one_of<T, char *, const char *>::value> {
48 :
public std::integral_constant<bool,
49 std::is_convertible<T, llvm::StringRef>::value> {};
53 :
public std::integral_constant<bool, std::is_pointer<T>::value &&
54 !is_cstring<T>::value> {};
58 :
public std::integral_constant<bool, std::is_floating_point<T>::value> {};
67 else if (Str.getAsInteger(10, Prec)) {
68 assert(
false &&
"Invalid precision specifier");
71 assert(Prec < 100 &&
"Precision out of range");
72 Result = std::min<size_t>(99u, Prec);
78 if (!Str.startswith_insensitive(
"x"))
81 if (Str.consume_front(
"x-"))
83 else if (Str.consume_front(
"X-"))
85 else if (Str.consume_front(
"x+") || Str.consume_front(
"x"))
87 else if (Str.consume_front(
"X+") || Str.consume_front(
"X"))
94 Str.consumeInteger(10, Default);
125 template <
typename T>
127 T,
std::enable_if_t<detail::use_integral_formatter<T>::value>>
134 if (consumeHexStyle(
Style,
HS)) {
135 Digits = consumeNumHexDigits(
Style,
HS, 0);
141 if (
Style.consume_front(
"N") ||
Style.consume_front(
"n"))
143 else if (
Style.consume_front(
"D") ||
Style.consume_front(
"d"))
146 Style.consumeInteger(10, Digits);
147 assert(
Style.empty() &&
"Invalid integral format style!");
174 template <
typename T>
176 T,
std::enable_if_t<detail::use_pointer_formatter<T>::value>>
183 size_t Digits = consumeNumHexDigits(
Style,
HS,
sizeof(
void *) * 2);
184 write_hex(Stream,
reinterpret_cast<std::uintptr_t
>(V),
HS, Digits);
199 template <
typename T>
201 T,
std::enable_if_t<detail::use_string_formatter<T>::value>> {
205 assert(
false &&
"Style is not a valid integer");
208 Stream <<
S.substr(0,
N);
232 template <
typename T>
234 std::enable_if_t<detail::use_char_formatter<T>::value>> {
240 int X =
static_cast<int>(V);
265 Stream << StringSwitch<const char *>(
Style)
266 .Case(
"Y",
B ?
"YES" :
"NO")
267 .Case(
"y",
B ?
"yes" :
"no")
268 .CaseLower(
"D",
B ?
"1" :
"0")
269 .Case(
"T",
B ?
"TRUE" :
"FALSE")
270 .Cases(
"t",
"",
B ?
"true" :
"false")
271 .Default(
B ?
"1" :
"0");
298 template <
typename T>
300 std::enable_if_t<detail::use_double_formatter<T>::value>>
304 if (
Style.consume_front(
"P") ||
Style.consume_front(
"p"))
306 else if (
Style.consume_front(
"F") ||
Style.consume_front(
"f"))
308 else if (
Style.consume_front(
"E"))
310 else if (
Style.consume_front(
"e"))
324 template <
typename IterT>
325 using IterValue =
typename std::iterator_traits<IterT>::value_type;
327 template <
typename IterT>
329 :
public std::integral_constant<
330 bool, !uses_missing_provider<IterValue<IterT>>::value> {};
357 using value =
typename std::iterator_traits<IterT>::value_type;
358 using reference =
typename std::iterator_traits<IterT>::reference;
364 if (
Style.front() != Indicator)
368 assert(
false &&
"Invalid range style");
372 for (
const char *
D : {
"[]",
"<>",
"()"}) {
373 if (
Style.front() !=
D[0])
375 size_t End =
Style.find_first_of(
D[1]);
377 assert(
false &&
"Missing range option end delimeter!");
384 assert(
false &&
"Invalid range style!");
388 static std::pair<StringRef, StringRef> parseOptions(
StringRef Style) {
391 assert(
Style.empty() &&
"Unexpected text in range option string!");
392 return std::make_pair(Sep,
Args);
397 "Range value_type does not have a format provider!");
402 std::tie(Sep, ArgStyle) = parseOptions(
Style);
403 auto Begin = V.
begin();
408 Adapter.format(Stream, ArgStyle);
411 while (Begin != End) {
415 Adapter.format(Stream, ArgStyle);