Home | History | Annotate | Line # | Download | only in Support
      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