48 it.
count_ +=
static_cast<size_t>(n);
55 template <
typename Char,
typename InputIt>
58 return it + (end - begin);
70 : out_(out), limit_(limit) {}
81 OutputIt
base()
const {
return out_; }
87 template <
typename OutputIt,
88 typename Enable =
typename std::is_void<
92 template <
typename OutputIt>
106 if (this->
count_++ < this->limit_) ++this->out_;
117 return this->
count_ < this->limit_ ? *this->out_ : blackhole_;
121 template <
typename OutputIt>
131 if (this->
count_++ < this->limit_) *this->out_++ = val;
143 template <
typename S>
159 #ifdef __cpp_if_constexpr 160 # define FMT_COMPILE(s) \ 161 FMT_STRING_IMPL(s, fmt::detail::compiled_string, explicit) 163 # define FMT_COMPILE(s) FMT_STRING(s) 166 #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 167 template <
typename Char,
size_t N,
168 fmt::detail_exported::fixed_string<Char, N> Str>
169 struct udl_compiled_string : compiled_string {
172 return {Str.
data, N - 1};
177 template <
typename T,
typename... Tail>
182 #ifdef __cpp_if_constexpr 183 template <
typename... Args>
struct type_list {};
186 template <
int N,
typename T,
typename... Args>
187 constexpr
const auto&
get([[maybe_unused]]
const T&
first,
188 [[maybe_unused]]
const Args&... rest) {
189 static_assert(N < 1 +
sizeof...(Args),
"index is out of bounds");
190 if constexpr (N == 0)
193 return get<N - 1>(rest...);
196 template <
typename Char,
typename... Args>
198 type_list<Args...>) {
202 template <
int N,
typename>
struct get_type_impl;
204 template <
int N,
typename... Args>
struct get_type_impl<N, type_list<Args...>> {
208 template <
int N,
typename T>
213 template <
typename Char>
struct text {
217 template <
typename OutputIt,
typename... Args>
218 constexpr OutputIt
format(OutputIt out,
const Args&...)
const {
219 return write<Char>(out,
data);
223 template <
typename Char>
226 template <
typename Char>
229 return {{&s[pos], size}};
232 template <
typename Char>
struct code_unit {
236 template <
typename OutputIt,
typename... Args>
237 constexpr OutputIt
format(OutputIt out,
const Args&...)
const {
238 return write<Char>(out, value);
243 template <
typename T,
int N,
typename... Args>
244 constexpr
const T& get_arg_checked(
const Args&...
args) {
245 const auto&
arg = get<N>(args...);
253 template <
typename Char>
257 template <
typename Char,
typename T,
int N>
struct field {
260 template <
typename OutputIt,
typename... Args>
261 constexpr OutputIt
format(OutputIt out,
const Args&... args)
const {
262 return write<Char>(out, get_arg_checked<T, N>(args...));
266 template <
typename Char,
typename T,
int N>
270 template <
typename Char>
struct runtime_named_field {
274 template <
typename OutputIt,
typename T>
275 constexpr
static bool try_format_argument(
280 if (arg_name == arg.name) {
281 out = write<Char>(out, arg.value);
288 template <
typename OutputIt,
typename... Args>
289 constexpr OutputIt
format(OutputIt out,
const Args&... args)
const {
290 bool found = (try_format_argument(out, name, args) || ...);
292 throw format_error(
"argument with specified name is not found");
298 template <
typename Char>
299 struct is_compiled_format<runtime_named_field<Char>> :
std::true_type {};
302 template <
typename Char,
typename T,
int N>
struct spec_field {
306 template <
typename OutputIt,
typename... Args>
308 const Args&... args)
const {
310 fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...);
312 return fmt.format(get_arg_checked<T, N>(args...), ctx);
316 template <
typename Char,
typename T,
int N>
317 struct is_compiled_format<spec_field<Char, T, N>> :
std::true_type {};
319 template <
typename L,
typename R>
struct concat {
324 template <
typename OutputIt,
typename... Args>
325 constexpr OutputIt
format(OutputIt out,
const Args&... args)
const {
326 out = lhs.format(out, args...);
327 return rhs.format(out, args...);
331 template <
typename L,
typename R>
334 template <
typename L,
typename R>
335 constexpr concat<L, R> make_concat(L lhs, R rhs) {
339 struct unknown_format {};
341 template <
typename Char>
343 for (
size_t size = str.
size(); pos !=
size; ++pos) {
344 if (str[pos] ==
'{' || str[pos] ==
'}')
break;
349 template <
typename Args,
size_t POS,
int ID,
typename S>
350 constexpr
auto compile_format_string(
S format_str);
352 template <
typename Args,
size_t POS,
int ID,
typename T,
typename S>
353 constexpr
auto parse_tail(T head,
S format_str) {
356 constexpr
auto tail = compile_format_string<Args, POS, ID>(format_str);
361 return make_concat(head, tail);
367 template <
typename T,
typename Char>
struct parse_specs_result {
373 constexpr
int manual_indexing_id = -1;
375 template <
typename T,
typename Char>
377 size_t pos,
int next_arg_id) {
381 auto end = f.parse(ctx);
383 next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()};
386 template <
typename Char>
struct arg_id_handler {
389 constexpr
int operator()() {
390 FMT_ASSERT(
false,
"handler cannot be used with automatic indexing");
393 constexpr
int operator()(
int id) {
402 constexpr
void on_error(
const char* message) {
throw format_error(message); }
405 template <
typename Char>
struct parse_arg_id_result {
407 const Char* arg_id_end;
410 template <
int ID,
typename Char>
411 constexpr
auto parse_arg_id(
const Char* begin,
const Char* end) {
414 return parse_arg_id_result<Char>{handler.arg_id, arg_id_end};
417 template <
typename T,
typename Enable =
void>
struct field_type {
421 template <
typename T>
426 template <
typename T,
typename Args,
size_t END_POS,
int ARG_INDEX,
int NEXT_ID,
428 constexpr
auto parse_replacement_field_then_tail(
S format_str) {
432 if constexpr (c ==
'}') {
433 return parse_tail<Args, END_POS + 1, NEXT_ID>(
436 }
else if constexpr (c ==
':') {
438 str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID);
439 return parse_tail<Args, result.end, result.next_arg_id>(
448 template <
typename Args,
size_t POS,
int ID,
typename S>
449 constexpr
auto compile_format_string(
S format_str) {
452 if constexpr (str[
POS] ==
'{') {
453 if constexpr (
POS + 1 == str.size())
455 if constexpr (str[
POS + 1] ==
'{') {
456 return parse_tail<Args, POS + 2, ID>(make_text(str,
POS, 1), format_str);
457 }
else if constexpr (str[
POS + 1] ==
'}' || str[
POS + 1] ==
':') {
458 static_assert(ID != manual_indexing_id,
459 "cannot switch from manual to automatic argument indexing");
460 constexpr
auto next_id =
461 ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
462 return parse_replacement_field_then_tail<get_type<ID, Args>, Args,
463 POS + 1, ID, next_id>(
466 constexpr
auto arg_id_result =
467 parse_arg_id<ID>(str.data() +
POS + 1, str.data() + str.size());
468 constexpr
auto arg_id_end_pos = arg_id_result.arg_id_end - str.data();
470 arg_id_end_pos != str.size() ? str[arg_id_end_pos] :
char_type();
471 static_assert(c ==
'}' || c ==
':',
"missing '}' in format string");
474 ID == manual_indexing_id || ID == 0,
475 "cannot switch from automatic to manual argument indexing");
476 constexpr
auto arg_index = arg_id_result.arg_id.val.index;
477 return parse_replacement_field_then_tail<get_type<arg_index, Args>,
478 Args, arg_id_end_pos,
479 arg_index, manual_indexing_id>(
482 constexpr
auto arg_index =
485 constexpr
auto next_id =
486 ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
487 return parse_replacement_field_then_tail<
488 decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos,
489 arg_index, next_id>(format_str);
491 if constexpr (c ==
'}') {
492 return parse_tail<Args, arg_id_end_pos + 1, ID>(
493 runtime_named_field<char_type>{arg_id_result.arg_id.val.name},
495 }
else if constexpr (c ==
':') {
496 return unknown_format();
501 }
else if constexpr (str[
POS] ==
'}') {
502 if constexpr (
POS + 1 == str.size())
504 return parse_tail<Args, POS + 2, ID>(make_text(str,
POS, 1), format_str);
506 constexpr
auto end = parse_text(str,
POS + 1);
507 if constexpr (end -
POS > 1) {
508 return parse_tail<Args, end, ID>(make_text(str,
POS, end -
POS),
511 return parse_tail<Args, end, ID>(code_unit<char_type>{str[
POS]},
517 template <
typename... Args,
typename S,
519 constexpr
auto compile(S format_str) {
521 if constexpr (str.size() == 0) {
522 return detail::make_text(str, 0, 0);
525 detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
530 #endif // __cpp_if_constexpr 535 #ifdef __cpp_if_constexpr 537 template <
typename CompiledFormat,
typename... Args,
538 typename Char =
typename CompiledFormat::char_type,
539 FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
541 const Args&...
args) {
542 auto s = std::basic_string<Char>();
543 cf.format(std::back_inserter(
s), args...);
547 template <
typename OutputIt,
typename CompiledFormat,
typename... Args,
548 FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
550 const Args&...
args) {
551 return cf.format(out, args...);
554 template <
typename S,
typename... Args,
558 if constexpr (std::is_same<typename S::char_type, char>::value) {
560 if constexpr (str.size() == 2 && str[0] ==
'{' && str[1] ==
'}') {
562 if constexpr (detail::is_named_arg<
570 constexpr
auto compiled = detail::compile<Args...>(
S());
572 detail::unknown_format>()) {
574 std::forward<Args>(
args)...);
576 return format(compiled, std::forward<Args>(
args)...);
580 template <
typename OutputIt,
typename S,
typename... Args,
583 constexpr
auto compiled = detail::compile<Args...>(
S());
585 detail::unknown_format>()) {
588 std::forward<Args>(
args)...);
590 return format_to(out, compiled, std::forward<Args>(
args)...);
595 template <
typename OutputIt,
typename S,
typename... Args,
598 const S& format_str, Args&&...
args) {
600 std::forward<Args>(
args)...);
601 return {it.base(), it.count()};
604 template <
typename S,
typename... Args,
610 template <
typename S,
typename... Args,
612 void print(std::FILE* f,
const S& format_str,
const Args&...
args) {
614 format_to(std::back_inserter(buffer), format_str, args...);
618 template <
typename S,
typename... Args,
621 print(stdout, format_str, args...);
624 #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 626 template <detail_exported::fixed_
string Str>
627 constexpr detail::udl_compiled_string<
629 sizeof(Str.data) /
sizeof(decltype(Str.data[0])), Str>
639 #endif // FMT_COMPILE_H_ FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
#define FMT_MODULE_EXPORT_END
#define FMT_ENABLE_IF(...)
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
truncating_iterator & operator++()
value_type operator*() const
value_type & operator*() const
counting_iterator copy_str(InputIt begin, InputIt end, counting_iterator it)
typename truncating_iterator_base< OutputIt >::value_type value_type
truncating_iterator & operator++()
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
constexpr auto size() const -> size_t
truncating_iterator(OutputIt out, size_t limit)
constexpr int invalid_arg_index
#define FMT_END_NAMESPACE
truncating_iterator operator++(int)
counting_iterator & operator++()
constexpr auto data() const -> const Char *
counting_iterator operator++(int)
integral_constant< bool, false > false_type
void operator=(const T &)
FMT_FUNC void print(std::FILE *f, string_view text)
std::ptrdiff_t difference_type
truncating_iterator_base< OutputIt >::value_type blackhole_
integral_constant< bool, true > true_type
typename std::iterator_traits< OutputIt >::value_type value_type
std::ptrdiff_t difference_type
std::string to_string(const std::string &arg)
std::output_iterator_tag iterator_category
FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler) -> const Char *
auto format_to(OutputIt out, const text_style &ts, const S &format_str, Args &&... args) -> typename std::enable_if< enable, OutputIt >::type
static void field(LexState *ls, ConsControl *cc)
truncating_iterator_base()
FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view< Char > name) -> int
friend counting_iterator operator+(counting_iterator it, difference_type n)
truncating_iterator_base(OutputIt out, size_t limit)
const T & first(const T &value, const Tail &...)
remove_cvref_t< decltype(*detail::range_begin(std::declval< Range >()))> value_type
truncating_iterator & operator=(T val)
std::output_iterator_tag iterator_category
size_t formatted_size(const S &format_str, const Args &... args)
truncating_iterator & operator++(int)
span_constexpr std::size_t size(span< T, Extent > const &spn)
#define FMT_ASSERT(condition, message)
#define FMT_BEGIN_NAMESPACE
FMT_MODULE_EXPORT_BEGIN format_to_n_result< OutputIt > format_to_n(OutputIt out, size_t n, const S &format_str, Args &&... args)
truncating_iterator(OutputIt out, size_t limit)
#define FMT_MODULE_EXPORT_BEGIN
truncating_iterator & operator*()
FMT_CONSTEXPR void remove_prefix(size_t n)
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)