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