HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
std.h
Go to the documentation of this file.
1 // Formatting library for C++ - formatters for standard library types
2 //
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
5 //
6 // For the license information refer to format.h.
7 
8 #ifndef FMT_STD_H_
9 #define FMT_STD_H_
10 
11 #include <cstdlib>
12 #include <exception>
13 #include <memory>
14 #include <thread>
15 #include <type_traits>
16 #include <typeinfo>
17 #include <utility>
18 
19 #include "ostream.h"
20 
21 #if FMT_HAS_INCLUDE(<version>)
22 # include <version>
23 #endif
24 // Checking FMT_CPLUSPLUS for warning suppression in MSVC.
25 #if FMT_CPLUSPLUS >= 201703L
26 # if FMT_HAS_INCLUDE(<filesystem>)
27 # include <filesystem>
28 # endif
29 # if FMT_HAS_INCLUDE(<variant>)
30 # include <variant>
31 # endif
32 # if FMT_HAS_INCLUDE(<optional>)
33 # include <optional>
34 # endif
35 #endif
36 
37 // GCC 4 does not support FMT_HAS_INCLUDE.
38 #if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
39 # include <cxxabi.h>
40 // Android NDK with gabi++ library on some architectures does not implement
41 // abi::__cxa_demangle().
42 # ifndef __GABIXX_CXXABI_H__
43 # define FMT_HAS_ABI_CXA_DEMANGLE
44 # endif
45 #endif
46 
47 #ifdef __cpp_lib_filesystem
49 
50 namespace detail {
51 
52 template <typename Char>
53 void write_escaped_path(basic_memory_buffer<Char>& quoted,
54  const std::filesystem::path& p) {
55  write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
56 }
57 # ifdef _WIN32
58 template <>
59 inline void write_escaped_path<char>(memory_buffer& quoted,
60  const std::filesystem::path& p) {
62  write_escaped_string<wchar_t>(std::back_inserter(buf), p.native());
63  // Convert UTF-16 to UTF-8.
64  if (!unicode_to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()}))
65  FMT_THROW(std::runtime_error("invalid utf16"));
66 }
67 # endif
68 template <>
69 inline void write_escaped_path<std::filesystem::path::value_type>(
71  const std::filesystem::path& p) {
72  write_escaped_string<std::filesystem::path::value_type>(
73  std::back_inserter(quoted), p.native());
74 }
75 
76 } // namespace detail
77 
79 template <typename Char>
80 struct formatter<std::filesystem::path, Char>
81  : formatter<basic_string_view<Char>> {
82  template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
83  auto out = formatter<basic_string_view<Char>>::parse(ctx);
84  this->set_debug_format(false);
85  return out;
86  }
87  template <typename FormatContext>
88  auto format(const std::filesystem::path& p, FormatContext& ctx) const ->
89  typename FormatContext::iterator {
90  auto quoted = basic_memory_buffer<Char>();
91  detail::write_escaped_path(quoted, p);
93  basic_string_view<Char>(quoted.data(), quoted.size()), ctx);
94  }
95 };
97 #endif
98 
101 template <typename Char>
102 struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
104 
105 #ifdef __cpp_lib_optional
108 template <typename T, typename Char>
109 struct formatter<std::optional<T>, Char,
110  std::enable_if_t<is_formattable<T, Char>::value>> {
111  private:
112  formatter<T, Char> underlying_;
113  static constexpr basic_string_view<Char> optional =
114  detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l',
115  '('>{};
116  static constexpr basic_string_view<Char> none =
118 
119  template <class U>
120  FMT_CONSTEXPR static auto maybe_set_debug_format(U& u, bool set)
121  -> decltype(u.set_debug_format(set)) {
122  u.set_debug_format(set);
123  }
124 
125  template <class U>
126  FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {}
127 
128  public:
129  template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
130  maybe_set_debug_format(underlying_, true);
131  return underlying_.parse(ctx);
132  }
133 
134  template <typename FormatContext>
135  auto format(std::optional<T> const& opt, FormatContext& ctx) const
136  -> decltype(ctx.out()) {
137  if (!opt) return detail::write<Char>(ctx.out(), none);
138 
139  auto out = ctx.out();
140  out = detail::write<Char>(out, optional);
141  ctx.advance_to(out);
142  out = underlying_.format(*opt, ctx);
143  return detail::write(out, ')');
144  }
145 };
147 #endif // __cpp_lib_optional
148 
149 #ifdef __cpp_lib_variant
152 template <typename Char> struct formatter<std::monostate, Char> {
153  template <typename ParseContext>
154  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
155  return ctx.begin();
156  }
157 
158  template <typename FormatContext>
159  auto format(const std::monostate&, FormatContext& ctx) const
160  -> decltype(ctx.out()) {
161  auto out = ctx.out();
162  out = detail::write<Char>(out, "monostate");
163  return out;
164  }
165 };
166 
167 namespace detail {
168 
169 template <typename T>
170 using variant_index_sequence =
172 
173 template <typename> struct is_variant_like_ : std::false_type {};
174 template <typename... Types>
175 struct is_variant_like_<std::variant<Types...>> : std::true_type {};
176 
177 // formattable element check.
178 template <typename T, typename C> class is_variant_formattable_ {
179  template <std::size_t... Is>
180  static std::conjunction<
182  check(std::index_sequence<Is...>);
183 
184  public:
185  static constexpr const bool value =
186  decltype(check(variant_index_sequence<T>{}))::value;
187 };
188 
189 template <typename Char, typename OutputIt, typename T>
190 auto write_variant_alternative(OutputIt out, const T& v) -> OutputIt {
191  if constexpr (is_string<T>::value)
192  return write_escaped_string<Char>(out, detail::to_string_view(v));
193  else if constexpr (std::is_same_v<T, Char>)
194  return write_escaped_char(out, v);
195  else
196  return write<Char>(out, v);
197 }
198 
199 } // namespace detail
200 template <typename T> struct is_variant_like {
201  static constexpr const bool value = detail::is_variant_like_<T>::value;
202 };
203 
204 template <typename T, typename C> struct is_variant_formattable {
205  static constexpr const bool value =
207 };
208 
210 template <typename Variant, typename Char>
211 struct formatter<
212  Variant, Char,
213  std::enable_if_t<std::conjunction_v<
214  is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
215  template <typename ParseContext>
216  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
217  return ctx.begin();
218  }
219 
220  template <typename FormatContext>
221  auto format(const Variant& value, FormatContext& ctx) const
222  -> decltype(ctx.out()) {
223  auto out = ctx.out();
224 
225  out = detail::write<Char>(out, "variant(");
226  try {
227  std::visit(
228  [&](const auto& v) {
229  out = detail::write_variant_alternative<Char>(out, v);
230  },
231  value);
232  } catch (const std::bad_variant_access&) {
233  detail::write<Char>(out, "valueless by exception");
234  }
235  *out++ = ')';
236  return out;
237  }
238 };
240 #endif // __cpp_lib_variant
241 
244 template <typename Char> struct formatter<std::error_code, Char> {
245  template <typename ParseContext>
246  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
247  return ctx.begin();
248  }
249 
250  template <typename FormatContext>
251  FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const
252  -> decltype(ctx.out()) {
253  auto out = ctx.out();
254  out = detail::write_bytes(out, ec.category().name(), format_specs<Char>());
255  out = detail::write<Char>(out, Char(':'));
256  out = detail::write<Char>(out, ec.value());
257  return out;
258  }
259 };
260 
262 template <typename T, typename Char>
263 struct formatter<
264  T, Char,
265  typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
266  private:
267  bool with_typename_ = false;
268 
269  public:
271  -> decltype(ctx.begin()) {
272  auto it = ctx.begin();
273  auto end = ctx.end();
274  if (it == end || *it == '}') return it;
275  if (*it == 't') {
276  ++it;
277  with_typename_ = true;
278  }
279  return it;
280  }
281 
282  template <typename OutputIt>
283  auto format(const std::exception& ex,
284  basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
285  format_specs<Char> spec;
286  auto out = ctx.out();
287  if (!with_typename_)
288  return detail::write_bytes(out, string_view(ex.what()), spec);
289 
290  const std::type_info& ti = typeid(ex);
291 #ifdef FMT_HAS_ABI_CXA_DEMANGLE
292  int status = 0;
293  std::size_t size = 0;
294  std::unique_ptr<char, decltype(&std::free)> demangled_name_ptr(
295  abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
296 
297  string_view demangled_name_view;
298  if (demangled_name_ptr) {
299  demangled_name_view = demangled_name_ptr.get();
300 
301  // Normalization of stdlib inline namespace names.
302  // libc++ inline namespaces.
303  // std::__1::* -> std::*
304  // std::__1::__fs::* -> std::*
305  // libstdc++ inline namespaces.
306  // std::__cxx11::* -> std::*
307  // std::filesystem::__cxx11::* -> std::filesystem::*
308  if (demangled_name_view.starts_with("std::")) {
309  char* begin = demangled_name_ptr.get();
310  char* to = begin + 5; // std::
311  for (char *from = to, *end = begin + demangled_name_view.size();
312  from < end;) {
313  // This is safe, because demangled_name is NUL-terminated.
314  if (from[0] == '_' && from[1] == '_') {
315  char* next = from + 1;
316  while (next < end && *next != ':') next++;
317  if (next[0] == ':' && next[1] == ':') {
318  from = next + 2;
319  continue;
320  }
321  }
322  *to++ = *from++;
323  }
324  demangled_name_view = {begin, detail::to_unsigned(to - begin)};
325  }
326  } else {
327  demangled_name_view = string_view(ti.name());
328  }
329  out = detail::write_bytes(out, demangled_name_view, spec);
330 #elif FMT_MSC_VERSION
331  string_view demangled_name_view(ti.name());
332  if (demangled_name_view.starts_with("class "))
333  demangled_name_view.remove_prefix(6);
334  else if (demangled_name_view.starts_with("struct "))
335  demangled_name_view.remove_prefix(7);
336  out = detail::write_bytes(out, demangled_name_view, spec);
337 #else
338  out = detail::write_bytes(out, string_view(ti.name()), spec);
339 #endif
340  out = detail::write<Char>(out, Char(':'));
341  out = detail::write<Char>(out, Char(' '));
342  out = detail::write_bytes(out, string_view(ex.what()), spec);
343 
344  return out;
345  }
346 };
348 
349 #endif // FMT_STD_H_
typename std::enable_if< B, T >::type enable_if_t
Define Imath::enable_if_t to be std for C++14, equivalent for C++11.
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
const GLdouble * v
Definition: glcorearb.h:837
GLsizei const GLfloat * value
Definition: glcorearb.h:824
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
auto write_escaped_char(OutputIt out, Char v) -> OutputIt
Definition: format.h:2067
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: std.h:246
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
Definition: core.h:374
bool_constant<!std::is_base_of< detail::unformattable, decltype(detail::arg_mapper< buffer_context< Char >>().map(std::declval< T >()))>::value > is_formattable
Definition: core.h:1781
auto format(const std::exception &ex, basic_format_context< OutputIt, Char > &ctx) const -> OutputIt
Definition: std.h:283
#define FMT_END_NAMESPACE
Definition: core.h:179
#define FMT_THROW(x)
Definition: format.h:120
basic_string_view< char > string_view
Definition: core.h:501
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition: core.h:517
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
auto write_escaped_string(OutputIt out, basic_string_view< Char > str) -> OutputIt
Definition: format.h:2051
constexpr auto set(type rhs) -> int
Definition: core.h:610
GLuint GLuint end
Definition: glcorearb.h:475
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
FMT_CONSTEXPR void remove_prefix(size_t n) noexcept
Definition: core.h:452
GLuint id
Definition: glcorearb.h:655
constexpr auto size() const noexcept-> size_t
Definition: core.h:443
GLsizeiptr size
Definition: glcorearb.h:664
#define FMT_CONSTEXPR
Definition: core.h:104
FMT_CONSTEXPR_CHAR_TRAITS bool starts_with(basic_string_view< Char > sv) const noexcept
Definition: core.h:457
FMT_CONSTEXPR auto format(const std::error_code &ec, FormatContext &ctx) const -> decltype(ctx.out())
Definition: std.h:251
if(num_boxed_items<=0)
Definition: UT_RTreeImpl.h:697
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
Definition: chrono.h:419
#define FMT_BEGIN_NAMESPACE
Definition: core.h:176
FMT_CONSTEXPR auto parse(basic_format_parse_context< Char > &ctx) -> decltype(ctx.begin())
Definition: std.h:270
FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, const format_specs< Char > &specs) -> OutputIt
Definition: format.h:1900
#define FMT_MODULE_EXPORT
Definition: core.h:185
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:566