Format.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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. #ifndef LLVM_SUPPORT_FORMAT_H
  23. #define LLVM_SUPPORT_FORMAT_H
  24. #include "llvm/ADT/STLExtras.h"
  25. #include "llvm/ADT/StringRef.h"
  26. #include "llvm/Support/DataTypes.h"
  27. #include <cassert>
  28. #include <cstdio>
  29. #include <tuple>
  30. namespace llvm {
  31. /// This is a helper class used for handling formatted output. It is the
  32. /// abstract base class of a templated derived class.
  33. class format_object_base {
  34. protected:
  35. const char *Fmt;
  36. ~format_object_base() = default; // Disallow polymorphic deletion.
  37. format_object_base(const format_object_base &) = default;
  38. virtual void home(); // Out of line virtual method.
  39. /// Call snprintf() for this object, on the given buffer and size.
  40. virtual int snprint(_Out_ char *Buffer, unsigned BufferSize) const = 0; // HLSL Change - SAL
  41. public:
  42. format_object_base(const char *fmt) : Fmt(fmt) {}
  43. /// Format the object into the specified buffer. On success, this returns
  44. /// the length of the formatted string. If the buffer is too small, this
  45. /// returns a length to retry with, which will be larger than BufferSize.
  46. unsigned print(_Out_ char *Buffer, unsigned BufferSize) const { // HLSL Change - SAL
  47. assert(BufferSize && "Invalid buffer size!");
  48. // Print the string, leaving room for the terminating null.
  49. int N = snprint(Buffer, BufferSize);
  50. // VC++ and old GlibC return negative on overflow, just double the size.
  51. if (N < 0)
  52. return BufferSize * 2;
  53. // Other implementations yield number of bytes needed, not including the
  54. // final '\0'.
  55. if (unsigned(N) >= BufferSize)
  56. return N + 1;
  57. // Otherwise N is the length of output (not including the final '\0').
  58. return N;
  59. }
  60. };
  61. /// These are templated helper classes used by the format function that
  62. /// capture the object to be formated and the format string. When actually
  63. /// printed, this synthesizes the string into a temporary buffer provided and
  64. /// returns whether or not it is big enough.
  65. template <typename... Ts>
  66. class format_object final : public format_object_base {
  67. std::tuple<Ts...> Vals;
  68. template <std::size_t... Is>
  69. int snprint_tuple(char *Buffer, unsigned BufferSize,
  70. index_sequence<Is...>) const {
  71. #ifdef _MSC_VER
  72. // Use _TRUNCATE as the buffer size; truncation will still return -1 as
  73. // a result, thereby triggering the 'double on VC++' behavior in
  74. // caller, for example llvm::format_object_base::print(char * Buffer, unsigned int BufferSize)
  75. return _snprintf_s(Buffer, BufferSize, _TRUNCATE, Fmt, std::get<Is>(Vals)...);
  76. #else
  77. return snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
  78. #endif
  79. }
  80. public:
  81. format_object(const char *fmt, const Ts &... vals)
  82. : format_object_base(fmt), Vals(vals...) {}
  83. int snprint(char *Buffer, unsigned BufferSize) const override {
  84. return snprint_tuple(Buffer, BufferSize, index_sequence_for<Ts...>());
  85. }
  86. };
  87. /// These are helper functions used to produce formatted output. They use
  88. /// template type deduction to construct the appropriate instance of the
  89. /// format_object class to simplify their construction.
  90. ///
  91. /// This is typically used like:
  92. /// \code
  93. /// OS << format("%0.4f", myfloat) << '\n';
  94. /// \endcode
  95. template <typename... Ts>
  96. inline format_object<Ts...> format(const char *Fmt, const Ts &... Vals) {
  97. return format_object<Ts...>(Fmt, Vals...);
  98. }
  99. /// This is a helper class used for left_justify() and right_justify().
  100. class FormattedString {
  101. StringRef Str;
  102. unsigned Width;
  103. bool RightJustify;
  104. friend class raw_ostream;
  105. public:
  106. FormattedString(StringRef S, unsigned W, bool R)
  107. : Str(S), Width(W), RightJustify(R) { }
  108. };
  109. /// left_justify - append spaces after string so total output is
  110. /// \p Width characters. If \p Str is larger that \p Width, full string
  111. /// is written with no padding.
  112. inline FormattedString left_justify(StringRef Str, unsigned Width) {
  113. return FormattedString(Str, Width, false);
  114. }
  115. /// right_justify - add spaces before string so total output is
  116. /// \p Width characters. If \p Str is larger that \p Width, full string
  117. /// is written with no padding.
  118. inline FormattedString right_justify(StringRef Str, unsigned Width) {
  119. return FormattedString(Str, Width, true);
  120. }
  121. /// This is a helper class used for format_hex() and format_decimal().
  122. class FormattedNumber {
  123. uint64_t HexValue;
  124. int64_t DecValue;
  125. unsigned Width;
  126. bool Hex;
  127. bool Upper;
  128. bool HexPrefix;
  129. friend class raw_ostream;
  130. public:
  131. FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U,
  132. bool Prefix)
  133. : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U),
  134. HexPrefix(Prefix) {}
  135. };
  136. /// format_hex - Output \p N as a fixed width hexadecimal. If number will not
  137. /// fit in width, full number is still printed. Examples:
  138. /// OS << format_hex(255, 4) => 0xff
  139. /// OS << format_hex(255, 4, true) => 0xFF
  140. /// OS << format_hex(255, 6) => 0x00ff
  141. /// OS << format_hex(255, 2) => 0xff
  142. inline FormattedNumber format_hex(uint64_t N, unsigned Width,
  143. bool Upper = false) {
  144. assert(Width <= 18 && "hex width must be <= 18");
  145. return FormattedNumber(N, 0, Width, true, Upper, true);
  146. }
  147. /// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not
  148. /// prepend '0x' to the outputted string. If number will not fit in width,
  149. /// full number is still printed. Examples:
  150. /// OS << format_hex_no_prefix(255, 4) => ff
  151. /// OS << format_hex_no_prefix(255, 4, true) => FF
  152. /// OS << format_hex_no_prefix(255, 6) => 00ff
  153. /// OS << format_hex_no_prefix(255, 2) => ff
  154. inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width,
  155. bool Upper = false) {
  156. assert(Width <= 18 && "hex width must be <= 18");
  157. return FormattedNumber(N, 0, Width, true, Upper, false);
  158. }
  159. /// format_decimal - Output \p N as a right justified, fixed-width decimal. If
  160. /// number will not fit in width, full number is still printed. Examples:
  161. /// OS << format_decimal(0, 5) => " 0"
  162. /// OS << format_decimal(255, 5) => " 255"
  163. /// OS << format_decimal(-1, 3) => " -1"
  164. /// OS << format_decimal(12345, 3) => "12345"
  165. inline FormattedNumber format_decimal(int64_t N, unsigned Width) {
  166. return FormattedNumber(0, N, Width, false, false, false);
  167. }
  168. } // end namespace llvm
  169. #endif