1 //===- FormatAdapters.h - Formatters for common LLVM types -----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_SUPPORT_FORMATADAPTERS_H 10 #define LLVM_SUPPORT_FORMATADAPTERS_H 11 12 #include "llvm/ADT/StringRef.h" 13 #include "llvm/Support/Error.h" 14 #include "llvm/Support/FormatCommon.h" 15 #include "llvm/Support/FormatVariadicDetails.h" 16 #include "llvm/Support/raw_ostream.h" 17 18 namespace llvm { 19 template <typename T> 20 class FormatAdapter : public support::detail::format_adapter { 21 protected: 22 explicit FormatAdapter(T &&Item) : Item(std::forward<T>(Item)) {} 23 24 T Item; 25 }; 26 27 namespace support { 28 namespace detail { 29 template <typename T> class AlignAdapter final : public FormatAdapter<T> { 30 AlignStyle Where; 31 size_t Amount; 32 char Fill; 33 34 public: 35 AlignAdapter(T &&Item, AlignStyle Where, size_t Amount, char Fill) 36 : FormatAdapter<T>(std::forward<T>(Item)), Where(Where), Amount(Amount), 37 Fill(Fill) {} 38 39 void format(llvm::raw_ostream &Stream, StringRef Style) override { 40 auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item)); 41 FmtAlign(Adapter, Where, Amount, Fill).format(Stream, Style); 42 } 43 }; 44 45 template <typename T> class PadAdapter final : public FormatAdapter<T> { 46 size_t Left; 47 size_t Right; 48 49 public: 50 PadAdapter(T &&Item, size_t Left, size_t Right) 51 : FormatAdapter<T>(std::forward<T>(Item)), Left(Left), Right(Right) {} 52 53 void format(llvm::raw_ostream &Stream, StringRef Style) override { 54 auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item)); 55 Stream.indent(Left); 56 Adapter.format(Stream, Style); 57 Stream.indent(Right); 58 } 59 }; 60 61 template <typename T> class RepeatAdapter final : public FormatAdapter<T> { 62 size_t Count; 63 64 public: 65 RepeatAdapter(T &&Item, size_t Count) 66 : FormatAdapter<T>(std::forward<T>(Item)), Count(Count) {} 67 68 void format(llvm::raw_ostream &Stream, StringRef Style) override { 69 auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item)); 70 for (size_t I = 0; I < Count; ++I) { 71 Adapter.format(Stream, Style); 72 } 73 } 74 }; 75 76 class ErrorAdapter : public FormatAdapter<Error> { 77 public: 78 ErrorAdapter(Error &&Item) : FormatAdapter(std::move(Item)) {} 79 ErrorAdapter(ErrorAdapter &&) = default; 80 ~ErrorAdapter() { consumeError(std::move(Item)); } 81 void format(llvm::raw_ostream &Stream, StringRef Style) override { 82 Stream << Item; 83 } 84 }; 85 } // namespace detail 86 } // namespace support 87 88 template <typename T> 89 support::detail::AlignAdapter<T> fmt_align(T &&Item, AlignStyle Where, 90 size_t Amount, char Fill = ' ') { 91 return support::detail::AlignAdapter<T>(std::forward<T>(Item), Where, Amount, 92 Fill); 93 } 94 95 template <typename T> 96 support::detail::PadAdapter<T> fmt_pad(T &&Item, size_t Left, size_t Right) { 97 return support::detail::PadAdapter<T>(std::forward<T>(Item), Left, Right); 98 } 99 100 template <typename T> 101 support::detail::RepeatAdapter<T> fmt_repeat(T &&Item, size_t Count) { 102 return support::detail::RepeatAdapter<T>(std::forward<T>(Item), Count); 103 } 104 105 // llvm::Error values must be consumed before being destroyed. 106 // Wrapping an error in fmt_consume explicitly indicates that the formatv_object 107 // should take ownership and consume it. 108 inline support::detail::ErrorAdapter fmt_consume(Error &&Item) { 109 return support::detail::ErrorAdapter(std::move(Item)); 110 } 111 } 112 113 #endif 114