xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Support/FormatCommon.h (revision 1ed2ef42e01771f5d8ca9be61e07dcf0fd47feba)
1 //===- FormatCommon.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_FORMATCOMMON_H
10 #define LLVM_SUPPORT_FORMATCOMMON_H
11 
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/Support/FormatVariadicDetails.h"
14 #include "llvm/Support/raw_ostream.h"
15 
16 namespace llvm {
17 enum class AlignStyle { Left, Center, Right };
18 
19 /// Helper class to format to a \p Width wide field, with alignment \p Where
20 /// within that field.
21 struct FmtAlign {
22   support::detail::format_adapter &Adapter;
23   AlignStyle Where;
24   unsigned Width;
25   char Fill;
26 
27   FmtAlign(support::detail::format_adapter &Adapter, AlignStyle Where,
28            unsigned Width, char Fill = ' ')
29       : Adapter(Adapter), Where(Where), Width(Width), Fill(Fill) {}
30 
31   void format(raw_ostream &S, StringRef Options) {
32     // If we don't need to align, we can format straight into the underlying
33     // stream.  Otherwise we have to go through an intermediate stream first
34     // in order to calculate how long the output is so we can align it.
35     // TODO: Make the format method return the number of bytes written, that
36     // way we can also skip the intermediate stream for left-aligned output.
37     if (Width == 0) {
38       Adapter.format(S, Options);
39       return;
40     }
41     SmallString<64> Item;
42     raw_svector_ostream Stream(Item);
43 
44     Adapter.format(Stream, Options);
45     if (Width <= Item.size()) {
46       S << Item;
47       return;
48     }
49 
50     unsigned PadAmount = Width - static_cast<unsigned>(Item.size());
51     switch (Where) {
52     case AlignStyle::Left:
53       S << Item;
54       fill(S, PadAmount);
55       break;
56     case AlignStyle::Center: {
57       unsigned X = PadAmount / 2;
58       fill(S, X);
59       S << Item;
60       fill(S, PadAmount - X);
61       break;
62     }
63     default:
64       fill(S, PadAmount);
65       S << Item;
66       break;
67     }
68   }
69 
70 private:
71   void fill(llvm::raw_ostream &S, unsigned Count) {
72     for (unsigned I = 0; I < Count; ++I)
73       S << Fill;
74   }
75 };
76 }
77 
78 #endif
79