1//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the format() function, which can be used with other 11// LLVM subsystems to provide printf-style formatting. This gives all the power 12// and risk of printf. This can be used like this (with raw_ostreams as an 13// example): 14// 15// OS << "mynumber: " << format("%4.5f", 1234.412) << '\n'; 16// 17// Or if you prefer: 18// 19// OS << format("mynumber: %4.5f\n", 1234.412); 20// 21//===----------------------------------------------------------------------===// 22 23#ifndef LLVM_SUPPORT_FORMAT_H 24#define LLVM_SUPPORT_FORMAT_H 25 26#include <cassert> 27#include <cstdio> 28#ifdef _MSC_VER 29// FIXME: This define is wrong: 30// - _snprintf does not guarantee that trailing null is always added - if 31// there is no space for null, it does not report any error. 32// - According to C++ standard, snprintf should be visible in the 'std' 33// namespace - this define makes this impossible. 34#define snprintf _snprintf 35#endif 36 37namespace llvm { 38 39/// format_object_base - This is a helper class used for handling formatted 40/// output. It is the abstract base class of a templated derived class. 41class format_object_base { 42protected: 43 const char *Fmt; 44 virtual void home(); // Out of line virtual method. 45 46 /// snprint - Call snprintf() for this object, on the given buffer and size. 47 virtual int snprint(char *Buffer, unsigned BufferSize) const = 0; 48 49public: 50 format_object_base(const char *fmt) : Fmt(fmt) {} 51 virtual ~format_object_base() {} 52 53 /// print - Format the object into the specified buffer. On success, this 54 /// returns the length of the formatted string. If the buffer is too small, 55 /// this returns a length to retry with, which will be larger than BufferSize. 56 unsigned print(char *Buffer, unsigned BufferSize) const { 57 assert(BufferSize && "Invalid buffer size!"); 58 59 // Print the string, leaving room for the terminating null. 60 int N = snprint(Buffer, BufferSize); 61 62 // VC++ and old GlibC return negative on overflow, just double the size. 63 if (N < 0) 64 return BufferSize*2; 65 66 // Other impls yield number of bytes needed, not including the final '\0'. 67 if (unsigned(N) >= BufferSize) 68 return N+1; 69 70 // Otherwise N is the length of output (not including the final '\0'). 71 return N; 72 } 73}; 74 75/// format_object1 - This is a templated helper class used by the format 76/// function that captures the object to be formated and the format string. When 77/// actually printed, this synthesizes the string into a temporary buffer 78/// provided and returns whether or not it is big enough. 79template <typename T> 80class format_object1 : public format_object_base { 81 T Val; 82public: 83 format_object1(const char *fmt, const T &val) 84 : format_object_base(fmt), Val(val) { 85 } 86 87 virtual int snprint(char *Buffer, unsigned BufferSize) const { 88 return snprintf(Buffer, BufferSize, Fmt, Val); 89 } 90}; 91 92/// format_object2 - This is a templated helper class used by the format 93/// function that captures the object to be formated and the format string. When 94/// actually printed, this synthesizes the string into a temporary buffer 95/// provided and returns whether or not it is big enough. 96template <typename T1, typename T2> 97class format_object2 : public format_object_base { 98 T1 Val1; 99 T2 Val2; 100public: 101 format_object2(const char *fmt, const T1 &val1, const T2 &val2) 102 : format_object_base(fmt), Val1(val1), Val2(val2) { 103 } 104 105 virtual int snprint(char *Buffer, unsigned BufferSize) const { 106 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2); 107 } 108}; 109 110/// format_object3 - This is a templated helper class used by the format 111/// function that captures the object to be formated and the format string. When 112/// actually printed, this synthesizes the string into a temporary buffer 113/// provided and returns whether or not it is big enough. 114template <typename T1, typename T2, typename T3> 115class format_object3 : public format_object_base { 116 T1 Val1; 117 T2 Val2; 118 T3 Val3; 119public: 120 format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3) 121 : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) { 122 } 123 124 virtual int snprint(char *Buffer, unsigned BufferSize) const { 125 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3); 126 } 127}; 128 129/// format_object4 - This is a templated helper class used by the format 130/// function that captures the object to be formated and the format string. When 131/// actually printed, this synthesizes the string into a temporary buffer 132/// provided and returns whether or not it is big enough. 133template <typename T1, typename T2, typename T3, typename T4> 134class format_object4 : public format_object_base { 135 T1 Val1; 136 T2 Val2; 137 T3 Val3; 138 T4 Val4; 139public: 140 format_object4(const char *fmt, const T1 &val1, const T2 &val2, 141 const T3 &val3, const T4 &val4) 142 : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) { 143 } 144 145 virtual int snprint(char *Buffer, unsigned BufferSize) const { 146 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4); 147 } 148}; 149 150/// format_object5 - This is a templated helper class used by the format 151/// function that captures the object to be formated and the format string. When 152/// actually printed, this synthesizes the string into a temporary buffer 153/// provided and returns whether or not it is big enough. 154template <typename T1, typename T2, typename T3, typename T4, typename T5> 155class format_object5 : public format_object_base { 156 T1 Val1; 157 T2 Val2; 158 T3 Val3; 159 T4 Val4; 160 T5 Val5; 161public: 162 format_object5(const char *fmt, const T1 &val1, const T2 &val2, 163 const T3 &val3, const T4 &val4, const T5 &val5) 164 : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4), 165 Val5(val5) { 166 } 167 168 virtual int snprint(char *Buffer, unsigned BufferSize) const { 169 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5); 170 } 171}; 172 173/// format - This is a helper function that is used to produce formatted output. 174/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; 175template <typename T> 176inline format_object1<T> format(const char *Fmt, const T &Val) { 177 return format_object1<T>(Fmt, Val); 178} 179 180/// format - This is a helper function that is used to produce formatted output. 181/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; 182template <typename T1, typename T2> 183inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1, 184 const T2 &Val2) { 185 return format_object2<T1, T2>(Fmt, Val1, Val2); 186} 187 188/// format - This is a helper function that is used to produce formatted output. 189/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; 190template <typename T1, typename T2, typename T3> 191 inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1, 192 const T2 &Val2, const T3 &Val3) { 193 return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3); 194} 195 196/// format - This is a helper function that is used to produce formatted output. 197/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; 198template <typename T1, typename T2, typename T3, typename T4> 199inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1, 200 const T2 &Val2, const T3 &Val3, 201 const T4 &Val4) { 202 return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4); 203} 204 205/// format - This is a helper function that is used to produce formatted output. 206/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; 207template <typename T1, typename T2, typename T3, typename T4, typename T5> 208inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1, 209 const T2 &Val2, const T3 &Val3, 210 const T4 &Val4, const T5 &Val5) { 211 return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5); 212} 213 214} // end namespace llvm 215 216#endif 217