LLVM API Documentation
00001 //===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the format() function, which can be used with other 00011 // LLVM subsystems to provide printf-style formatting. This gives all the power 00012 // and risk of printf. This can be used like this (with raw_ostreams as an 00013 // example): 00014 // 00015 // OS << "mynumber: " << format("%4.5f", 1234.412) << '\n'; 00016 // 00017 // Or if you prefer: 00018 // 00019 // OS << format("mynumber: %4.5f\n", 1234.412); 00020 // 00021 //===----------------------------------------------------------------------===// 00022 00023 #ifndef LLVM_SUPPORT_FORMAT_H 00024 #define LLVM_SUPPORT_FORMAT_H 00025 00026 #include <cassert> 00027 #include <cstdio> 00028 #ifdef _MSC_VER 00029 // FIXME: This define is wrong: 00030 // - _snprintf does not guarantee that trailing null is always added - if 00031 // there is no space for null, it does not report any error. 00032 // - According to C++ standard, snprintf should be visible in the 'std' 00033 // namespace - this define makes this impossible. 00034 #define snprintf _snprintf 00035 #endif 00036 00037 namespace llvm { 00038 00039 /// This is a helper class used for handling formatted output. It is the 00040 /// abstract base class of a templated derived class. 00041 class format_object_base { 00042 protected: 00043 const char *Fmt; 00044 ~format_object_base() {} // Disallow polymorphic deletion. 00045 virtual void home(); // Out of line virtual method. 00046 00047 /// Call snprintf() for this object, on the given buffer and size. 00048 virtual int snprint(char *Buffer, unsigned BufferSize) const = 0; 00049 00050 public: 00051 format_object_base(const char *fmt) : Fmt(fmt) {} 00052 00053 /// Format the object into the specified buffer. On success, this returns 00054 /// the length of the formatted string. If the buffer is too small, this 00055 /// returns a length to retry with, which will be larger than BufferSize. 00056 unsigned print(char *Buffer, unsigned BufferSize) const { 00057 assert(BufferSize && "Invalid buffer size!"); 00058 00059 // Print the string, leaving room for the terminating null. 00060 int N = snprint(Buffer, BufferSize); 00061 00062 // VC++ and old GlibC return negative on overflow, just double the size. 00063 if (N < 0) 00064 return BufferSize * 2; 00065 00066 // Other implementations yield number of bytes needed, not including the 00067 // final '\0'. 00068 if (unsigned(N) >= BufferSize) 00069 return N + 1; 00070 00071 // Otherwise N is the length of output (not including the final '\0'). 00072 return N; 00073 } 00074 }; 00075 00076 /// These are templated helper classes used by the format function that 00077 /// capture the object to be formated and the format string. When actually 00078 /// printed, this synthesizes the string into a temporary buffer provided and 00079 /// returns whether or not it is big enough. 00080 00081 template <typename T> 00082 class format_object1 final : public format_object_base { 00083 T Val; 00084 public: 00085 format_object1(const char *fmt, const T &val) 00086 : format_object_base(fmt), Val(val) { 00087 } 00088 00089 int snprint(char *Buffer, unsigned BufferSize) const override { 00090 return snprintf(Buffer, BufferSize, Fmt, Val); 00091 } 00092 }; 00093 00094 template <typename T1, typename T2> 00095 class format_object2 final : public format_object_base { 00096 T1 Val1; 00097 T2 Val2; 00098 public: 00099 format_object2(const char *fmt, const T1 &val1, const T2 &val2) 00100 : format_object_base(fmt), Val1(val1), Val2(val2) { 00101 } 00102 00103 int snprint(char *Buffer, unsigned BufferSize) const override { 00104 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2); 00105 } 00106 }; 00107 00108 template <typename T1, typename T2, typename T3> 00109 class format_object3 final : public format_object_base { 00110 T1 Val1; 00111 T2 Val2; 00112 T3 Val3; 00113 public: 00114 format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3) 00115 : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) { 00116 } 00117 00118 int snprint(char *Buffer, unsigned BufferSize) const override { 00119 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3); 00120 } 00121 }; 00122 00123 template <typename T1, typename T2, typename T3, typename T4> 00124 class format_object4 final : public format_object_base { 00125 T1 Val1; 00126 T2 Val2; 00127 T3 Val3; 00128 T4 Val4; 00129 public: 00130 format_object4(const char *fmt, const T1 &val1, const T2 &val2, 00131 const T3 &val3, const T4 &val4) 00132 : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) { 00133 } 00134 00135 int snprint(char *Buffer, unsigned BufferSize) const override { 00136 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4); 00137 } 00138 }; 00139 00140 template <typename T1, typename T2, typename T3, typename T4, typename T5> 00141 class format_object5 final : public format_object_base { 00142 T1 Val1; 00143 T2 Val2; 00144 T3 Val3; 00145 T4 Val4; 00146 T5 Val5; 00147 public: 00148 format_object5(const char *fmt, const T1 &val1, const T2 &val2, 00149 const T3 &val3, const T4 &val4, const T5 &val5) 00150 : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4), 00151 Val5(val5) { 00152 } 00153 00154 int snprint(char *Buffer, unsigned BufferSize) const override { 00155 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5); 00156 } 00157 }; 00158 00159 template <typename T1, typename T2, typename T3, typename T4, typename T5, 00160 typename T6> 00161 class format_object6 final : public format_object_base { 00162 T1 Val1; 00163 T2 Val2; 00164 T3 Val3; 00165 T4 Val4; 00166 T5 Val5; 00167 T6 Val6; 00168 public: 00169 format_object6(const char *Fmt, const T1 &Val1, const T2 &Val2, 00170 const T3 &Val3, const T4 &Val4, const T5 &Val5, const T6 &Val6) 00171 : format_object_base(Fmt), Val1(Val1), Val2(Val2), Val3(Val3), Val4(Val4), 00172 Val5(Val5), Val6(Val6) { } 00173 00174 int snprint(char *Buffer, unsigned BufferSize) const override { 00175 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5, Val6); 00176 } 00177 }; 00178 00179 /// These are helper functions used to produce formatted output. They use 00180 /// template type deduction to construct the appropriate instance of the 00181 /// format_object class to simplify their construction. 00182 /// 00183 /// This is typically used like: 00184 /// \code 00185 /// OS << format("%0.4f", myfloat) << '\n'; 00186 /// \endcode 00187 00188 template <typename T> 00189 inline format_object1<T> format(const char *Fmt, const T &Val) { 00190 return format_object1<T>(Fmt, Val); 00191 } 00192 00193 template <typename T1, typename T2> 00194 inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1, 00195 const T2 &Val2) { 00196 return format_object2<T1, T2>(Fmt, Val1, Val2); 00197 } 00198 00199 template <typename T1, typename T2, typename T3> 00200 inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1, 00201 const T2 &Val2, const T3 &Val3) { 00202 return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3); 00203 } 00204 00205 template <typename T1, typename T2, typename T3, typename T4> 00206 inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1, 00207 const T2 &Val2, const T3 &Val3, 00208 const T4 &Val4) { 00209 return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4); 00210 } 00211 00212 template <typename T1, typename T2, typename T3, typename T4, typename T5> 00213 inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1, 00214 const T2 &Val2, const T3 &Val3, 00215 const T4 &Val4, const T5 &Val5) { 00216 return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5); 00217 } 00218 00219 template <typename T1, typename T2, typename T3, typename T4, typename T5, 00220 typename T6> 00221 inline format_object6<T1, T2, T3, T4, T5, T6> 00222 format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3, 00223 const T4 &Val4, const T5 &Val5, const T6 &Val6) { 00224 return format_object6<T1, T2, T3, T4, T5, T6>(Fmt, Val1, Val2, Val3, Val4, 00225 Val5, Val6); 00226 } 00227 00228 } // end namespace llvm 00229 00230 #endif