LLVM API Documentation

Format.h
Go to the documentation of this file.
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