1311116Sdim//===- FormatAdapters.h - Formatters for common LLVM types -----*- C++ -*-===//
2311116Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6311116Sdim//
7311116Sdim//===----------------------------------------------------------------------===//
8311116Sdim
9311116Sdim#ifndef LLVM_SUPPORT_FORMATADAPTERS_H
10311116Sdim#define LLVM_SUPPORT_FORMATADAPTERS_H
11311116Sdim
12311116Sdim#include "llvm/ADT/SmallString.h"
13311116Sdim#include "llvm/ADT/StringRef.h"
14341825Sdim#include "llvm/Support/Error.h"
15311116Sdim#include "llvm/Support/FormatCommon.h"
16311116Sdim#include "llvm/Support/FormatVariadicDetails.h"
17311116Sdim#include "llvm/Support/raw_ostream.h"
18311116Sdim
19311116Sdimnamespace llvm {
20311116Sdimtemplate <typename T> class FormatAdapter : public detail::format_adapter {
21311116Sdimprotected:
22341825Sdim  explicit FormatAdapter(T &&Item) : Item(std::forward<T>(Item)) {}
23311116Sdim
24311116Sdim  T Item;
25311116Sdim};
26311116Sdim
27311116Sdimnamespace detail {
28311116Sdimtemplate <typename T> class AlignAdapter final : public FormatAdapter<T> {
29311116Sdim  AlignStyle Where;
30311116Sdim  size_t Amount;
31321369Sdim  char Fill;
32311116Sdim
33311116Sdimpublic:
34321369Sdim  AlignAdapter(T &&Item, AlignStyle Where, size_t Amount, char Fill)
35321369Sdim      : FormatAdapter<T>(std::forward<T>(Item)), Where(Where), Amount(Amount),
36321369Sdim        Fill(Fill) {}
37311116Sdim
38311116Sdim  void format(llvm::raw_ostream &Stream, StringRef Style) {
39311116Sdim    auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
40321369Sdim    FmtAlign(Adapter, Where, Amount, Fill).format(Stream, Style);
41311116Sdim  }
42311116Sdim};
43311116Sdim
44311116Sdimtemplate <typename T> class PadAdapter final : public FormatAdapter<T> {
45311116Sdim  size_t Left;
46311116Sdim  size_t Right;
47311116Sdim
48311116Sdimpublic:
49311116Sdim  PadAdapter(T &&Item, size_t Left, size_t Right)
50311116Sdim      : FormatAdapter<T>(std::forward<T>(Item)), Left(Left), Right(Right) {}
51311116Sdim
52311116Sdim  void format(llvm::raw_ostream &Stream, StringRef Style) {
53311116Sdim    auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
54311116Sdim    Stream.indent(Left);
55311116Sdim    Adapter.format(Stream, Style);
56311116Sdim    Stream.indent(Right);
57311116Sdim  }
58311116Sdim};
59311116Sdim
60311116Sdimtemplate <typename T> class RepeatAdapter final : public FormatAdapter<T> {
61311116Sdim  size_t Count;
62311116Sdim
63311116Sdimpublic:
64311116Sdim  RepeatAdapter(T &&Item, size_t Count)
65311116Sdim      : FormatAdapter<T>(std::forward<T>(Item)), Count(Count) {}
66311116Sdim
67311116Sdim  void format(llvm::raw_ostream &Stream, StringRef Style) {
68311116Sdim    auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
69311116Sdim    for (size_t I = 0; I < Count; ++I) {
70311116Sdim      Adapter.format(Stream, Style);
71311116Sdim    }
72311116Sdim  }
73311116Sdim};
74341825Sdim
75341825Sdimclass ErrorAdapter : public FormatAdapter<Error> {
76341825Sdimpublic:
77341825Sdim  ErrorAdapter(Error &&Item) : FormatAdapter(std::move(Item)) {}
78341825Sdim  ErrorAdapter(ErrorAdapter &&) = default;
79341825Sdim  ~ErrorAdapter() { consumeError(std::move(Item)); }
80341825Sdim  void format(llvm::raw_ostream &Stream, StringRef Style) { Stream << Item; }
81341825Sdim};
82311116Sdim}
83311116Sdim
84311116Sdimtemplate <typename T>
85321369Sdimdetail::AlignAdapter<T> fmt_align(T &&Item, AlignStyle Where, size_t Amount,
86321369Sdim                                  char Fill = ' ') {
87321369Sdim  return detail::AlignAdapter<T>(std::forward<T>(Item), Where, Amount, Fill);
88311116Sdim}
89311116Sdim
90311116Sdimtemplate <typename T>
91311116Sdimdetail::PadAdapter<T> fmt_pad(T &&Item, size_t Left, size_t Right) {
92311116Sdim  return detail::PadAdapter<T>(std::forward<T>(Item), Left, Right);
93311116Sdim}
94311116Sdim
95311116Sdimtemplate <typename T>
96311116Sdimdetail::RepeatAdapter<T> fmt_repeat(T &&Item, size_t Count) {
97311116Sdim  return detail::RepeatAdapter<T>(std::forward<T>(Item), Count);
98311116Sdim}
99341825Sdim
100341825Sdim// llvm::Error values must be consumed before being destroyed.
101341825Sdim// Wrapping an error in fmt_consume explicitly indicates that the formatv_object
102341825Sdim// should take ownership and consume it.
103341825Sdiminline detail::ErrorAdapter fmt_consume(Error &&Item) {
104341825Sdim  return detail::ErrorAdapter(std::move(Item));
105311116Sdim}
106341825Sdim}
107311116Sdim
108311116Sdim#endif
109