Scippy

SoPlex

Sequential object-oriented simPlex

printf.h
Go to the documentation of this file.
1 // Formatting library for C++ - legacy printf implementation
2 //
3 // Copyright (c) 2012 - 2016, Victor Zverovich
4 // All rights reserved.
5 //
6 // For the license information refer to format.h.
7 
8 #ifndef FMT_PRINTF_H_
9 #define FMT_PRINTF_H_
10 
11 #include <algorithm> // std::max
12 #include <limits> // std::numeric_limits
13 
14 #include "ostream.h"
15 
17 namespace internal {
18 
19 // Checks if a value fits in int - used to avoid warnings about comparing
20 // signed and unsigned integers.
21 template <bool IsSigned> struct int_checker {
22  template <typename T> static bool fits_in_int(T value) {
23  unsigned max = max_value<int>();
24  return value <= max;
25  }
26  static bool fits_in_int(bool) { return true; }
27 };
28 
29 template <> struct int_checker<true> {
30  template <typename T> static bool fits_in_int(T value) {
31  return value >= std::numeric_limits<int>::min() &&
33  }
34  static bool fits_in_int(int) { return true; }
35 };
36 
38  public:
39  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
40  int operator()(T value) {
41  if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
42  FMT_THROW(format_error("number is too big"));
43  return (std::max)(static_cast<int>(value), 0);
44  }
45 
46  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
47  int operator()(T) {
48  FMT_THROW(format_error("precision is not integer"));
49  return 0;
50  }
51 };
52 
53 // An argument visitor that returns true iff arg is a zero integer.
54 class is_zero_int {
55  public:
56  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
57  bool operator()(T value) {
58  return value == 0;
59  }
60 
61  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
62  bool operator()(T) {
63  return false;
64  }
65 };
66 
67 template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};
68 
69 template <> struct make_unsigned_or_bool<bool> { using type = bool; };
70 
71 template <typename T, typename Context> class arg_converter {
72  private:
73  using char_type = typename Context::char_type;
74 
77 
78  public:
80  : arg_(arg), type_(type) {}
81 
82  void operator()(bool value) {
83  if (type_ != 's') operator()<bool>(value);
84  }
85 
86  template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
87  void operator()(U value) {
88  bool is_signed = type_ == 'd' || type_ == 'i';
89  using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
90  if (const_check(sizeof(target_type) <= sizeof(int))) {
91  // Extra casts are used to silence warnings.
92  if (is_signed) {
93  arg_ = internal::make_arg<Context>(
94  static_cast<int>(static_cast<target_type>(value)));
95  } else {
96  using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
97  arg_ = internal::make_arg<Context>(
98  static_cast<unsigned>(static_cast<unsigned_type>(value)));
99  }
100  } else {
101  if (is_signed) {
102  // glibc's printf doesn't sign extend arguments of smaller types:
103  // std::printf("%lld", -42); // prints "4294967254"
104  // but we don't have to do the same because it's a UB.
105  arg_ = internal::make_arg<Context>(static_cast<long long>(value));
106  } else {
107  arg_ = internal::make_arg<Context>(
108  static_cast<typename make_unsigned_or_bool<U>::type>(value));
109  }
110  }
111  }
112 
113  template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>
114  void operator()(U) {} // No conversion needed for non-integral types.
115 };
116 
117 // Converts an integer argument to T for printf, if T is an integral type.
118 // If T is void, the argument is converted to corresponding signed or unsigned
119 // type depending on the type specifier: 'd' and 'i' - signed, other -
120 // unsigned).
121 template <typename T, typename Context, typename Char>
124 }
125 
126 // Converts an integer argument to char for printf.
127 template <typename Context> class char_converter {
128  private:
130 
131  public:
132  explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}
133 
134  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
135  void operator()(T value) {
136  arg_ = internal::make_arg<Context>(
137  static_cast<typename Context::char_type>(value));
138  }
139 
140  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
141  void operator()(T) {} // No conversion needed for non-integral types.
142 };
143 
144 // Checks if an argument is a valid printf width specifier and sets
145 // left alignment if it is negative.
146 template <typename Char> class printf_width_handler {
147  private:
149 
151 
152  public:
153  explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
154 
155  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
156  unsigned operator()(T value) {
157  auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
159  specs_.align = align::left;
160  width = 0 - width;
161  }
162  unsigned int_max = max_value<int>();
163  if (width > int_max) FMT_THROW(format_error("number is too big"));
164  return static_cast<unsigned>(width);
165  }
166 
167  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
168  unsigned operator()(T) {
169  FMT_THROW(format_error("width is not integer"));
170  return 0;
171  }
172 };
173 
174 template <typename Char, typename Context>
177  Context(std::back_inserter(buf), format, args).format();
178 }
179 
180 template <typename OutputIt, typename Char, typename Context>
184  return Context(it, format, args).format();
185 }
186 } // namespace internal
187 
188 using internal::printf; // For printing into memory_buffer.
189 
190 template <typename Range> class printf_arg_formatter;
191 
192 template <typename OutputIt, typename Char> class basic_printf_context;
193 
194 /**
195  \rst
196  The ``printf`` argument formatter.
197  \endrst
198  */
199 template <typename Range>
201  public:
202  using iterator = typename Range::iterator;
203 
204  private:
205  using char_type = typename Range::value_type;
208 
210 
211  void write_null_pointer(char) {
212  this->specs()->type = 0;
213  this->write("(nil)");
214  }
215 
216  void write_null_pointer(wchar_t) {
217  this->specs()->type = 0;
218  this->write(L"(nil)");
219  }
220 
221  public:
223 
224  /**
225  \rst
226  Constructs an argument formatter object.
227  *buffer* is a reference to the output buffer and *specs* contains format
228  specifier information for standard argument types.
229  \endrst
230  */
232  : base(Range(iter), &specs, internal::locale_ref()), context_(ctx) {}
233 
234  template <typename T, FMT_ENABLE_IF(fmt::internal::is_integral<T>::value)>
235  iterator operator()(T value) {
236  // MSVC2013 fails to compile separate overloads for bool and char_type so
237  // use std::is_same instead.
238  if (std::is_same<T, bool>::value) {
239  format_specs& fmt_specs = *this->specs();
240  if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0);
241  fmt_specs.type = 0;
242  this->write(value != 0);
243  } else if (std::is_same<T, char_type>::value) {
244  format_specs& fmt_specs = *this->specs();
245  if (fmt_specs.type && fmt_specs.type != 'c')
246  return (*this)(static_cast<int>(value));
247  fmt_specs.sign = sign::none;
248  fmt_specs.alt = false;
249  fmt_specs.align = align::right;
250  return base::operator()(value);
251  } else {
252  return base::operator()(value);
253  }
254  return this->out();
255  }
256 
257  template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
258  iterator operator()(T value) {
259  return base::operator()(value);
260  }
261 
262  /** Formats a null-terminated C string. */
263  iterator operator()(const char* value) {
264  if (value)
265  base::operator()(value);
266  else if (this->specs()->type == 'p')
267  write_null_pointer(char_type());
268  else
269  this->write("(null)");
270  return this->out();
271  }
272 
273  /** Formats a null-terminated wide C string. */
274  iterator operator()(const wchar_t* value) {
275  if (value)
276  base::operator()(value);
277  else if (this->specs()->type == 'p')
278  write_null_pointer(char_type());
279  else
280  this->write(L"(null)");
281  return this->out();
282  }
283 
285  return base::operator()(value);
286  }
287 
288  iterator operator()(monostate value) { return base::operator()(value); }
289 
290  /** Formats a pointer. */
291  iterator operator()(const void* value) {
292  if (value) return base::operator()(value);
293  this->specs()->type = 0;
294  write_null_pointer(char_type());
295  return this->out();
296  }
297 
298  /** Formats an argument of a custom (user-defined) type. */
300  handle.format(context_.parse_context(), context_);
301  return this->out();
302  }
303 };
304 
305 template <typename T> struct printf_formatter {
306  template <typename ParseContext>
307  auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
308  return ctx.begin();
309  }
310 
311  template <typename FormatContext>
312  auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) {
314  return ctx.out();
315  }
316 };
317 
318 /** This template formats data and writes the output to a writer. */
319 template <typename OutputIt, typename Char> class basic_printf_context {
320  public:
321  /** The character type for the output. */
322  using char_type = Char;
324  template <typename T> using formatter_type = printf_formatter<T>;
325 
326  private:
328 
329  OutputIt out_;
332 
333  static void parse_flags(format_specs& specs, const Char*& it,
334  const Char* end);
335 
336  // Returns the argument with specified index or, if arg_index is -1, the next
337  // argument.
338  format_arg get_arg(int arg_index = -1);
339 
340  // Parses argument index, flags and width and returns the argument index.
341  int parse_header(const Char*& it, const Char* end, format_specs& specs);
342 
343  public:
344  /**
345  \rst
346  Constructs a ``printf_context`` object. References to the arguments and
347  the writer are stored in the context object so make sure they have
348  appropriate lifetimes.
349  \endrst
350  */
353  : out_(out), args_(args), parse_ctx_(format_str) {}
354 
355  OutputIt out() { return out_; }
356  void advance_to(OutputIt it) { out_ = it; }
357 
358  format_arg arg(int id) const { return args_.get(id); }
359 
361 
362  FMT_CONSTEXPR void on_error(const char* message) {
363  parse_ctx_.on_error(message);
364  }
365 
366  /** Formats stored arguments and writes the output to the range. */
367  template <typename ArgFormatter = printf_arg_formatter<buffer_range<Char>>>
368  OutputIt format();
369 };
370 
371 template <typename OutputIt, typename Char>
373  const Char*& it,
374  const Char* end) {
375  for (; it != end; ++it) {
376  switch (*it) {
377  case '-':
378  specs.align = align::left;
379  break;
380  case '+':
381  specs.sign = sign::plus;
382  break;
383  case '0':
384  specs.fill[0] = '0';
385  break;
386  case ' ':
387  specs.sign = sign::space;
388  break;
389  case '#':
390  specs.alt = true;
391  break;
392  default:
393  return;
394  }
395  }
396 }
397 
398 template <typename OutputIt, typename Char>
401  if (arg_index < 0)
402  arg_index = parse_ctx_.next_arg_id();
403  else
404  parse_ctx_.check_arg_id(--arg_index);
405  return internal::get_arg(*this, arg_index);
406 }
407 
408 template <typename OutputIt, typename Char>
410  const Char*& it, const Char* end, format_specs& specs) {
411  int arg_index = -1;
412  char_type c = *it;
413  if (c >= '0' && c <= '9') {
414  // Parse an argument index (if followed by '$') or a width possibly
415  // preceded with '0' flag(s).
417  int value = parse_nonnegative_int(it, end, eh);
418  if (it != end && *it == '$') { // value is an argument index
419  ++it;
420  arg_index = value;
421  } else {
422  if (c == '0') specs.fill[0] = '0';
423  if (value != 0) {
424  // Nonzero value means that we parsed width and don't need to
425  // parse it or flags again, so return now.
426  specs.width = value;
427  return arg_index;
428  }
429  }
430  }
431  parse_flags(specs, it, end);
432  // Parse width.
433  if (it != end) {
434  if (*it >= '0' && *it <= '9') {
436  specs.width = parse_nonnegative_int(it, end, eh);
437  } else if (*it == '*') {
438  ++it;
439  specs.width = static_cast<int>(visit_format_arg(
441  }
442  }
443  return arg_index;
444 }
445 
446 template <typename OutputIt, typename Char>
447 template <typename ArgFormatter>
449  auto out = this->out();
450  const Char* start = parse_ctx_.begin();
451  const Char* end = parse_ctx_.end();
452  auto it = start;
453  while (it != end) {
454  char_type c = *it++;
455  if (c != '%') continue;
456  if (it != end && *it == c) {
457  out = std::copy(start, it, out);
458  start = ++it;
459  continue;
460  }
461  out = std::copy(start, it - 1, out);
462 
463  format_specs specs;
464  specs.align = align::right;
465 
466  // Parse argument index, flags and width.
467  int arg_index = parse_header(it, end, specs);
468  if (arg_index == 0) on_error("argument index out of range");
469 
470  // Parse precision.
471  if (it != end && *it == '.') {
472  ++it;
473  c = it != end ? *it : 0;
474  if ('0' <= c && c <= '9') {
476  specs.precision = parse_nonnegative_int(it, end, eh);
477  } else if (c == '*') {
478  ++it;
479  specs.precision =
481  } else {
482  specs.precision = 0;
483  }
484  }
485 
486  format_arg arg = get_arg(arg_index);
487  if (specs.alt && visit_format_arg(internal::is_zero_int(), arg))
488  specs.alt = false;
489  if (specs.fill[0] == '0') {
490  if (arg.is_arithmetic())
491  specs.align = align::numeric;
492  else
493  specs.fill[0] = ' '; // Ignore '0' flag for non-numeric types.
494  }
495 
496  // Parse length and convert the argument to the required type.
497  c = it != end ? *it++ : 0;
498  char_type t = it != end ? *it : 0;
499  using internal::convert_arg;
500  switch (c) {
501  case 'h':
502  if (t == 'h') {
503  ++it;
504  t = it != end ? *it : 0;
505  convert_arg<signed char>(arg, t);
506  } else {
507  convert_arg<short>(arg, t);
508  }
509  break;
510  case 'l':
511  if (t == 'l') {
512  ++it;
513  t = it != end ? *it : 0;
514  convert_arg<long long>(arg, t);
515  } else {
516  convert_arg<long>(arg, t);
517  }
518  break;
519  case 'j':
520  convert_arg<intmax_t>(arg, t);
521  break;
522  case 'z':
523  convert_arg<std::size_t>(arg, t);
524  break;
525  case 't':
526  convert_arg<std::ptrdiff_t>(arg, t);
527  break;
528  case 'L':
529  // printf produces garbage when 'L' is omitted for long double, no
530  // need to do the same.
531  break;
532  default:
533  --it;
534  convert_arg<void>(arg, c);
535  }
536 
537  // Parse type.
538  if (it == end) FMT_THROW(format_error("invalid format string"));
539  specs.type = static_cast<char>(*it++);
540  if (arg.is_integral()) {
541  // Normalize type.
542  switch (specs.type) {
543  case 'i':
544  case 'u':
545  specs.type = 'd';
546  break;
547  case 'c':
549  arg);
550  break;
551  }
552  }
553 
554  start = it;
555 
556  // Format argument.
557  visit_format_arg(ArgFormatter(out, specs, *this), arg);
558  }
559  return std::copy(start, it, out);
560 }
561 
562 template <typename Char>
565  Char>;
566 
569 
572 
573 /**
574  \rst
575  Constructs an `~fmt::format_arg_store` object that contains references to
576  arguments and can be implicitly converted to `~fmt::printf_args`.
577  \endrst
578  */
579 template <typename... Args>
581  const Args&... args) {
582  return {args...};
583 }
584 
585 /**
586  \rst
587  Constructs an `~fmt::format_arg_store` object that contains references to
588  arguments and can be implicitly converted to `~fmt::wprintf_args`.
589  \endrst
590  */
591 template <typename... Args>
593  const Args&... args) {
594  return {args...};
595 }
596 
597 template <typename S, typename Char = char_t<S>>
598 inline std::basic_string<Char> vsprintf(
601  printf(buffer, to_string_view(format), args);
602  return to_string(buffer);
603 }
604 
605 /**
606  \rst
607  Formats arguments and returns the result as a string.
608 
609  **Example**::
610 
611  std::string message = fmt::sprintf("The answer is %d", 42);
612  \endrst
613 */
614 template <typename S, typename... Args,
616 inline std::basic_string<Char> sprintf(const S& format, const Args&... args) {
617  using context = basic_printf_context_t<Char>;
618  return vsprintf(to_string_view(format), {make_format_args<context>(args...)});
619 }
620 
621 template <typename S, typename Char = char_t<S>>
622 inline int vfprintf(std::FILE* f, const S& format,
625  printf(buffer, to_string_view(format), args);
626  std::size_t size = buffer.size();
627  return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
628  ? -1
629  : static_cast<int>(size);
630 }
631 
632 /**
633  \rst
634  Prints formatted data to the file *f*.
635 
636  **Example**::
637 
638  fmt::fprintf(stderr, "Don't %s!", "panic");
639  \endrst
640  */
641 template <typename S, typename... Args,
643 inline int fprintf(std::FILE* f, const S& format, const Args&... args) {
644  using context = basic_printf_context_t<Char>;
645  return vfprintf(f, to_string_view(format),
646  {make_format_args<context>(args...)});
647 }
648 
649 template <typename S, typename Char = char_t<S>>
650 inline int vprintf(const S& format,
652  return vfprintf(stdout, to_string_view(format), args);
653 }
654 
655 /**
656  \rst
657  Prints formatted data to ``stdout``.
658 
659  **Example**::
660 
661  fmt::printf("Elapsed time: %.2f seconds", 1.23);
662  \endrst
663  */
664 template <typename S, typename... Args,
666 inline int printf(const S& format_str, const Args&... args) {
667  using context = basic_printf_context_t<char_t<S>>;
668  return vprintf(to_string_view(format_str),
669  {make_format_args<context>(args...)});
670 }
671 
672 template <typename S, typename Char = char_t<S>>
673 inline int vfprintf(std::basic_ostream<Char>& os, const S& format,
676  printf(buffer, to_string_view(format), args);
677  internal::write(os, buffer);
678  return static_cast<int>(buffer.size());
679 }
680 
681 /** Formats arguments and writes the output to the range. */
682 template <typename ArgFormatter, typename Char,
683  typename Context =
685 typename ArgFormatter::iterator vprintf(internal::buffer<Char>& out,
686  basic_string_view<Char> format_str,
688  typename ArgFormatter::iterator iter(out);
689  Context(iter, format_str, args).template format<ArgFormatter>();
690  return iter;
691 }
692 
693 /**
694  \rst
695  Prints formatted data to the stream *os*.
696 
697  **Example**::
698 
699  fmt::fprintf(cerr, "Don't %s!", "panic");
700  \endrst
701  */
702 template <typename S, typename... Args, typename Char = char_t<S>>
703 inline int fprintf(std::basic_ostream<Char>& os, const S& format_str,
704  const Args&... args) {
705  using context = basic_printf_context_t<Char>;
706  return vfprintf(os, to_string_view(format_str),
707  {make_format_args<context>(args...)});
708 }
710 
711 #endif // FMT_PRINTF_H_
context_type & context_
Definition: printf.h:209
int vfprintf(std::FILE *f, const S &format, basic_format_args< basic_printf_context_t< Char >> args)
Definition: printf.h:622
#define FMT_BEGIN_NAMESPACE
Definition: core.h:163
iterator operator()(monostate value)
Definition: printf.h:288
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
Definition: color.h:562
std::size_t size() const FMT_NOEXCEPT
Definition: core.h:607
std::basic_string< Char > vsprintf(const S &format, basic_format_args< basic_printf_context_t< Char >> args)
Definition: printf.h:598
int parse_header(const Char *&it, const Char *end, format_specs &specs)
Definition: printf.h:409
basic_format_parse_context< Char > & parse_context()
Definition: printf.h:360
basic_printf_context(OutputIt out, basic_string_view< char_type > format_str, basic_format_args< basic_printf_context > args)
Definition: printf.h:351
void operator()(bool value)
Definition: printf.h:82
auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: printf.h:307
int vprintf(const S &format, basic_format_args< basic_printf_context_t< Char >> args)
Definition: printf.h:650
std::basic_string< Char > sprintf(const S &format, const Args &... args)
Definition: printf.h:616
bool is_arithmetic() const
Definition: core.h:993
basic_format_arg< Context > & arg_
Definition: printf.h:129
iterator operator()(basic_string_view< char_type > value)
Definition: printf.h:284
arg_converter(basic_format_arg< Context > &arg, char_type type)
Definition: printf.h:79
FMT_CONSTEXPR Context::format_arg get_arg(Context &ctx, int id)
Definition: format.h:2136
FMT_CONSTEXPR void on_error(const char *message)
Definition: core.h:531
void write_null_pointer(char)
Definition: printf.h:211
FMT_CONSTEXPR void on_error(const char *message)
Definition: printf.h:362
internal::fill_t< Char > fill
Definition: format.h:1022
int fprintf(std::FILE *f, const S &format, const Args &... args)
Definition: printf.h:643
bool is_integral() const
Definition: core.h:992
T * data() FMT_NOEXCEPT
Definition: core.h:613
void advance_to(OutputIt it)
Definition: printf.h:356
#define FMT_THROW(x)
Definition: format.h:94
iterator operator()(const void *value)
Definition: printf.h:291
FMT_CONSTEXPR bool is_negative(T value)
Definition: format.h:708
void convert_arg(basic_format_arg< Context > &arg, Char type)
Definition: printf.h:122
OutputIt format()
Definition: printf.h:448
typename internal::char_t_impl< S >::type char_t
Definition: core.h:458
void format_value(buffer< Char > &buf, const T &value, locale_ref loc=locale_ref())
Definition: ostream.h:92
basic_format_args< basic_printf_context > args_
Definition: printf.h:330
#define FMT_END_NAMESPACE
Definition: core.h:158
format_arg get_arg(int arg_index=-1)
Definition: printf.h:400
basic_format_arg< Context > & arg_
Definition: printf.h:75
static bool fits_in_int(int)
Definition: printf.h:34
format_arg_store< printf_context, Args... > make_printf_args(const Args &... args)
Definition: printf.h:580
typename Context::char_type char_type
Definition: printf.h:73
basic_format_parse_context< Char > parse_ctx_
Definition: printf.h:331
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:204
auto format(const T &value, FormatContext &ctx) -> decltype(ctx.out())
Definition: printf.h:312
FMT_CONSTEXPR int parse_nonnegative_int(const Char *&begin, const Char *end, ErrorHandler &&eh)
Definition: format.h:1926
std::string to_string(const T &value)
Definition: format.h:3245
OutputIterator copy(const RangeT &range, OutputIterator out)
Definition: ranges.h:58
#define FMT_ENABLE_IF(...)
Definition: core.h:220
void to_string_view(...)
basic_format_specs< char > format_specs
Definition: format.h:1034
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:206
T const_check(T value)
Definition: format.h:208
basic_printf_context_t< wchar_t > wprintf_context
Definition: printf.h:568
static bool fits_in_int(T value)
Definition: printf.h:30
FMT_CONSTEXPR auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
Definition: core.h:1004
void write_null_pointer(wchar_t)
Definition: printf.h:216
format_arg get(int index) const
Definition: core.h:1303
type
Definition: core.h:687
static void parse_flags(format_specs &specs, const Char *&it, const Char *end)
Definition: printf.h:372
OutputIt out()
Definition: printf.h:355
typename base::format_specs format_specs
Definition: printf.h:222
printf_width_handler(format_specs &specs)
Definition: printf.h:153
basic_printf_context_t< char > printf_context
Definition: printf.h:567
static bool fits_in_int(T value)
Definition: printf.h:22
static bool fits_in_int(bool)
Definition: printf.h:26
iterator operator()(const char *value)
Definition: printf.h:263
typename Range::iterator iterator
Definition: printf.h:202
char_converter(basic_format_arg< Context > &arg)
Definition: printf.h:132
typename Range::value_type char_type
Definition: printf.h:205
iterator operator()(typename basic_format_arg< context_type >::handle handle)
Definition: printf.h:299
printf_arg_formatter(iterator iter, format_specs &specs, context_type &ctx)
Definition: printf.h:231
conditional_t< std::numeric_limits< T >::digits<=32, uint32_t, conditional_t< std::numeric_limits< T >::digits<=64, uint64_t, uint128_t > > uint32_or_64_or_128_t
Definition: format.h:721
Container & get_container(std::back_insert_iterator< Container > it)
Definition: core.h:665
#define FMT_CONSTEXPR
Definition: core.h:75
void write(std::basic_ostream< Char > &os, buffer< Char > &buf)
Definition: ostream.h:78
void format(basic_format_parse_context< char_type > &parse_ctx, Context &ctx) const
Definition: core.h:975
internal::named_arg< T, Char > arg(const S &name, const T &arg)
Definition: core.h:1422
format_arg_store< wprintf_context, Args... > make_wprintf_args(const Args &... args)
Definition: printf.h:592
format_arg arg(int id) const
Definition: printf.h:358
void printf(buffer< Char > &buf, basic_string_view< Char > format, basic_format_args< Context > args)
Definition: printf.h:175
iterator operator()(const wchar_t *value)
Definition: printf.h:274