106f32e7eSjoerg //===- FormatAdapters.h - Formatters for common LLVM types -----*- C++ -*-===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg 
906f32e7eSjoerg #ifndef LLVM_SUPPORT_FORMATADAPTERS_H
1006f32e7eSjoerg #define LLVM_SUPPORT_FORMATADAPTERS_H
1106f32e7eSjoerg 
1206f32e7eSjoerg #include "llvm/ADT/StringRef.h"
1306f32e7eSjoerg #include "llvm/Support/Error.h"
1406f32e7eSjoerg #include "llvm/Support/FormatCommon.h"
1506f32e7eSjoerg #include "llvm/Support/FormatVariadicDetails.h"
1606f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
1706f32e7eSjoerg 
1806f32e7eSjoerg namespace llvm {
1906f32e7eSjoerg template <typename T> class FormatAdapter : public detail::format_adapter {
2006f32e7eSjoerg protected:
FormatAdapter(T && Item)2106f32e7eSjoerg   explicit FormatAdapter(T &&Item) : Item(std::forward<T>(Item)) {}
2206f32e7eSjoerg 
2306f32e7eSjoerg   T Item;
2406f32e7eSjoerg };
2506f32e7eSjoerg 
2606f32e7eSjoerg namespace detail {
2706f32e7eSjoerg template <typename T> class AlignAdapter final : public FormatAdapter<T> {
2806f32e7eSjoerg   AlignStyle Where;
2906f32e7eSjoerg   size_t Amount;
3006f32e7eSjoerg   char Fill;
3106f32e7eSjoerg 
3206f32e7eSjoerg public:
AlignAdapter(T && Item,AlignStyle Where,size_t Amount,char Fill)3306f32e7eSjoerg   AlignAdapter(T &&Item, AlignStyle Where, size_t Amount, char Fill)
3406f32e7eSjoerg       : FormatAdapter<T>(std::forward<T>(Item)), Where(Where), Amount(Amount),
3506f32e7eSjoerg         Fill(Fill) {}
3606f32e7eSjoerg 
format(llvm::raw_ostream & Stream,StringRef Style)37*da58b97aSjoerg   void format(llvm::raw_ostream &Stream, StringRef Style) override {
3806f32e7eSjoerg     auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
3906f32e7eSjoerg     FmtAlign(Adapter, Where, Amount, Fill).format(Stream, Style);
4006f32e7eSjoerg   }
4106f32e7eSjoerg };
4206f32e7eSjoerg 
4306f32e7eSjoerg template <typename T> class PadAdapter final : public FormatAdapter<T> {
4406f32e7eSjoerg   size_t Left;
4506f32e7eSjoerg   size_t Right;
4606f32e7eSjoerg 
4706f32e7eSjoerg public:
PadAdapter(T && Item,size_t Left,size_t Right)4806f32e7eSjoerg   PadAdapter(T &&Item, size_t Left, size_t Right)
4906f32e7eSjoerg       : FormatAdapter<T>(std::forward<T>(Item)), Left(Left), Right(Right) {}
5006f32e7eSjoerg 
format(llvm::raw_ostream & Stream,StringRef Style)51*da58b97aSjoerg   void format(llvm::raw_ostream &Stream, StringRef Style) override {
5206f32e7eSjoerg     auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
5306f32e7eSjoerg     Stream.indent(Left);
5406f32e7eSjoerg     Adapter.format(Stream, Style);
5506f32e7eSjoerg     Stream.indent(Right);
5606f32e7eSjoerg   }
5706f32e7eSjoerg };
5806f32e7eSjoerg 
5906f32e7eSjoerg template <typename T> class RepeatAdapter final : public FormatAdapter<T> {
6006f32e7eSjoerg   size_t Count;
6106f32e7eSjoerg 
6206f32e7eSjoerg public:
RepeatAdapter(T && Item,size_t Count)6306f32e7eSjoerg   RepeatAdapter(T &&Item, size_t Count)
6406f32e7eSjoerg       : FormatAdapter<T>(std::forward<T>(Item)), Count(Count) {}
6506f32e7eSjoerg 
format(llvm::raw_ostream & Stream,StringRef Style)66*da58b97aSjoerg   void format(llvm::raw_ostream &Stream, StringRef Style) override {
6706f32e7eSjoerg     auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
6806f32e7eSjoerg     for (size_t I = 0; I < Count; ++I) {
6906f32e7eSjoerg       Adapter.format(Stream, Style);
7006f32e7eSjoerg     }
7106f32e7eSjoerg   }
7206f32e7eSjoerg };
7306f32e7eSjoerg 
7406f32e7eSjoerg class ErrorAdapter : public FormatAdapter<Error> {
7506f32e7eSjoerg public:
ErrorAdapter(Error && Item)7606f32e7eSjoerg   ErrorAdapter(Error &&Item) : FormatAdapter(std::move(Item)) {}
7706f32e7eSjoerg   ErrorAdapter(ErrorAdapter &&) = default;
~ErrorAdapter()7806f32e7eSjoerg   ~ErrorAdapter() { consumeError(std::move(Item)); }
format(llvm::raw_ostream & Stream,StringRef Style)79*da58b97aSjoerg   void format(llvm::raw_ostream &Stream, StringRef Style) override {
80*da58b97aSjoerg     Stream << Item;
81*da58b97aSjoerg   }
8206f32e7eSjoerg };
8306f32e7eSjoerg }
8406f32e7eSjoerg 
8506f32e7eSjoerg template <typename T>
8606f32e7eSjoerg detail::AlignAdapter<T> fmt_align(T &&Item, AlignStyle Where, size_t Amount,
8706f32e7eSjoerg                                   char Fill = ' ') {
8806f32e7eSjoerg   return detail::AlignAdapter<T>(std::forward<T>(Item), Where, Amount, Fill);
8906f32e7eSjoerg }
9006f32e7eSjoerg 
9106f32e7eSjoerg template <typename T>
fmt_pad(T && Item,size_t Left,size_t Right)9206f32e7eSjoerg detail::PadAdapter<T> fmt_pad(T &&Item, size_t Left, size_t Right) {
9306f32e7eSjoerg   return detail::PadAdapter<T>(std::forward<T>(Item), Left, Right);
9406f32e7eSjoerg }
9506f32e7eSjoerg 
9606f32e7eSjoerg template <typename T>
fmt_repeat(T && Item,size_t Count)9706f32e7eSjoerg detail::RepeatAdapter<T> fmt_repeat(T &&Item, size_t Count) {
9806f32e7eSjoerg   return detail::RepeatAdapter<T>(std::forward<T>(Item), Count);
9906f32e7eSjoerg }
10006f32e7eSjoerg 
10106f32e7eSjoerg // llvm::Error values must be consumed before being destroyed.
10206f32e7eSjoerg // Wrapping an error in fmt_consume explicitly indicates that the formatv_object
10306f32e7eSjoerg // should take ownership and consume it.
fmt_consume(Error && Item)10406f32e7eSjoerg inline detail::ErrorAdapter fmt_consume(Error &&Item) {
10506f32e7eSjoerg   return detail::ErrorAdapter(std::move(Item));
10606f32e7eSjoerg }
10706f32e7eSjoerg }
10806f32e7eSjoerg 
10906f32e7eSjoerg #endif
110