12# include <initializer_list>
15# include <type_traits>
29 template <
typename U>
static auto check(U*) ->
typename U::mapped_type;
30 template <
typename>
static void check(...);
34 !std::is_void<decltype(check<T>(
nullptr))>
::value;
38 template <
typename U>
static auto check(U*) ->
typename U::key_type;
39 template <
typename>
static void check(...);
47template <
typename T,
size_t N>
51template <
typename T,
size_t N>
auto range_end(
const T (&arr)[N]) ->
const T* {
55template <
typename T,
typename Enable =
void>
60 decltype(std::declval<T>().end())>>
65auto range_begin(T&& rng) ->
decltype(
static_cast<T&&
>(rng).begin()) {
66 return static_cast<T&&
>(rng).begin();
69auto range_end(T&& rng) ->
decltype(
static_cast<T&&
>(rng).end()) {
70 return static_cast<T&&
>(rng).end();
78 decltype(begin(
static_cast<T&&
>(rng)))> {
79 return begin(
static_cast<T&&
>(rng));
83 decltype(end(
static_cast<T&&
>(rng)))> {
84 return end(
static_cast<T&&
>(rng));
87template <
typename T,
typename Enable =
void>
89template <
typename T,
typename Enable =
void>
106 int>> : std::true_type {};
108template <
typename T,
typename _ =
void>
struct is_range_ : std::false_type {};
111 : std::integral_constant<bool, (has_const_begin_end<T>::value ||
112 has_mutable_begin_end<T>::value)> {};
116 template <typename U, typename V = typename std::remove_cv<U>::type>
117 static auto check(U* p) ->
decltype(std::tuple_size<V>::value, 0);
118 template <
typename>
static void check(...);
122 !std::is_void<decltype(check<T>(
nullptr))>
::value;
126#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900
127template <
typename T, T... N>
129template <
size_t... N>
using index_sequence = std::index_sequence<N...>;
140template <
typename T,
size_t N, T... Ns>
142template <
typename T, T... Ns>
152template <typename T, typename C, bool = is_tuple_like_<T>::value>
155 static constexpr bool value =
false;
158 template <
size_t... Is>
161 static auto all_true(...) -> std::false_type;
163 template <
size_t... Is>
175template <
typename Tuple,
typename F,
size_t... Is>
179 const int unused[] = {0, ((void)f(get<Is>(t)), 0)...};
183template <
typename Tuple,
typename F>
186 std::forward<Tuple>(t), std::forward<F>(f));
189template <
typename Tuple1,
typename Tuple2,
typename F,
size_t... Is>
192 const int unused[] = {0, ((void)f(get<Is>(t1), get<Is>(t2)), 0)...};
196template <
typename Tuple1,
typename Tuple2,
typename F>
199 std::forward<Tuple1>(t1), std::forward<Tuple2>(t2),
205template <
typename Char,
typename... T>
206using result_t = std::tuple<formatter<remove_cvref_t<T>, Char>...>;
209template <
typename Tuple,
typename Char,
size_t... Is>
214#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920
216template <
typename R>
struct range_reference_type_impl {
220template <
typename T,
size_t N>
struct range_reference_type_impl<T[N]> {
227template <
typename Range>
234template <
typename Range>
237template <
typename Formatter>
239 ->
decltype(f.set_debug_format(
set)) {
240 f.set_debug_format(
set);
242template <
typename Formatter>
247 : std::integral_constant<range_format,
248 std::is_same<uncvref_type<T>, T>::value
249 ? range_format::disabled
250 : is_map<T>::value ? range_format::map
251 : is_set<T>::value ? range_format::set
252 : range_format::sequence> {};
254template <range_format K>
268 template <
typename T>
271 ctx.advance_to(f.format(v,
ctx));
293template <
typename Tuple,
typename Char>
296 fmt::is_tuple_formattable<Tuple, Char>::value>> {
316 opening_bracket_ = open;
317 closing_bracket_ = close;
321 auto it = ctx.begin();
322 auto end = ctx.end();
325 set_brackets({}, {});
328 if (it != end && *it !=
'}')
report_error(
"invalid format specifier");
334 template <
typename FormatContext>
335 auto format(
const Tuple& value, FormatContext& ctx)
const
336 ->
decltype(ctx.out()) {
346template <
typename T,
typename Char>
struct is_range {
353template <
typename Char,
typename Element>
360template <
typename R,
typename Char>
367template <
typename P1,
typename... Pn>
372template <
typename T,
typename Char,
typename Enable =
void>
375template <
typename T,
typename Char>
387 bool is_debug =
false;
389 template <
typename Output,
typename It,
typename Sentinel,
typename U = T,
391 auto write_debug_string(Output& out, It it, Sentinel end)
const -> Output {
393 for (; it != end; ++it) buf.push_back(*it);
400 template <
typename Output,
typename It,
typename Sentinel,
typename U = T,
402 auto write_debug_string(Output& out, It, Sentinel)
const -> Output {
419 opening_bracket_ = open;
420 closing_bracket_ = close;
424 auto it = ctx.begin();
425 auto end = ctx.end();
427 if (it == end)
return underlying_.parse(ctx);
431 set_brackets({}, {});
436 set_brackets({}, {});
438 if (it == end || *it !=
's')
report_error(
"invalid format specifier");
441 if (!std::is_same<T, Char>::value)
453 if (it != end && *it !=
'}') {
454 if (*it !=
':')
report_error(
"invalid format specifier");
460 return underlying_.parse(ctx);
463 template <
typename R,
typename FormatContext>
464 auto format(R&& range, FormatContext& ctx)
const ->
decltype(ctx.out()) {
465 auto out = ctx.out();
468 if (is_debug)
return write_debug_string(out, std::move(it), end);
472 for (; it != end; ++it) {
476 out = underlying_.format(item, ctx);
485template <
typename T,
typename Char,
typename Enable =
void>
488 is_range<T, Char>::value, detail::range_format_kind_<T>,
489 std::integral_constant<range_format, range_format::disabled>> {};
491template <
typename R,
typename Char>
517 return range_formatter_.parse(ctx);
520 template <
typename FormatContext>
521 auto format(range_type& range, FormatContext& ctx)
const
522 ->
decltype(ctx.out()) {
523 return range_formatter_.format(range, ctx);
528template <
typename R,
typename Char>
540 bool no_delimiters_ =
false;
546 auto it = ctx.begin();
547 auto end = ctx.end();
550 no_delimiters_ =
true;
553 if (it != end && *it !=
'}') {
554 if (*it !=
':')
report_error(
"invalid format specifier");
563 template <
typename FormatContext>
564 auto format(map_type&
map, FormatContext& ctx)
const ->
decltype(ctx.out()) {
565 auto out = ctx.out();
570 for (
auto&& value :
map) {
585template <
typename R,
typename Char>
604 return underlying_.parse(ctx);
607 template <
typename FormatContext>
608 auto format(range_type& range, FormatContext& ctx)
const
609 ->
decltype(ctx.out()) {
610 auto out = ctx.out();
614 out = underlying_.format(
623template <
typename It,
typename Sentinel,
typename Char =
char>
630 : begin(
std::move(b)), end(e),
sep(s) {}
633template <
typename It,
typename Sentinel,
typename Char>
637#ifdef __cpp_lib_ranges
638 std::iter_value_t<It>;
640 typename std::iterator_traits<It>::value_type;
652 return value_formatter_.parse(ctx);
655 template <
typename FormatContext>
656 auto format(view& value, FormatContext& ctx)
const ->
decltype(ctx.out()) {
659 iter it = value.begin;
660 auto out = ctx.out();
661 if (it == value.end)
return out;
662 out = value_formatter_.format(*it, ctx);
664 while (it != value.end) {
667 out = value_formatter_.format(*it, ctx);
686#ifndef FMT_TUPLE_JOIN_SPECIFIERS
687# define FMT_TUPLE_JOIN_SPECIFIERS 0
690template <
typename Tuple,
typename Char>
694 return do_parse(ctx, std::tuple_size<Tuple>());
697 template <
typename FormatContext>
699 FormatContext& ctx)
const ->
typename FormatContext::iterator {
700 return do_format(value, ctx, std::tuple_size<Tuple>());
708 std::integral_constant<size_t, 0>)
715 std::integral_constant<size_t, N>)
717 auto end = ctx.begin();
718#if FMT_TUPLE_JOIN_SPECIFIERS
719 end = std::get<std::tuple_size<Tuple>::value - N>(formatters_).parse(ctx);
721 auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
723 report_error(
"incompatible format specs for tuple elements");
729 template <
typename FormatContext>
731 std::integral_constant<size_t, 0>)
const ->
732 typename FormatContext::iterator {
736 template <
typename FormatContext,
size_t N>
738 std::integral_constant<size_t, N>)
const ->
739 typename FormatContext::iterator {
742 std::get<std::tuple_size<Tuple>::value - N>(formatters_)
743 .
format(get<std::tuple_size<Tuple>::value - N>(
value.tuple), ctx);
744 if (N <= 1)
return out;
747 return do_format(value, ctx, std::integral_constant<size_t, N - 1>());
755 template <
typename U>
static auto check(U* p) ->
typename U::container_type;
756 template <
typename>
static void check(...);
760 !std::is_void<decltype(check<T>(
nullptr))>
::value;
763template <
typename Container>
struct all {
765 auto begin() const -> typename Container::const_iterator {
return c.begin(); }
766 auto end() const -> typename Container::const_iterator {
return c.end(); }
770template <
typename T,
typename Char>
775 range_format::disabled>>::value>>
776 :
formatter<detail::all<typename T::container_type>, Char> {
778 template <
typename FormatContext>
779 auto format(
const T& value, FormatContext& ctx)
const ->
decltype(ctx.out()) {
781 static auto get(
const T& v) ->
all {
782 return {v.*(&getter::c)};
793template <
typename It,
typename Sentinel>
795 return {std::move(begin), end, sep};
812template <
typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
828template <
typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
846 return join(std::begin(list), std::end(list), sep);
constexpr T & get(wpi::array< T, N > &arr) noexcept
Definition array.h:66
A dynamically growing memory buffer for trivially copyable/constructible types with the first SIZE el...
Definition format.h:774
An implementation of std::basic_string_view for pre-C++17.
Definition base.h:518
static constexpr bool value
Definition ranges.h:759
static constexpr bool value
Definition ranges.h:33
static constexpr bool value
Definition ranges.h:42
static constexpr bool value
Definition ranges.h:121
Parsing context consisting of a format string range being parsed and an argument counter for automati...
Definition base.h:866
std::tuple< formatter< remove_cvref_t< T >, Char >... > result_t
Definition ranges.h:206
auto get_formatters(index_sequence< Is... >) -> result_t< Char, decltype(get< Is >(std::declval< Tuple >()))... >
detail namespace with internal helper functions
Definition input_adapters.h:32
constexpr auto to_ascii(Char c) -> char
Definition base.h:1280
remove_cvref_t< range_reference_type< Range > > uncvref_type
Definition ranges.h:235
FMT_CONSTEXPR void ignore_unused(const T &...)
Definition base.h:363
decltype(*detail::range_begin(std::declval< Range & >())) range_reference_type
Definition ranges.h:228
FMT_CONSTEXPR auto write(OutputIt out, Char value, const format_specs &specs, locale_ref loc={}) -> OutputIt
Definition format.h:1815
auto range_begin(const T(&arr)[N]) -> const T *
Definition ranges.h:48
@ value
the parser finished reading a JSON value
FMT_CONSTEXPR void for_each(index_sequence< Is... >, Tuple &&t, F &&f)
Definition ranges.h:176
FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T
Definition base.h:382
conditional_t< has_const_begin_end< R >::value, const R, R > maybe_const_range
Definition ranges.h:357
FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt
Definition base.h:2051
auto range_end(const T(&arr)[N]) -> const T *
Definition ranges.h:51
typename make_void< Ts... >::type void_t
Definition void_t.h:21
void for_each2(index_sequence< Is... >, Tuple1 &&t1, Tuple2 &&t2, F &&f)
Definition ranges.h:190
std::integral_constant< range_format, K > range_format_constant
Definition ranges.h:255
type
Definition base.h:958
FMT_CONSTEXPR auto maybe_set_debug_format(Formatter &f, bool set) -> decltype(f.set_debug_format(set))
Definition ranges.h:238
Definition PointerIntPair.h:280
range_format
Definition ranges.h:24
FMT_BEGIN_EXPORT auto join(It begin, Sentinel end, string_view sep) -> join_view< It, Sentinel >
Returns a view that formats the iterator range [begin, end) with elements separated by sep.
Definition ranges.h:794
auto begin() const -> typename Container::const_iterator
Definition ranges.h:765
auto end() const -> typename Container::const_iterator
Definition ranges.h:766
const Container & c
Definition ranges.h:764
Definition cpp_future.h:66
static FMT_CONSTEXPR auto size() -> size_t
Definition ranges.h:135
T value_type
Definition ranges.h:133
parse_context< Char > & ctx
Definition ranges.h:263
FMT_CONSTEXPR void operator()(Formatter &f)
Definition ranges.h:259
static constexpr bool value
Definition ranges.h:347
static constexpr bool value
Definition ranges.h:284
It begin
Definition ranges.h:625
join_view(It b, Sentinel e, basic_string_view< Char > s)
Definition ranges.h:629
Sentinel end
Definition ranges.h:626
basic_string_view< Char > sep
Definition ranges.h:627
tuple_join_view(const Tuple &t, basic_string_view< Char > s)
Definition ranges.h:679
const Tuple & tuple
Definition ranges.h:676
basic_string_view< Char > sep
Definition ranges.h:677
typename std::enable_if< B, T >::type enable_if_t
Definition base.h:312
#define FMT_END_EXPORT
Definition base.h:272
std::integral_constant< bool, B > bool_constant
Definition base.h:315
#define FMT_FALLTHROUGH
Definition base.h:186
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition base.h:321
#define FMT_CONSTEXPR
Definition base.h:113
FMT_NORETURN FMT_API void report_error(const char *message)
Reports a format error at compile time or, via a format_error exception, at runtime.
Definition format-inl.h:135
#define FMT_BEGIN_NAMESPACE
Definition base.h:261
#define FMT_ENABLE_IF(...)
Definition base.h:349
#define FMT_BEGIN_EXPORT
Definition base.h:271
typename std::conditional< B, T, F >::type conditional_t
Definition base.h:314
#define FMT_END_NAMESPACE
Definition base.h:264
#define FMT_EXPORT
Definition base.h:270
bool_constant<!std::is_same< detail::mapped_t< conditional_t< std::is_void< T >::value, int *, T >, Char >, void >::value > is_formattable
Definition base.h:2792