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> class FormatAdapter : public detail::format_adapter { 20 protected: 21 explicit FormatAdapter(T &&Item) : Item(std::forward<T>(Item)) {} 22 23 T Item; 24 }; 25 26 namespace detail { 27 template <typename T> class AlignAdapter final : public FormatAdapter<T> { 28 AlignStyle Where; 29 size_t Amount; 30 char Fill; 31 32 public: 33 AlignAdapter(T &&Item, AlignStyle Where, size_t Amount, char Fill) 34 : FormatAdapter<T>(std::forward<T>(Item)), Where(Where), Amount(Amount), 35 Fill(Fill) {} 36 37 void format(llvm::raw_ostream &Stream, StringRef Style) override { 38 auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item)); 39 FmtAlign(Adapter, Where, Amount, Fill).format(Stream, Style); 40 } 41 }; 42 43 template <typename T> class PadAdapter final : public FormatAdapter<T> { 44 size_t Left; 45 size_t Right; 46 47 public: 48 PadAdapter(T &&Item, size_t Left, size_t Right) 49 : FormatAdapter<T>(std::forward<T>(Item)), Left(Left), Right(Right) {} 50 51 void format(llvm::raw_ostream &Stream, StringRef Style) override { 52 auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item)); 53 Stream.indent(Left); 54 Adapter.format(Stream, Style); 55 Stream.indent(Right); 56 } 57 }; 58 59 template <typename T> class RepeatAdapter final : public FormatAdapter<T> { 60 size_t Count; 61 62 public: 63 RepeatAdapter(T &&Item, size_t Count) 64 : FormatAdapter<T>(std::forward<T>(Item)), Count(Count) {} 65 66 void format(llvm::raw_ostream &Stream, StringRef Style) override { 67 auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item)); 68 for (size_t I = 0; I < Count; ++I) { 69 Adapter.format(Stream, Style); 70 } 71 } 72 }; 73 74 class ErrorAdapter : public FormatAdapter<Error> { 75 public: 76 ErrorAdapter(Error &&Item) : FormatAdapter(std::move(Item)) {} 77 ErrorAdapter(ErrorAdapter &&) = default; 78 ~ErrorAdapter() { consumeError(std::move(Item)); } 79 void format(llvm::raw_ostream &Stream, StringRef Style) override { 80 Stream << Item; 81 } 82 }; 83 } 84 85 template <typename T> 86 detail::AlignAdapter<T> fmt_align(T &&Item, AlignStyle Where, size_t Amount, 87 char Fill = ' ') { 88 return detail::AlignAdapter<T>(std::forward<T>(Item), Where, Amount, Fill); 89 } 90 91 template <typename T> 92 detail::PadAdapter<T> fmt_pad(T &&Item, size_t Left, size_t Right) { 93 return detail::PadAdapter<T>(std::forward<T>(Item), Left, Right); 94 } 95 96 template <typename T> 97 detail::RepeatAdapter<T> fmt_repeat(T &&Item, size_t Count) { 98 return detail::RepeatAdapter<T>(std::forward<T>(Item), Count); 99 } 100 101 // llvm::Error values must be consumed before being destroyed. 102 // Wrapping an error in fmt_consume explicitly indicates that the formatv_object 103 // should take ownership and consume it. 104 inline detail::ErrorAdapter fmt_consume(Error &&Item) { 105 return detail::ErrorAdapter(std::move(Item)); 106 } 107 } 108 109 #endif 110