Format.h 7.1 KB

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