14#ifndef LLVM_SUPPORT_FORMATPROVIDERS_H
15#define LLVM_SUPPORT_FORMATPROVIDERS_H
32 :
public std::integral_constant<
33 bool, is_one_of<T, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
34 int64_t, uint64_t, int, unsigned, long, unsigned long,
35 long long, unsigned long long>::value> {};
39 :
public std::integral_constant<bool, std::is_same_v<T, char>> {};
43 :
public std::integral_constant<bool,
44 is_one_of<T, char *, const char *>::value> {
49 :
public std::integral_constant<bool,
50 std::is_convertible_v<T, llvm::StringRef>> {
55 :
public std::integral_constant<bool, std::is_pointer_v<T> &&
56 !is_cstring<T>::value> {};
60 :
public std::integral_constant<bool, std::is_floating_point_v<T>> {};
66 std::optional<size_t> Result;
68 Result = std::nullopt;
69 else if (Str.getAsInteger(10, Prec)) {
70 assert(
false &&
"Invalid precision specifier");
71 Result = std::nullopt;
73 assert(Prec < 100 &&
"Precision out of range");
74 Result = std::min<size_t>(99u, Prec);
80 if (!Str.starts_with_insensitive(
"x"))
83 if (Str.consume_front(
"x-"))
85 if (Str.consume_front(
"X-"))
87 if (Str.consume_front(
"x+") || Str.consume_front(
"x"))
89 if (!Str.consume_front(
"X+"))
90 Str.consume_front(
"X");
96 Str.consumeInteger(10,
Default);
130 T,
std::enable_if_t<support::detail::use_integral_formatter<T>::value>>
136 if (std::optional<HexPrintStyle> HS = consumeHexStyle(Style)) {
137 Digits = consumeNumHexDigits(Style, *HS, 0);
143 if (Style.consume_front(
"N") || Style.consume_front(
"n"))
145 else if (Style.consume_front(
"D") || Style.consume_front(
"d"))
148 Style.consumeInteger(10, Digits);
149 assert(Style.empty() &&
"Invalid integral format style!");
178 T,
std::enable_if_t<support::detail::use_pointer_formatter<T>::value>>
184 if (std::optional<HexPrintStyle> consumed = consumeHexStyle(Style))
186 size_t Digits = consumeNumHexDigits(Style, HS,
sizeof(
void *) * 2);
187 write_hex(Stream,
reinterpret_cast<std::uintptr_t
>(V), HS, Digits);
204 T,
std::enable_if_t<support::detail::use_string_formatter<T>::value>> {
207 if (!Style.empty() && Style.getAsInteger(10,
N)) {
208 assert(
false &&
"Style is not a valid integer");
237 T,
std::enable_if_t<support::detail::use_char_formatter<T>::value>> {
243 int X =
static_cast<int>(V);
268 Stream << StringSwitch<const char *>(Style)
269 .Case(
"Y",
B ?
"YES" :
"NO")
270 .Case(
"y",
B ?
"yes" :
"no")
271 .CaseLower(
"D",
B ?
"1" :
"0")
272 .Case(
"T",
B ?
"TRUE" :
"FALSE")
273 .Cases(
"t",
"",
B ?
"true" :
"false")
274 .Default(
B ?
"1" :
"0");
303 T,
std::enable_if_t<support::detail::use_double_formatter<T>::value>>
307 if (Style.consume_front(
"P") || Style.consume_front(
"p"))
309 else if (Style.consume_front(
"F") || Style.consume_front(
"f"))
311 else if (Style.consume_front(
"E"))
313 else if (Style.consume_front(
"e"))
318 std::optional<size_t> Precision = parseNumericPrecision(Style);
322 write_double(Stream,
static_cast<double>(V), S, Precision);
328template <
typename IterT>
329using IterValue =
typename std::iterator_traits<IterT>::value_type;
331template <
typename IterT>
333 :
public std::integral_constant<
335 !support::detail::uses_missing_provider<IterValue<IterT>>::value> {};
363 using value =
typename std::iterator_traits<IterT>::value_type;
369 if (Style.front() != Indicator)
371 Style = Style.drop_front();
373 assert(
false &&
"Invalid range style");
377 for (
const char *
D : std::array<const char *, 3>{
"[]",
"<>",
"()"}) {
378 if (Style.front() !=
D[0])
380 size_t End = Style.find_first_of(
D[1]);
382 assert(
false &&
"Missing range option end delimeter!");
386 Style = Style.drop_front(
End + 1);
389 assert(
false &&
"Invalid range style!");
393 static std::pair<StringRef, StringRef> parseOptions(
StringRef Style) {
394 StringRef Sep = consumeOneOption(Style,
'$',
", ");
395 StringRef Args = consumeOneOption(Style,
'@',
"");
396 assert(Style.empty() &&
"Unexpected text in range option string!");
397 return std::make_pair(Sep, Args);
402 "Range value_type does not have a format provider!");
407 std::tie(Sep, ArgStyle) = parseOptions(Style);
408 auto Begin = V.begin();
412 Adapter.format(Stream, ArgStyle);
415 while (Begin !=
End) {
418 Adapter.format(Stream, ArgStyle);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
static constexpr size_t npos
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
static size_t consumeNumHexDigits(StringRef &Str, HexPrintStyle Style, size_t Default)
static std::optional< size_t > parseNumericPrecision(StringRef Str)
static std::optional< HexPrintStyle > consumeHexStyle(StringRef &Str)
std::enable_if_t< uses_format_member< T >::value, T > build_format_adapter(T &&Item)
typename std::iterator_traits< IterT >::value_type IterValue
This is an optimization pass for GlobalISel generic memory operations.
void write_integer(raw_ostream &S, unsigned int N, size_t MinDigits, IntegerStyle Style)
size_t getDefaultPrecision(FloatStyle Style)
void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, std::optional< size_t > Width=std::nullopt)
void write_double(raw_ostream &S, double D, FloatStyle Style, std::optional< size_t > Precision=std::nullopt)
@ Default
The result values are uniform if and only if all operands are uniform.
bool isPrefixedHexStyle(HexPrintStyle S)
Implement std::hash so that hash_code can be used in STL containers.