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 struct FmtAlign { 20 support::detail::format_adapter &Adapter; 21 AlignStyle Where; 22 size_t Amount; 23 char Fill; 24 25 FmtAlign(support::detail::format_adapter &Adapter, AlignStyle Where, 26 size_t Amount, char Fill = ' ') AdapterFmtAlign27 : Adapter(Adapter), Where(Where), Amount(Amount), Fill(Fill) {} 28 formatFmtAlign29 void format(raw_ostream &S, StringRef Options) { 30 // If we don't need to align, we can format straight into the underlying 31 // stream. Otherwise we have to go through an intermediate stream first 32 // in order to calculate how long the output is so we can align it. 33 // TODO: Make the format method return the number of bytes written, that 34 // way we can also skip the intermediate stream for left-aligned output. 35 if (Amount == 0) { 36 Adapter.format(S, Options); 37 return; 38 } 39 SmallString<64> Item; 40 raw_svector_ostream Stream(Item); 41 42 Adapter.format(Stream, Options); 43 if (Amount <= Item.size()) { 44 S << Item; 45 return; 46 } 47 48 size_t PadAmount = Amount - Item.size(); 49 switch (Where) { 50 case AlignStyle::Left: 51 S << Item; 52 fill(S, PadAmount); 53 break; 54 case AlignStyle::Center: { 55 size_t X = PadAmount / 2; 56 fill(S, X); 57 S << Item; 58 fill(S, PadAmount - X); 59 break; 60 } 61 default: 62 fill(S, PadAmount); 63 S << Item; 64 break; 65 } 66 } 67 68 private: fillFmtAlign69 void fill(llvm::raw_ostream &S, size_t Count) { 70 for (size_t I = 0; I < Count; ++I) 71 S << Fill; 72 } 73 }; 74 } 75 76 #endif 77