Photon 1.0.0
Loading...
Searching...
No Matches
ranges.h
Go to the documentation of this file.
1// Formatting library for C++ - experimental range support
2//
3// Copyright (c) 2012 - present, Victor Zverovich
4// All rights reserved.
5//
6// For the license information refer to format.h.
7//
8// Copyright (c) 2018 - present, Remotion (Igor Schulz)
9// All Rights Reserved
10// {fmt} support for ranges, containers and types tuple interface.
11
12#ifndef FMT_RANGES_H_
13#define FMT_RANGES_H_
14
15#include <initializer_list>
16#include <tuple>
17#include <type_traits>
18
19#include "format.h"
20
22
23namespace detail
24{
25
26 template <typename RangeT, typename OutputIterator>
27 OutputIterator copy(const RangeT& range, OutputIterator out)
28 {
29 for (auto it = range.begin(), end = range.end(); it != end; ++it)
30 *out++ = *it;
31 return out;
32 }
33
34 template <typename OutputIterator>
35 OutputIterator copy(const char* str, OutputIterator out)
36 {
37 while (*str)
38 *out++ = *str++;
39 return out;
40 }
41
42 template <typename OutputIterator>
43 OutputIterator copy(char ch, OutputIterator out)
44 {
45 *out++ = ch;
46 return out;
47 }
48
49 template <typename OutputIterator>
50 OutputIterator copy(wchar_t ch, OutputIterator out)
51 {
52 *out++ = ch;
53 return out;
54 }
55
56 // Returns true if T has a std::string-like interface, like std::string_view.
57 template <typename T>
59 {
60 template <typename U>
61 static auto check(U* p)
62 -> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
63 template <typename>
64 static void check(...);
65
66 public:
67 static constexpr const bool value =
69 std::is_convertible<T, std_string_view<char>>::value ||
70 !std::is_void<decltype(check<T>(nullptr))>::value;
71 };
72
73 template <typename Char>
74 struct is_std_string_like<fmt::basic_string_view<Char>> : std::true_type
75 {
76 };
77
78 template <typename T>
79 class is_map
80 {
81 template <typename U>
82 static auto check(U*) -> typename U::mapped_type;
83 template <typename>
84 static void check(...);
85
86 public:
87#ifdef FMT_FORMAT_MAP_AS_LIST
88 static constexpr const bool value = false;
89#else
90 static constexpr const bool value =
91 !std::is_void<decltype(check<T>(nullptr))>::value;
92#endif
93 };
94
95 template <typename T>
96 class is_set
97 {
98 template <typename U>
99 static auto check(U*) -> typename U::key_type;
100 template <typename>
101 static void check(...);
102
103 public:
104#ifdef FMT_FORMAT_SET_AS_LIST
105 static constexpr const bool value = false;
106#else
107 static constexpr const bool value =
108 !std::is_void<decltype(check<T>(nullptr))>::value && !is_map<T>::value;
109#endif
110 };
111
112 template <typename... Ts>
114 {
115 };
116
117 template <typename T, typename _ = void>
118 struct is_range_ : std::false_type
119 {
120 };
121
122#if !FMT_MSC_VERSION || FMT_MSC_VERSION > 1800
123
124#define FMT_DECLTYPE_RETURN(val) \
125 ->decltype(val) \
126 { \
127 return val; \
128 } \
129 static_assert( \
130 true, "") // This makes it so that a semicolon is required after the
131 // macro, which helps clang-format handle the formatting.
132
133 // C array overload
134 template <typename T, std::size_t N>
135 auto range_begin(const T (&arr)[N]) -> const T*
136 {
137 return arr;
138 }
139 template <typename T, std::size_t N>
140 auto range_end(const T (&arr)[N]) -> const T*
141 {
142 return arr + N;
143 }
144
145 template <typename T, typename Enable = void>
146 struct has_member_fn_begin_end_t : std::false_type
147 {
148 };
149
150 template <typename T>
151 struct has_member_fn_begin_end_t<T, void_t<decltype(std::declval<T>().begin()), decltype(std::declval<T>().end())>>
152 : std::true_type
153 {
154 };
155
156 // Member function overload
157 template <typename T>
158 auto range_begin(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).begin());
159 template <typename T>
160 auto range_end(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).end());
161
162 // ADL overload. Only participates in overload resolution if member functions
163 // are not found.
164 template <typename T>
165 auto range_begin(T&& rng)
167 decltype(begin(static_cast<T&&>(rng)))>
168 {
169 return begin(static_cast<T&&>(rng));
170 }
171 template <typename T>
173 decltype(end(static_cast<T&&>(rng)))>
174 {
175 return end(static_cast<T&&>(rng));
176 }
177
178 template <typename T, typename Enable = void>
179 struct has_const_begin_end : std::false_type
180 {
181 };
182 template <typename T, typename Enable = void>
183 struct has_mutable_begin_end : std::false_type
184 {
185 };
186
187 template <typename T>
189 T,
190 void_t<
191 decltype(detail::range_begin(std::declval<const remove_cvref_t<T>&>())),
192 decltype(detail::range_end(std::declval<const remove_cvref_t<T>&>()))>>
193 : std::true_type
194 {
195 };
196
197 template <typename T>
199 T,
200 void_t<decltype(detail::range_begin(std::declval<T>())),
201 decltype(detail::range_end(std::declval<T>())),
202 enable_if_t<std::is_copy_constructible<T>::value>>>
203 : std::true_type
204 {
205 };
206
207 template <typename T>
208 struct is_range_<T, void>
209 : std::integral_constant<bool, (has_const_begin_end<T>::value || has_mutable_begin_end<T>::value)>
210 {
211 };
212#undef FMT_DECLTYPE_RETURN
213#endif
214
215 // tuple_size and tuple_element check.
216 template <typename T>
218 {
219 template <typename U>
220 static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
221 template <typename>
222 static void check(...);
223
224 public:
225 static constexpr const bool value =
226 !std::is_void<decltype(check<T>(nullptr))>::value;
227 };
228
229// Check for integer_sequence
230#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900
231 template <typename T, T... N>
232 using integer_sequence = std::integer_sequence<T, N...>;
233 template <size_t... N>
234 using index_sequence = std::index_sequence<N...>;
235 template <size_t N>
236 using make_index_sequence = std::make_index_sequence<N>;
237#else
238 template <typename T, T... N>
240 {
241 using value_type = T;
242
243 static FMT_CONSTEXPR size_t size()
244 {
245 return sizeof...(N);
246 }
247 };
248
249 template <size_t... N>
250 using index_sequence = integer_sequence<size_t, N...>;
251
252 template <typename T, size_t N, T... Ns>
253 struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...>
254 {
255 };
256 template <typename T, T... Ns>
257 struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...>
258 {
259 };
260
261 template <size_t N>
263#endif
264
265 template <typename T>
267
268 template <typename T, typename C, bool = is_tuple_like_<T>::value>
270 {
271 public:
272 static constexpr const bool value = false;
273 };
274 template <typename T, typename C>
275 class is_tuple_formattable_<T, C, true>
276 {
277 template <std::size_t... I>
278 static std::true_type check2(index_sequence<I...>,
279 integer_sequence<bool, (I == I)...>);
280 static std::false_type check2(...);
281 template <std::size_t... I>
282 static decltype(check2(
285 bool,
287 C>::value)...>{})) check(index_sequence<I...>);
288
289 public:
290 static constexpr const bool value =
291 decltype(check(tuple_index_sequence<T>{}))::value;
292 };
293
294 template <class Tuple, class F, size_t... Is>
295 void for_each(index_sequence<Is...>, Tuple&& tup, F&& f) noexcept
296 {
297 using std::get;
298 // using free function get<I>(T) now.
299 const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
300 (void)_; // blocks warnings
301 }
302
303 template <class T>
309
310 template <class Tuple, class F>
311 void for_each(Tuple&& tup, F&& f)
312 {
313 const auto indexes = get_indexes(tup);
314 for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
315 }
316
317#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920
318 // Older MSVC doesn't get the reference type correctly for arrays.
319 template <typename R>
320 struct range_reference_type_impl
321 {
322 using type = decltype(*detail::range_begin(std::declval<R&>()));
323 };
324
325 template <typename T, std::size_t N>
326 struct range_reference_type_impl<T[N]>
327 {
328 using type = T&;
329 };
330
331 template <typename T>
332 using range_reference_type = typename range_reference_type_impl<T>::type;
333#else
334 template <typename Range>
336 decltype(*detail::range_begin(std::declval<Range&>()));
337#endif
338
339 // We don't use the Range's value_type for anything, but we do need the Range's
340 // reference type, with cv-ref stripped.
341 template <typename Range>
343
344 template <typename Range>
346 remove_cvref_t<decltype(std::declval<range_reference_type<Range>>().first)>;
347
348 template <typename Range>
350 decltype(std::declval<range_reference_type<Range>>().second)>;
351
352 template <typename OutputIt>
353 OutputIt write_delimiter(OutputIt out)
354 {
355 *out++ = ',';
356 *out++ = ' ';
357 return out;
358 }
359
360 template <typename Char, typename OutputIt>
361 auto write_range_entry(OutputIt out, basic_string_view<Char> str) -> OutputIt
362 {
363 return write_escaped_string(out, str);
364 }
365
366 template <typename Char, typename OutputIt, typename T, FMT_ENABLE_IF(std::is_convertible<T, std_string_view<char>>::value)>
367 inline auto write_range_entry(OutputIt out, const T& str) -> OutputIt
368 {
369 auto sv = std_string_view<Char>(str);
370 return write_range_entry<Char>(out, basic_string_view<Char>(sv));
371 }
372
373 template <typename Char, typename OutputIt, typename Arg, FMT_ENABLE_IF(std::is_same<Arg, Char>::value)>
374 OutputIt write_range_entry(OutputIt out, const Arg v)
375 {
376 return write_escaped_char(out, v);
377 }
378
379 template <
380 typename Char,
381 typename OutputIt,
382 typename Arg,
383 FMT_ENABLE_IF(!is_std_string_like<typename std::decay<Arg>::type>::value &&
384 !std::is_same<Arg, Char>::value)>
385 OutputIt write_range_entry(OutputIt out, const Arg& v)
386 {
387 return write<Char>(out, v);
388 }
389
390} // namespace detail
391
392template <typename T>
394{
395 static constexpr const bool value =
397};
398
399template <typename T, typename C>
401{
402 static constexpr const bool value =
404};
405
406template <typename TupleT, typename Char>
407struct formatter<TupleT, Char, enable_if_t<fmt::is_tuple_like<TupleT>::value && fmt::is_tuple_formattable<TupleT, Char>::value>>
408{
409private:
410 basic_string_view<Char> separator_ = detail::string_literal<Char, ',', ' '>{};
411 basic_string_view<Char> opening_bracket_ =
412 detail::string_literal<Char, '('>{};
413 basic_string_view<Char> closing_bracket_ =
414 detail::string_literal<Char, ')'>{};
415
416 // C++11 generic lambda for format().
417 template <typename FormatContext>
418 struct format_each
419 {
420 template <typename T>
421 void operator()(const T& v)
422 {
423 if (i > 0)
424 out = detail::copy_str<Char>(separator, out);
425 out = detail::write_range_entry<Char>(out, v);
426 ++i;
427 }
428 int i;
429 typename FormatContext::iterator& out;
431 };
432
433public:
437
439 {
440 separator_ = sep;
441 }
442
445 {
446 opening_bracket_ = open;
447 closing_bracket_ = close;
448 }
449
450 template <typename ParseContext>
451 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin())
452 {
453 return ctx.begin();
454 }
455
456 template <typename FormatContext = format_context>
457 auto format(const TupleT& values, FormatContext& ctx) const
458 -> decltype(ctx.out())
459 {
460 auto out = ctx.out();
461 out = detail::copy_str<Char>(opening_bracket_, out);
462 detail::for_each(values, format_each<FormatContext>{0, out, separator_});
463 out = detail::copy_str<Char>(closing_bracket_, out);
464 return out;
465 }
466};
467
468template <typename T, typename Char>
470{
471 static constexpr const bool value =
473 !std::is_convertible<T, std::basic_string<Char>>::value &&
474 !std::is_convertible<T, detail::std_string_view<Char>>::value;
475};
476
477namespace detail
478{
479 template <typename Context>
481 {
483
484 template <typename T,
486 static auto map(T&& value) -> T&&
487 {
488 return static_cast<T&&>(value);
489 }
490 template <typename T,
492 static auto map(T&& value)
493 -> decltype(mapper().map(static_cast<T&&>(value)))
494 {
495 return mapper().map(static_cast<T&&>(value));
496 }
497 };
498
499 template <typename Char, typename Element>
503 std::declval<Element>()))>,
504 Char>,
506
507 template <typename R>
510
511// Workaround a bug in MSVC 2015 and earlier.
512#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
513 template <typename R, typename Char>
515 : disjunction<
516 is_formattable<uncvref_type<maybe_const_range<R>>, Char>,
517 has_fallback_formatter<uncvref_type<maybe_const_range<R>>, Char>>
518 {
519 };
520#endif
521
522} // namespace detail
523
524template <typename T, typename Char, typename Enable = void>
526
527template <typename T, typename Char>
529 T,
530 Char,
532 std::is_same<T, remove_cvref_t<T>>,
533 disjunction<is_formattable<T, Char>,
534 detail::has_fallback_formatter<T, Char>>>::value>>
535{
536private:
538 bool custom_specs_ = false;
539 basic_string_view<Char> separator_ = detail::string_literal<Char, ',', ' '>{};
540 basic_string_view<Char> opening_bracket_ =
541 detail::string_literal<Char, '['>{};
542 basic_string_view<Char> closing_bracket_ =
543 detail::string_literal<Char, ']'>{};
544
545 template <class U>
547 -> decltype(u.set_debug_format())
548 {
549 u.set_debug_format();
550 }
551
552 template <class U>
554 {
555 }
556
558 {
559 maybe_set_debug_format(underlying_, 0);
560 }
561
562public:
566
568 {
569 return underlying_;
570 }
571
573 {
574 separator_ = sep;
575 }
576
579 {
580 opening_bracket_ = open;
581 closing_bracket_ = close;
582 }
583
584 template <typename ParseContext>
585 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin())
586 {
587 auto it = ctx.begin();
588 auto end = ctx.end();
589 if (it == end || *it == '}')
590 {
591 maybe_set_debug_format();
592 return it;
593 }
594
595 if (*it == 'n')
596 {
597 set_brackets({}, {});
598 ++it;
599 }
600
601 if (*it == '}')
602 {
603 maybe_set_debug_format();
604 return it;
605 }
606
607 if (*it != ':')
608 FMT_THROW(format_error("no other top-level range formatters supported"));
609
610 custom_specs_ = true;
611 ++it;
612 ctx.advance_to(it);
613 return underlying_.parse(ctx);
614 }
615
616 template <typename R, class FormatContext>
617 auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out())
618 {
620 auto out = ctx.out();
621 out = detail::copy_str<Char>(opening_bracket_, out);
622 int i = 0;
623 auto it = detail::range_begin(range);
624 auto end = detail::range_end(range);
625 for (; it != end; ++it)
626 {
627 if (i > 0)
628 out = detail::copy_str<Char>(separator_, out);
629 ;
630 ctx.advance_to(out);
631 out = underlying_.format(mapper.map(*it), ctx);
632 ++i;
633 }
634 out = detail::copy_str<Char>(closing_bracket_, out);
635 return out;
636 }
637};
638
639enum class range_format
640{
641 disabled,
642 map,
643 set,
644 sequence,
645 string,
647};
648
649namespace detail
650{
651 template <typename T>
653 {
654 static constexpr auto value = std::is_same<range_reference_type<T>, T>::value
659 };
660
661 template <range_format K, typename R, typename Char, typename Enable = void>
663
664 template <range_format K>
665 using range_format_constant = std::integral_constant<range_format, K>;
666
667 template <range_format K, typename R, typename Char>
669 K,
670 R,
671 Char,
673 K == range_format::set)>>
674 {
677
682
684 {
685 underlying_.set_brackets(detail::string_literal<Char, '{'>{},
686 detail::string_literal<Char, '}'>{});
687 }
688
690 {
691 underlying_.set_brackets(detail::string_literal<Char, '{'>{},
692 detail::string_literal<Char, '}'>{});
693 underlying_.underlying().set_brackets({}, {});
694 underlying_.underlying().set_separator(
695 detail::string_literal<Char, ':', ' '>{});
696 }
697
701
702 template <typename ParseContext>
703 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin())
704 {
705 return underlying_.parse(ctx);
706 }
707
708 template <typename FormatContext>
709 auto format(range_type& range, FormatContext& ctx) const
710 -> decltype(ctx.out())
711 {
712 return underlying_.format(range, ctx);
713 }
714 };
715} // namespace detail
716
717template <typename T, typename Char, typename Enable = void>
720 is_range<T, Char>::value,
721 detail::range_format_kind_<T>,
722 std::integral_constant<range_format, range_format::disabled>>
723{
724};
725
726template <typename R, typename Char>
728 R,
729 Char,
732// Workaround a bug in MSVC 2015 and earlier.
733#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
734 ,
736#endif
737 >::value>>
738 : detail::range_default_formatter<range_format_kind<R, Char>::value, R, Char>
739{
740};
741
742template <typename Char, typename... T>
743struct tuple_join_view : detail::view
744{
745 const std::tuple<T...>& tuple;
747
748 tuple_join_view(const std::tuple<T...>& t, basic_string_view<Char> s)
749 : tuple(t), sep{s}
750 {
751 }
752};
753
754template <typename Char, typename... T>
755using tuple_arg_join = tuple_join_view<Char, T...>;
756
757// Define FMT_TUPLE_JOIN_SPECIFIERS to enable experimental format specifiers
758// support in tuple_join. It is disabled by default because of issues with
759// the dynamic width and precision.
760#ifndef FMT_TUPLE_JOIN_SPECIFIERS
761#define FMT_TUPLE_JOIN_SPECIFIERS 0
762#endif
763
764template <typename Char, typename... T>
765struct formatter<tuple_join_view<Char, T...>, Char>
766{
767 template <typename ParseContext>
768 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin())
769 {
770 return do_parse(ctx, std::integral_constant<size_t, sizeof...(T)>());
771 }
772
773 template <typename FormatContext>
775 FormatContext& ctx) const -> typename FormatContext::iterator
776 {
777 return do_format(value, ctx,
778 std::integral_constant<size_t, sizeof...(T)>());
779 }
780
781private:
782 std::tuple<formatter<typename std::decay<T>::type, Char>...> formatters_;
783
784 template <typename ParseContext>
785 FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
786 std::integral_constant<size_t, 0>)
787 -> decltype(ctx.begin())
788 {
789 return ctx.begin();
790 }
791
792 template <typename ParseContext, size_t N>
793 FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
794 std::integral_constant<size_t, N>)
795 -> decltype(ctx.begin())
796 {
797 auto end = ctx.begin();
798#if FMT_TUPLE_JOIN_SPECIFIERS
799 end = std::get<sizeof...(T) - N>(formatters_).parse(ctx);
800 if (N > 1)
801 {
802 auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
803 if (end != end1)
804 FMT_THROW(format_error("incompatible format specs for tuple elements"));
805 }
806#endif
807 return end;
808 }
809
810 template <typename FormatContext>
811 auto do_format(const tuple_join_view<Char, T...>&, FormatContext& ctx, std::integral_constant<size_t, 0>) const ->
812 typename FormatContext::iterator
813 {
814 return ctx.out();
815 }
816
817 template <typename FormatContext, size_t N>
818 auto do_format(const tuple_join_view<Char, T...>& value, FormatContext& ctx, std::integral_constant<size_t, N>) const ->
819 typename FormatContext::iterator
820 {
821 auto out = std::get<sizeof...(T) - N>(formatters_)
822 .format(std::get<sizeof...(T) - N>(value.tuple), ctx);
823 if (N > 1)
824 {
825 out = std::copy(value.sep.begin(), value.sep.end(), out);
826 ctx.advance_to(out);
827 return do_format(value, ctx, std::integral_constant<size_t, N - 1>());
828 }
829 return out;
830 }
831};
832
834
846template <typename... T>
847FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
848 -> tuple_join_view<char, T...>
849{
850 return {tuple, sep};
851}
852
853template <typename... T>
854FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple,
856 -> tuple_join_view<wchar_t, T...>
857{
858 return {tuple, sep};
859}
860
872template <typename T>
873auto join(std::initializer_list<T> list, string_view sep)
875{
876 return join(std::begin(list), std::end(list), sep);
877}
878
881
882#endif // FMT_RANGES_H_
range_format
Definition ranges.h:640
#define FMT_DECLTYPE_RETURN(val)
Definition ranges.h:124
tuple_join_view< Char, T... > tuple_arg_join
Definition ranges.h:755
FMT_MODULE_EXPORT_BEGIN FMT_CONSTEXPR auto join(const std::tuple< T... > &tuple, string_view sep) -> tuple_join_view< char, T... >
Definition ranges.h:847
Definition core.h:483
Definition ranges.h:80
static auto check(U *) -> typename U::mapped_type
static void check(...)
Definition ranges.h:97
static auto check(U *) -> typename U::key_type
static void check(...)
Definition ranges.h:59
static void check(...)
static auto check(U *p) -> decltype((void) p->find('a'), p->length(),(void) p->data(), int())
static std::true_type check2(index_sequence< I... >, integer_sequence< bool,(I==I)... >)
static std::false_type check2(...)
Definition ranges.h:270
static constexpr const bool value
Definition ranges.h:272
Definition ranges.h:218
static void check(...)
static auto check(U *p) -> decltype(std::tuple_size< U >::value, int())
Definition format.h:1113
Definition core.h:1598
typename std::enable_if< B, T >::type enable_if_t
Definition core.h:302
std::integral_constant< bool, B > bool_constant
Definition core.h:306
#define FMT_MODULE_EXPORT_BEGIN
Definition core.h:226
#define FMT_CONSTEXPR
Definition core.h:106
std::is_constructible< typename Context::template formatter_type< T > > has_formatter
Definition core.h:953
type
Definition core.h:681
bool_constant< !std::is_base_of< detail::unformattable, decltype(detail::arg_mapper< buffer_context< Char > >().map(std::declval< T >()))>::value &&!detail::has_fallback_formatter< T, Char >::value > is_formattable
Definition core.h:2427
#define FMT_BEGIN_NAMESPACE
Definition core.h:214
#define FMT_ENABLE_IF(...)
Definition core.h:364
void void_t
Definition core.h:2201
typename std::conditional< B, T, F >::type conditional_t
Definition core.h:304
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition core.h:312
#define FMT_END_NAMESPACE
Definition core.h:219
#define FMT_MODULE_EXPORT_END
Definition core.h:227
#define out
Definition encodings.cpp:5
auto write_escaped_string(OutputIt out, basic_string_view< Char > str) -> OutputIt
Definition format.h:2223
auto write_escaped_char(OutputIt out, Char v) -> OutputIt
Definition format.h:2242
#define FMT_THROW(x)
Definition format.h:99
Definition args.h:20
OutputIt write_delimiter(OutputIt out)
Definition ranges.h:353
void for_each(index_sequence< Is... >, Tuple &&tup, F &&f) noexcept
Definition ranges.h:295
auto range_begin(const T(&arr)[N]) -> const T *
Definition ranges.h:135
remove_cvref_t< decltype(std::declval< range_reference_type< Range > >().first)> uncvref_first_type
Definition ranges.h:346
FMT_CONSTEXPR make_index_sequence< std::tuple_size< T >::value > get_indexes(T const &)
Definition ranges.h:304
OutputIterator copy(const RangeT &range, OutputIterator out)
Definition ranges.h:27
const T & first(const T &value, const Tail &...)
Definition compile.h:179
make_integer_sequence< size_t, N > make_index_sequence
Definition ranges.h:262
remove_cvref_t< range_reference_type< Range > > uncvref_type
Definition ranges.h:342
auto range_end(const T(&arr)[N]) -> const T *
Definition ranges.h:140
conditional_t< has_const_begin_end< R >::value, const R, R > maybe_const_range
Definition ranges.h:509
auto write_range_entry(OutputIt out, basic_string_view< Char > str) -> OutputIt
Definition ranges.h:361
integer_sequence< size_t, N... > index_sequence
Definition ranges.h:250
std::integral_constant< range_format, K > range_format_constant
Definition ranges.h:665
make_index_sequence< std::tuple_size< T >::value > tuple_index_sequence
Definition ranges.h:266
decltype(*detail::range_begin(std::declval< Range & >())) range_reference_type
Definition ranges.h:336
remove_cvref_t< decltype(std::declval< range_reference_type< Range > >().second)> uncvref_second_type
Definition ranges.h:350
conditional_t< is_formattable< Element, Char >::value, formatter< remove_cvref_t< decltype(range_mapper< buffer_context< Char > >{}.map(std::declval< Element >()))>, Char >, fallback_formatter< Element, Char > > range_formatter_type
Definition ranges.h:505
Definition bin_to_hex.h:111
Definition uuid.h:926
Definition core.h:1760
Definition core.h:339
Definition ranges.h:114
Definition ranges.h:180
Definition ranges.h:147
Definition ranges.h:184
Definition ranges.h:240
static FMT_CONSTEXPR size_t size()
Definition ranges.h:243
T value_type
Definition ranges.h:241
Definition ranges.h:518
Definition ranges.h:119
Definition ranges.h:254
FMT_CONSTEXPR void init(range_format_constant< range_format::sequence >)
Definition ranges.h:698
auto format(range_type &range, FormatContext &ctx) const -> decltype(ctx.out())
Definition ranges.h:709
Definition ranges.h:662
Definition ranges.h:653
Definition ranges.h:481
arg_mapper< Context > mapper
Definition ranges.h:482
static auto map(T &&value) -> decltype(mapper().map(static_cast< T && >(value)))
Definition ranges.h:492
static auto map(T &&value) -> T &&
Definition ranges.h:486
Definition format.h:269
Definition core.h:325
Definition core.h:1420
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition ranges.h:451
auto format(const TupleT &values, FormatContext &ctx) const -> decltype(ctx.out())
Definition ranges.h:457
FMT_CONSTEXPR void set_brackets(basic_string_view< Char > open, basic_string_view< Char > close)
Definition ranges.h:443
std::tuple< formatter< typename std::decay< T >::type, Char >... > formatters_
Definition ranges.h:782
auto do_format(const tuple_join_view< Char, T... > &value, FormatContext &ctx, std::integral_constant< size_t, N >) const -> typename FormatContext::iterator
Definition ranges.h:818
auto format(const tuple_join_view< Char, T... > &value, FormatContext &ctx) const -> typename FormatContext::iterator
Definition ranges.h:774
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition ranges.h:768
FMT_CONSTEXPR auto do_parse(ParseContext &ctx, std::integral_constant< size_t, N >) -> decltype(ctx.begin())
Definition ranges.h:793
FMT_CONSTEXPR auto do_parse(ParseContext &ctx, std::integral_constant< size_t, 0 >) -> decltype(ctx.begin())
Definition ranges.h:785
auto do_format(const tuple_join_view< Char, T... > &, FormatContext &ctx, std::integral_constant< size_t, 0 >) const -> typename FormatContext::iterator
Definition ranges.h:811
Definition core.h:944
Definition ranges.h:470
static constexpr const bool value
Definition ranges.h:471
Definition core.h:666
Definition ranges.h:401
Definition ranges.h:394
Definition format.h:4709
Definition ranges.h:723
Definition ranges.h:525
Definition core.h:419
Definition ranges.h:744
tuple_join_view(const std::tuple< T... > &t, basic_string_view< Char > s)
Definition ranges.h:748
const std::tuple< T... > & tuple
Definition ranges.h:745
basic_string_view< Char > sep
Definition ranges.h:746
s
Definition tag_strings.h:47
u
Definition tag_strings.h:62
i
Definition tag_strings.h:60
p
Definition tag_strings.h:29