File indexing completed on 2026-05-10 08:44:30
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_SUPPORT_FORMATVARIADICDETAILS_H
0010 #define LLVM_SUPPORT_FORMATVARIADICDETAILS_H
0011
0012 #include "llvm/ADT/StringRef.h"
0013 #include "llvm/ADT/STLExtras.h"
0014 #include "llvm/Support/raw_ostream.h"
0015
0016 #include <type_traits>
0017
0018 namespace llvm {
0019 template <typename T, typename Enable = void> struct format_provider {};
0020 class Error;
0021
0022 namespace support {
0023 namespace detail {
0024 class format_adapter {
0025 virtual void anchor();
0026
0027 protected:
0028 virtual ~format_adapter() = default;
0029
0030 public:
0031 virtual void format(raw_ostream &S, StringRef Options) = 0;
0032 };
0033
0034 template <typename T> class provider_format_adapter : public format_adapter {
0035 T Item;
0036
0037 public:
0038 explicit provider_format_adapter(T &&Item) : Item(std::forward<T>(Item)) {}
0039
0040 void format(llvm::raw_ostream &S, StringRef Options) override {
0041 format_provider<std::decay_t<T>>::format(Item, S, Options);
0042 }
0043 };
0044
0045 template <typename T>
0046 class stream_operator_format_adapter : public format_adapter {
0047 T Item;
0048
0049 public:
0050 explicit stream_operator_format_adapter(T &&Item)
0051 : Item(std::forward<T>(Item)) {}
0052
0053 void format(llvm::raw_ostream &S, StringRef) override { S << Item; }
0054 };
0055
0056 template <typename T> class missing_format_adapter;
0057
0058
0059
0060
0061
0062 template <class T> class has_FormatProvider {
0063 public:
0064 using Decayed = std::decay_t<T>;
0065 typedef void (*Signature_format)(const Decayed &, llvm::raw_ostream &,
0066 StringRef);
0067
0068 template <typename U>
0069 static char test(SameType<Signature_format, &U::format> *);
0070
0071 template <typename U> static double test(...);
0072
0073 static bool const value =
0074 (sizeof(test<llvm::format_provider<Decayed>>(nullptr)) == 1);
0075 };
0076
0077
0078 template <class T> class has_StreamOperator {
0079 public:
0080 using ConstRefT = const std::decay_t<T> &;
0081
0082 template <typename U>
0083 static char test(std::enable_if_t<
0084 std::is_same_v<decltype(std::declval<llvm::raw_ostream &>()
0085 << std::declval<U>()),
0086 llvm::raw_ostream &>,
0087 int *>);
0088
0089 template <typename U> static double test(...);
0090
0091 static bool const value = (sizeof(test<ConstRefT>(nullptr)) == 1);
0092 };
0093
0094
0095
0096 template <typename T>
0097 struct uses_format_member
0098 : public std::integral_constant<
0099 bool, std::is_base_of_v<format_adapter, std::remove_reference_t<T>>> {
0100 };
0101
0102
0103
0104
0105 template <typename T>
0106 struct uses_format_provider
0107 : public std::integral_constant<
0108 bool, !uses_format_member<T>::value && has_FormatProvider<T>::value> {
0109 };
0110
0111
0112
0113 template <typename T>
0114 struct uses_stream_operator
0115 : public std::integral_constant<bool, !uses_format_member<T>::value &&
0116 !uses_format_provider<T>::value &&
0117 has_StreamOperator<T>::value> {};
0118
0119
0120
0121
0122
0123 template <typename T>
0124 struct uses_missing_provider
0125 : public std::integral_constant<bool, !uses_format_member<T>::value &&
0126 !uses_format_provider<T>::value &&
0127 !uses_stream_operator<T>::value> {
0128 };
0129
0130 template <typename T>
0131 std::enable_if_t<uses_format_member<T>::value, T>
0132 build_format_adapter(T &&Item) {
0133 return std::forward<T>(Item);
0134 }
0135
0136 template <typename T>
0137 std::enable_if_t<uses_format_provider<T>::value, provider_format_adapter<T>>
0138 build_format_adapter(T &&Item) {
0139 return provider_format_adapter<T>(std::forward<T>(Item));
0140 }
0141
0142 template <typename T>
0143 std::enable_if_t<uses_stream_operator<T>::value,
0144 stream_operator_format_adapter<T>>
0145 build_format_adapter(T &&Item) {
0146
0147
0148
0149 static_assert(
0150 !std::is_same_v<llvm::Error, std::remove_cv_t<T>>,
0151 "llvm::Error-by-value must be wrapped in fmt_consume() for formatv");
0152 return stream_operator_format_adapter<T>(std::forward<T>(Item));
0153 }
0154
0155 template <typename T>
0156 std::enable_if_t<uses_missing_provider<T>::value, missing_format_adapter<T>>
0157 build_format_adapter(T &&) {
0158 return missing_format_adapter<T>();
0159 }
0160 }
0161 }
0162 }
0163
0164 #endif