Photon 1.0.0
Loading...
Searching...
No Matches
compile.h
Go to the documentation of this file.
1// Formatting library for C++ - experimental format string compilation
2//
3// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors
4// All rights reserved.
5//
6// For the license information refer to format.h.
7
8#ifndef FMT_COMPILE_H_
9#define FMT_COMPILE_H_
10
11#include "format.h"
12
14namespace detail
15{
16
17 template <typename Char, typename InputIt>
18 FMT_CONSTEXPR inline counting_iterator copy_str(InputIt begin, InputIt end, counting_iterator it)
19 {
20 return it + (end - begin);
21 }
22
23 template <typename OutputIt>
25 {
26 protected:
27 OutputIt out_;
28 size_t limit_;
29 size_t count_ = 0;
30
32 : out_(), limit_(0)
33 {
34 }
35
36 truncating_iterator_base(OutputIt out, size_t limit)
37 : out_(out), limit_(limit)
38 {
39 }
40
41 public:
42 using iterator_category = std::output_iterator_tag;
43 using value_type = typename std::iterator_traits<OutputIt>::value_type;
44 using difference_type = std::ptrdiff_t;
45 using pointer = void;
46 using reference = void;
48
49 OutputIt base() const
50 {
51 return out_;
52 }
53 size_t count() const
54 {
55 return count_;
56 }
57 };
58
59 // An output iterator that truncates the output and counts the number of objects
60 // written to it.
61 template <typename OutputIt,
62 typename Enable = typename std::is_void<
63 typename std::iterator_traits<OutputIt>::value_type>::type>
65
66 template <typename OutputIt>
67 class truncating_iterator<OutputIt, std::false_type>
68 : public truncating_iterator_base<OutputIt>
69 {
71
72 public:
74
76
77 truncating_iterator(OutputIt out, size_t limit)
78 : truncating_iterator_base<OutputIt>(out, limit)
79 {
80 }
81
83 {
84 if (this->count_++ < this->limit_)
85 ++this->out_;
86 return *this;
87 }
88
90 {
91 auto it = *this;
92 ++*this;
93 return it;
94 }
95
97 {
98 return this->count_ < this->limit_ ? *this->out_ : blackhole_;
99 }
100 };
101
102 template <typename OutputIt>
103 class truncating_iterator<OutputIt, std::true_type>
104 : public truncating_iterator_base<OutputIt>
105 {
106 public:
108
109 truncating_iterator(OutputIt out, size_t limit)
110 : truncating_iterator_base<OutputIt>(out, limit)
111 {
112 }
113
114 template <typename T>
116 {
117 if (this->count_++ < this->limit_)
118 *this->out_++ = val;
119 return *this;
120 }
121
123 {
124 return *this;
125 }
127 {
128 return *this;
129 }
131 {
132 return *this;
133 }
134 };
135
136 // A compile-time string which is compiled into fast formatting code.
138 {
139 };
140
141 template <typename S>
142 struct is_compiled_string : std::is_base_of<compiled_string, S>
143 {
144 };
145
159#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
160#define FMT_COMPILE(s) \
161 FMT_STRING_IMPL(s, fmt::detail::compiled_string, explicit)
162#else
163#define FMT_COMPILE(s) FMT_STRING(s)
164#endif
165
166#if FMT_USE_NONTYPE_TEMPLATE_ARGS
167 template <typename Char, size_t N, fmt::detail_exported::fixed_string<Char, N> Str>
168 struct udl_compiled_string : compiled_string
169 {
170 using char_type = Char;
171 explicit constexpr operator basic_string_view<char_type>() const
172 {
173 return {Str.data, N - 1};
174 }
175 };
176#endif
177
178 template <typename T, typename... Tail>
179 const T& first(const T& value, const Tail&...)
180 {
181 return value;
182 }
183
184#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
185 template <typename... Args>
186 struct type_list
187 {
188 };
189
190 // Returns a reference to the argument at index N from [first, rest...].
191 template <int N, typename T, typename... Args>
192 constexpr const auto& get([[maybe_unused]] const T& first,
193 [[maybe_unused]] const Args&... rest)
194 {
195 static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
196 if constexpr (N == 0)
197 return first;
198 else
199 return detail::get<N - 1>(rest...);
200 }
201
202 template <typename Char, typename... Args>
204 type_list<Args...>)
205 {
206 return get_arg_index_by_name<Args...>(name);
207 }
208
209 template <int N, typename>
210 struct get_type_impl;
211
212 template <int N, typename... Args>
213 struct get_type_impl<N, type_list<Args...>>
214 {
215 using type =
216 remove_cvref_t<decltype(detail::get<N>(std::declval<Args>()...))>;
217 };
218
219 template <int N, typename T>
220 using get_type = typename get_type_impl<N, T>::type;
221
222 template <typename T>
223 struct is_compiled_format : std::false_type
224 {
225 };
226
227 template <typename Char>
228 struct text
229 {
231 using char_type = Char;
232
233 template <typename OutputIt, typename... Args>
234 constexpr OutputIt format(OutputIt out, const Args&...) const
235 {
236 return write<Char>(out, data);
237 }
238 };
239
240 template <typename Char>
241 struct is_compiled_format<text<Char>> : std::true_type
242 {
243 };
244
245 template <typename Char>
246 constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos, size_t size)
247 {
248 return {{&s[pos], size}};
249 }
250
251 template <typename Char>
252 struct code_unit
253 {
254 Char value;
255 using char_type = Char;
256
257 template <typename OutputIt, typename... Args>
258 constexpr OutputIt format(OutputIt out, const Args&...) const
259 {
260 return write<Char>(out, value);
261 }
262 };
263
264 // This ensures that the argument type is convertible to `const T&`.
265 template <typename T, int N, typename... Args>
266 constexpr const T& get_arg_checked(const Args&... args)
267 {
268 const auto& arg = detail::get<N>(args...);
269 if constexpr (detail::is_named_arg<remove_cvref_t<decltype(arg)>>())
270 {
271 return arg.value;
272 }
273 else
274 {
275 return arg;
276 }
277 }
278
279 template <typename Char>
280 struct is_compiled_format<code_unit<Char>> : std::true_type
281 {
282 };
283
284 // A replacement field that refers to argument N.
285 template <typename Char, typename T, int N>
286 struct field
287 {
288 using char_type = Char;
289
290 template <typename OutputIt, typename... Args>
291 constexpr OutputIt format(OutputIt out, const Args&... args) const
292 {
293 return write<Char>(out, get_arg_checked<T, N>(args...));
294 }
295 };
296
297 template <typename Char, typename T, int N>
298 struct is_compiled_format<field<Char, T, N>> : std::true_type
299 {
300 };
301
302 // A replacement field that refers to argument with name.
303 template <typename Char>
304 struct runtime_named_field
305 {
306 using char_type = Char;
308
309 template <typename OutputIt, typename T>
310 constexpr static bool try_format_argument(
311 OutputIt& out,
312 // [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9
313 [[maybe_unused]] basic_string_view<Char> arg_name,
314 const T& arg)
315 {
317 {
318 if (arg_name == arg.name)
319 {
320 out = write<Char>(out, arg.value);
321 return true;
322 }
323 }
324 return false;
325 }
326
327 template <typename OutputIt, typename... Args>
328 constexpr OutputIt format(OutputIt out, const Args&... args) const
329 {
330 bool found = (try_format_argument(out, name, args) || ...);
331 if (!found)
332 {
333 FMT_THROW(format_error("argument with specified name is not found"));
334 }
335 return out;
336 }
337 };
338
339 template <typename Char>
340 struct is_compiled_format<runtime_named_field<Char>> : std::true_type
341 {
342 };
343
344 // A replacement field that refers to argument N and has format specifiers.
345 template <typename Char, typename T, int N>
346 struct spec_field
347 {
348 using char_type = Char;
350
351 template <typename OutputIt, typename... Args>
352 constexpr FMT_INLINE OutputIt format(OutputIt out,
353 const Args&... args) const
354 {
355 const auto& vargs =
356 fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...);
358 return fmt.format(get_arg_checked<T, N>(args...), ctx);
359 }
360 };
361
362 template <typename Char, typename T, int N>
363 struct is_compiled_format<spec_field<Char, T, N>> : std::true_type
364 {
365 };
366
367 template <typename L, typename R>
368 struct concat
369 {
370 L lhs;
371 R rhs;
372 using char_type = typename L::char_type;
373
374 template <typename OutputIt, typename... Args>
375 constexpr OutputIt format(OutputIt out, const Args&... args) const
376 {
377 out = lhs.format(out, args...);
378 return rhs.format(out, args...);
379 }
380 };
381
382 template <typename L, typename R>
383 struct is_compiled_format<concat<L, R>> : std::true_type
384 {
385 };
386
387 template <typename L, typename R>
388 constexpr concat<L, R> make_concat(L lhs, R rhs)
389 {
390 return {lhs, rhs};
391 }
392
393 struct unknown_format
394 {
395 };
396
397 template <typename Char>
398 constexpr size_t parse_text(basic_string_view<Char> str, size_t pos)
399 {
400 for (size_t size = str.size(); pos != size; ++pos)
401 {
402 if (str[pos] == '{' || str[pos] == '}')
403 break;
404 }
405 return pos;
406 }
407
408 template <typename Args, size_t POS, int ID, typename S>
409 constexpr auto compile_format_string(S format_str);
410
411 template <typename Args, size_t POS, int ID, typename T, typename S>
412 constexpr auto parse_tail(T head, S format_str)
413 {
414 if constexpr (POS !=
416 {
417 constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
418 if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
419 unknown_format>())
420 return tail;
421 else
422 return make_concat(head, tail);
423 }
424 else
425 {
426 return head;
427 }
428 }
429
430 template <typename T, typename Char>
431 struct parse_specs_result
432 {
434 size_t end;
435 int next_arg_id;
436 };
437
438 constexpr int manual_indexing_id = -1;
439
440 template <typename T, typename Char>
441 constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
442 size_t pos,
443 int next_arg_id)
444 {
445 str.remove_prefix(pos);
446 auto ctx = compile_parse_context<Char>(str, max_value<int>(), nullptr, {},
447 next_arg_id);
448 auto f = formatter<T, Char>();
449 auto end = f.parse(ctx);
450 return {f, pos + fmt::detail::to_unsigned(end - str.data()),
451 next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()};
452 }
453
454 template <typename Char>
455 struct arg_id_handler
456 {
457 arg_ref<Char> arg_id;
458
459 constexpr int operator()()
460 {
461 FMT_ASSERT(false, "handler cannot be used with automatic indexing");
462 return 0;
463 }
464 constexpr int operator()(int id)
465 {
466 arg_id = arg_ref<Char>(id);
467 return 0;
468 }
469 constexpr int operator()(basic_string_view<Char> id)
470 {
471 arg_id = arg_ref<Char>(id);
472 return 0;
473 }
474
475 constexpr void on_error(const char* message)
476 {
477 FMT_THROW(format_error(message));
478 }
479 };
480
481 template <typename Char>
482 struct parse_arg_id_result
483 {
484 arg_ref<Char> arg_id;
485 const Char* arg_id_end;
486 };
487
488 template <int ID, typename Char>
489 constexpr auto parse_arg_id(const Char* begin, const Char* end)
490 {
491 auto handler = arg_id_handler<Char>{arg_ref<Char>{}};
492 auto arg_id_end = parse_arg_id(begin, end, handler);
493 return parse_arg_id_result<Char>{handler.arg_id, arg_id_end};
494 }
495
496 template <typename T, typename Enable = void>
497 struct field_type
498 {
499 using type = remove_cvref_t<T>;
500 };
501
502 template <typename T>
503 struct field_type<T, enable_if_t<detail::is_named_arg<T>::value>>
504 {
505 using type = remove_cvref_t<decltype(T::value)>;
506 };
507
508 template <typename T, typename Args, size_t END_POS, int ARG_INDEX, int NEXT_ID, typename S>
509 constexpr auto parse_replacement_field_then_tail(S format_str)
510 {
511 using char_type = typename S::char_type;
512 constexpr auto str = basic_string_view<char_type>(format_str);
513 constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type();
514 if constexpr (c == '}')
515 {
516 return parse_tail<Args, END_POS + 1, NEXT_ID>(
517 field<char_type, typename field_type<T>::type, ARG_INDEX>(),
518 format_str);
519 }
520 else if constexpr (c != ':')
521 {
522 FMT_THROW(format_error("expected ':'"));
523 }
524 else
525 {
526 constexpr auto result = parse_specs<typename field_type<T>::type>(
527 str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID);
528 if constexpr (result.end >= str.size() || str[result.end] != '}')
529 {
530 FMT_THROW(format_error("expected '}'"));
531 return 0;
532 }
533 else
534 {
535 return parse_tail<Args, result.end + 1, result.next_arg_id>(
536 spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{
537 result.fmt},
538 format_str);
539 }
540 }
541 }
542
543 // Compiles a non-empty format string and returns the compiled representation
544 // or unknown_format() on unrecognized input.
545 template <typename Args, size_t POS, int ID, typename S>
546 constexpr auto compile_format_string(S format_str)
547 {
548 using char_type = typename S::char_type;
549 constexpr auto str = basic_string_view<char_type>(format_str);
550 if constexpr (str[POS] == '{')
551 {
552 if constexpr (POS + 1 == str.size())
553 FMT_THROW(format_error("unmatched '{' in format string"));
554 if constexpr (str[POS + 1] == '{')
555 {
556 return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
557 }
558 else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':')
559 {
560 static_assert(ID != manual_indexing_id,
561 "cannot switch from manual to automatic argument indexing");
562 constexpr auto next_id =
563 ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
564 return parse_replacement_field_then_tail<get_type<ID, Args>, Args,
565 POS + 1, ID, next_id>(
566 format_str);
567 }
568 else
569 {
570 constexpr auto arg_id_result =
571 parse_arg_id<ID>(str.data() + POS + 1, str.data() + str.size());
572 constexpr auto arg_id_end_pos = arg_id_result.arg_id_end - str.data();
573 constexpr char_type c =
574 arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type();
575 static_assert(c == '}' || c == ':', "missing '}' in format string");
576 if constexpr (arg_id_result.arg_id.kind == arg_id_kind::index)
577 {
578 static_assert(
579 ID == manual_indexing_id || ID == 0,
580 "cannot switch from automatic to manual argument indexing");
581 constexpr auto arg_index = arg_id_result.arg_id.val.index;
582 return parse_replacement_field_then_tail<get_type<arg_index, Args>,
583 Args, arg_id_end_pos,
584 arg_index, manual_indexing_id>(
585 format_str);
586 }
587 else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name)
588 {
589 constexpr auto arg_index =
590 get_arg_index_by_name(arg_id_result.arg_id.val.name, Args{});
591 if constexpr (arg_index != invalid_arg_index)
592 {
593 constexpr auto next_id =
594 ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
595 return parse_replacement_field_then_tail<
596 decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos,
597 arg_index, next_id>(format_str);
598 }
599 else
600 {
601 if constexpr (c == '}')
602 {
603 return parse_tail<Args, arg_id_end_pos + 1, ID>(
604 runtime_named_field<char_type>{arg_id_result.arg_id.val.name},
605 format_str);
606 }
607 else if constexpr (c == ':')
608 {
609 return unknown_format(); // no type info for specs parsing
610 }
611 }
612 }
613 }
614 }
615 else if constexpr (str[POS] == '}')
616 {
617 if constexpr (POS + 1 == str.size())
618 FMT_THROW(format_error("unmatched '}' in format string"));
619 return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
620 }
621 else
622 {
623 constexpr auto end = parse_text(str, POS + 1);
624 if constexpr (end - POS > 1)
625 {
626 return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
627 format_str);
628 }
629 else
630 {
631 return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]},
632 format_str);
633 }
634 }
635 }
636
637 template <typename... Args, typename S, FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
638 constexpr auto compile(S format_str)
639 {
640 constexpr auto str = basic_string_view<typename S::char_type>(format_str);
641 if constexpr (str.size() == 0)
642 {
643 return detail::make_text(str, 0, 0);
644 }
645 else
646 {
647 constexpr auto result =
648 detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
649 format_str);
650 return result;
651 }
652 }
653#endif // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
654} // namespace detail
655
657
658#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
659
660template <typename CompiledFormat, typename... Args, typename Char = typename CompiledFormat::char_type, FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
661FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
662 const Args&... args)
663{
664 auto s = std::basic_string<Char>();
665 cf.format(std::back_inserter(s), args...);
666 return s;
667}
668
669template <typename OutputIt, typename CompiledFormat, typename... Args, FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
670constexpr FMT_INLINE OutputIt format_to(OutputIt out, const CompiledFormat& cf, const Args&... args)
671{
672 return cf.format(out, args...);
673}
674
675template <typename S, typename... Args, FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
676FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
677 Args&&... args)
678{
679 if constexpr (std::is_same<typename S::char_type, char>::value)
680 {
681 constexpr auto str = basic_string_view<typename S::char_type>(S());
682 if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}')
683 {
684 const auto& first = detail::first(args...);
685 if constexpr (detail::is_named_arg<
686 remove_cvref_t<decltype(first)>>::value)
687 {
688 return fmt::to_string(first.value);
689 }
690 else
691 {
692 return fmt::to_string(first);
693 }
694 }
695 }
696 constexpr auto compiled = detail::compile<Args...>(S());
697 if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
698 detail::unknown_format>())
699 {
700 return fmt::format(
702 std::forward<Args>(args)...);
703 }
704 else
705 {
706 return fmt::format(compiled, std::forward<Args>(args)...);
707 }
708}
709
710template <typename OutputIt, typename S, typename... Args, FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
711FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args)
712{
713 constexpr auto compiled = detail::compile<Args...>(S());
714 if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
715 detail::unknown_format>())
716 {
717 return fmt::format_to(
719 std::forward<Args>(args)...);
720 }
721 else
722 {
723 return fmt::format_to(out, compiled, std::forward<Args>(args)...);
724 }
725}
726#endif
727
728template <typename OutputIt, typename S, typename... Args, FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
729format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n, const S& format_str, Args&&... args)
730{
731 auto it = fmt::format_to(detail::truncating_iterator<OutputIt>(out, n),
732 format_str, std::forward<Args>(args)...);
733 return {it.base(), it.count()};
734}
735
736template <typename S, typename... Args, FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
737FMT_CONSTEXPR20 size_t formatted_size(const S& format_str,
738 const Args&... args)
739{
740 return fmt::format_to(detail::counting_iterator(), format_str, args...)
741 .count();
742}
743
744template <typename S, typename... Args, FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
745void print(std::FILE* f, const S& format_str, const Args&... args)
746{
748 fmt::format_to(std::back_inserter(buffer), format_str, args...);
750}
751
752template <typename S, typename... Args, FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
753void print(const S& format_str, const Args&... args)
754{
755 print(stdout, format_str, args...);
756}
757
758#if FMT_USE_NONTYPE_TEMPLATE_ARGS
759inline namespace literals
760{
761 template <detail_exported::fixed_string Str>
762 constexpr auto operator""_cf()
763 {
764 using char_t = remove_cvref_t<decltype(Str.data[0])>;
765 return detail::udl_compiled_string<char_t, sizeof(Str.data) / sizeof(char_t),
766 Str>();
767 }
768} // namespace literals
769#endif
770
773
774#endif // FMT_COMPILE_H_
void print(std::FILE *f, const S &format_str, const Args &... args)
Definition compile.h:745
FMT_MODULE_EXPORT_BEGIN format_to_n_result< OutputIt > format_to_n(OutputIt out, size_t n, const S &format_str, Args &&... args)
Definition compile.h:729
FMT_CONSTEXPR20 size_t formatted_size(const S &format_str, const Args &... args)
Definition compile.h:737
Definition core.h:2338
Definition core.h:483
constexpr auto size() const noexcept -> size_t
Definition core.h:541
constexpr auto data() const noexcept -> const Char *
Definition core.h:535
FMT_CONSTEXPR void remove_prefix(size_t n) noexcept
Definition core.h:560
Definition core.h:1032
FMT_CONSTEXPR auto data() noexcept -> T *
Definition core.h:1102
constexpr auto size() const noexcept -> size_t
Definition core.h:1090
Definition core.h:863
FMT_CONSTEXPR auto next_arg_id() -> int
Definition core.h:885
Definition format.h:2565
Definition compile.h:138
truncating_iterator operator++(int)
Definition compile.h:89
truncating_iterator(OutputIt out, size_t limit)
Definition compile.h:77
truncating_iterator_base< OutputIt >::value_type blackhole_
Definition compile.h:70
typename truncating_iterator_base< OutputIt >::value_type value_type
Definition compile.h:73
truncating_iterator & operator++()
Definition compile.h:82
value_type & operator*() const
Definition compile.h:96
truncating_iterator & operator++(int)
Definition compile.h:126
truncating_iterator & operator=(T val)
Definition compile.h:115
truncating_iterator & operator*()
Definition compile.h:130
truncating_iterator(OutputIt out, size_t limit)
Definition compile.h:109
truncating_iterator & operator++()
Definition compile.h:122
Definition compile.h:25
truncating_iterator_base()
Definition compile.h:31
FMT_UNCHECKED_ITERATOR(truncating_iterator_base)
size_t count_
Definition compile.h:29
size_t count() const
Definition compile.h:53
truncating_iterator_base(OutputIt out, size_t limit)
Definition compile.h:36
OutputIt base() const
Definition compile.h:49
size_t limit_
Definition compile.h:28
OutputIt out_
Definition compile.h:27
void pointer
Definition compile.h:45
std::ptrdiff_t difference_type
Definition compile.h:44
void reference
Definition compile.h:46
std::output_iterator_tag iterator_category
Definition compile.h:42
typename std::iterator_traits< OutputIt >::value_type value_type
Definition compile.h:43
Definition compile.h:64
Definition format.h:1113
Definition core.h:1598
auto format_to(OutputIt out, const text_style &ts, const S &format_str, Args &&... args) -> typename std::enable_if< enable, OutputIt >::type
Definition color.h:677
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
Definition color.h:646
typename std::enable_if< B, T >::type enable_if_t
Definition core.h:302
#define FMT_ASSERT(condition, message)
Definition core.h:403
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition core.h:2506
typename detail::char_t_impl< S >::type char_t
Definition core.h:759
#define FMT_MODULE_EXPORT_BEGIN
Definition core.h:226
#define FMT_CONSTEXPR
Definition core.h:106
type
Definition core.h:681
@ char_type
#define FMT_BEGIN_NAMESPACE
Definition core.h:214
#define FMT_ENABLE_IF(...)
Definition core.h:364
#define FMT_INLINE
Definition core.h:199
FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler) -> const Char *
Definition core.h:3165
#define FMT_CONSTEXPR20
Definition core.h:114
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition core.h:312
constexpr int invalid_arg_index
Definition core.h:3748
#define FMT_END_NAMESPACE
Definition core.h:219
#define FMT_MODULE_EXPORT_END
Definition core.h:227
FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view< Char > name) -> int
Definition core.h:3767
#define out
Definition encodings.cpp:5
basic_memory_buffer< char > memory_buffer
Definition format.h:1095
#define FMT_THROW(x)
Definition format.h:99
Definition args.h:20
FMT_CONSTEXPR counting_iterator copy_str(InputIt begin, InputIt end, counting_iterator it)
Definition compile.h:18
FMT_FUNC void print(std::FILE *f, string_view text)
Definition format-inl.h:1620
const T & first(const T &value, const Tail &...)
Definition compile.h:179
result
Definition format.h:3059
Definition bin_to_hex.h:111
bool end(const css_token_vector &tokens, int index)
Definition gradient.cpp:78
Definition xchar.h:72
SPDLOG_INLINE std::shared_ptr< logger > get(const std::string &name)
Definition spdlog-inl.h:21
Definition uuid.h:926
Definition core.h:2808
Definition format.h:1901
Definition compile.h:143
Definition core.h:4128
Definition core.h:944
Definition core.h:1507
s
Definition tag_strings.h:47
head
Definition tag_strings.h:5