12# include <initializer_list>
16# include <type_traits>
30 template <
typename U>
static auto check(U*) ->
typename U::mapped_type;
31 template <
typename>
static void check(...);
34 static constexpr const bool value =
35 !std::is_void<decltype(check<T>(
nullptr))>
::value;
39 template <
typename U>
static auto check(U*) ->
typename U::key_type;
40 template <
typename>
static void check(...);
43 static constexpr const bool value =
48template <
typename T, std::
size_t N>
52template <
typename T, std::
size_t N>
57template <
typename T,
typename Enable =
void>
62 decltype(std::declval<T>().end())>>
67auto range_begin(T&& rng) ->
decltype(
static_cast<T&&
>(rng).begin()) {
68 return static_cast<T&&
>(rng).begin();
71auto range_end(T&& rng) ->
decltype(
static_cast<T&&
>(rng).end()) {
72 return static_cast<T&&
>(rng).end();
80 decltype(begin(
static_cast<T&&
>(rng)))> {
81 return begin(
static_cast<T&&
>(rng));
85 decltype(end(
static_cast<T&&
>(rng)))> {
86 return end(
static_cast<T&&
>(rng));
89template <
typename T,
typename Enable =
void>
91template <
typename T,
typename Enable =
void>
108 int>> : std::true_type {};
110template <
typename T,
typename _ =
void>
struct is_range_ : std::false_type {};
113 : std::integral_constant<bool, (has_const_begin_end<T>::value ||
114 has_mutable_begin_end<T>::value)> {};
118 template <typename U, typename V = typename std::remove_cv<U>::type>
119 static auto check(U* p) ->
decltype(std::tuple_size<V>::value, 0);
120 template <
typename>
static void check(...);
124 !std::is_void<decltype(check<T>(
nullptr))>
::value;
128#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900
129template <
typename T, T... N>
131template <
size_t... N>
using index_sequence = std::index_sequence<N...>;
142template <
typename T,
size_t N, T... Ns>
144template <
typename T, T... Ns>
154template <typename T, typename C, bool = is_tuple_like_<T>::value>
157 static constexpr const bool value =
false;
160 template <
size_t... Is>
163 static auto all_true(...) -> std::false_type;
165 template <
size_t... Is>
177template <
typename Tuple,
typename F,
size_t... Is>
181 const int unused[] = {0, ((void)f(get<Is>(t)), 0)...};
185template <
typename Tuple,
typename F>
188 std::forward<Tuple>(t), std::forward<F>(f));
191template <
typename Tuple1,
typename Tuple2,
typename F,
size_t... Is>
194 const int unused[] = {0, ((void)f(get<Is>(t1), get<Is>(t2)), 0)...};
198template <
typename Tuple1,
typename Tuple2,
typename F>
201 std::forward<Tuple1>(t1), std::forward<Tuple2>(t2),
207template <
typename Char,
typename... T>
208using result_t = std::tuple<formatter<remove_cvref_t<T>, Char>...>;
211template <
typename Tuple,
typename Char, std::size_t... Is>
216#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920
218template <
typename R>
struct range_reference_type_impl {
222template <
typename T, std::
size_t N>
struct range_reference_type_impl<T[N]> {
229template <
typename Range>
236template <
typename Range>
239template <
typename Formatter>
241 ->
decltype(f.set_debug_format(
set)) {
242 f.set_debug_format(
set);
244template <
typename Formatter>
249 : std::integral_constant<range_format,
250 std::is_same<uncvref_type<T>, T>::value
251 ? range_format::disabled
252 : is_map<T>::value ? range_format::map
253 : is_set<T>::value ? range_format::set
254 : range_format::sequence> {};
256template <range_format K>
270 template <
typename T>
273 ctx.advance_to(f.format(v,
ctx));
294template <
typename Tuple,
typename Char>
297 fmt::is_tuple_formattable<Tuple, Char>::value>> {
317 opening_bracket_ = open;
318 closing_bracket_ = close;
322 auto it = ctx.begin();
323 auto end = ctx.end();
326 set_brackets({}, {});
329 if (it != end && *it !=
'}')
report_error(
"invalid format specifier");
335 template <
typename FormatContext>
336 auto format(
const Tuple& value, FormatContext& ctx)
const
337 ->
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>
371template <
typename T,
typename Char,
typename Enable =
void>
374template <
typename T,
typename Char>
386 bool is_debug =
false;
388 template <
typename Output,
typename It,
typename Sentinel,
typename U = T,
390 auto write_debug_string(Output& out, It it, Sentinel end)
const -> Output {
392 for (; it != end; ++it) buf.push_back(*it);
399 template <
typename Output,
typename It,
typename Sentinel,
typename U = T,
401 auto write_debug_string(Output& out, It, Sentinel)
const -> Output {
418 opening_bracket_ = open;
419 closing_bracket_ = close;
423 auto it = ctx.begin();
424 auto end = ctx.end();
426 if (it == end)
return underlying_.parse(ctx);
430 set_brackets({}, {});
435 set_brackets({}, {});
437 if (it == end || *it !=
's')
report_error(
"invalid format specifier");
440 if (!std::is_same<T, Char>::value)
452 if (it != end && *it !=
'}') {
453 if (*it !=
':')
report_error(
"invalid format specifier");
459 return underlying_.parse(ctx);
462 template <
typename R,
typename FormatContext>
463 auto format(R&& range, FormatContext& ctx)
const ->
decltype(ctx.out()) {
464 auto out = ctx.out();
467 if (is_debug)
return write_debug_string(out, std::move(it), end);
471 for (; it != end; ++it) {
475 out = underlying_.format(item, ctx);
484template <
typename T,
typename Char,
typename Enable =
void>
487 is_range<T, Char>::value, detail::range_format_kind_<T>,
488 std::integral_constant<range_format, range_format::disabled>> {};
490template <
typename R,
typename Char>
516 return range_formatter_.parse(ctx);
519 template <
typename FormatContext>
520 auto format(range_type& range, FormatContext& ctx)
const
521 ->
decltype(ctx.out()) {
522 return range_formatter_.format(range, ctx);
527template <
typename R,
typename Char>
537 bool no_delimiters_ =
false;
543 auto it = ctx.begin();
544 auto end = ctx.end();
547 no_delimiters_ =
true;
550 if (it != end && *it !=
'}') {
551 if (*it !=
':')
report_error(
"invalid format specifier");
560 template <
typename FormatContext>
561 auto format(map_type&
map, FormatContext& ctx)
const ->
decltype(ctx.out()) {
562 auto out = ctx.out();
567 for (
auto&& value :
map) {
582template <
typename R,
typename Char>
601 return underlying_.parse(ctx);
604 template <
typename FormatContext>
605 auto format(range_type& range, FormatContext& ctx)
const
606 ->
decltype(ctx.out()) {
607 auto out = ctx.out();
611 out = underlying_.format(
620template <
typename It,
typename Sentinel,
typename Char =
char>
627 : begin(
std::move(b)), end(e),
sep(s) {}
630template <
typename It,
typename Sentinel,
typename Char>
634#ifdef __cpp_lib_ranges
635 std::iter_value_t<It>;
637 typename std::iterator_traits<It>::value_type;
649 return value_formatter_.parse(ctx);
652 template <
typename FormatContext>
653 auto format(view& value, FormatContext& ctx)
const ->
decltype(ctx.out()) {
656 iter it = value.begin;
657 auto out = ctx.out();
658 if (it == value.end)
return out;
659 out = value_formatter_.format(*it, ctx);
661 while (it != value.end) {
664 out = value_formatter_.format(*it, ctx);
682#ifndef FMT_TUPLE_JOIN_SPECIFIERS
683# define FMT_TUPLE_JOIN_SPECIFIERS 0
686template <
typename Char,
typename Tuple>
690 return do_parse(ctx, std::tuple_size<Tuple>());
693 template <
typename FormatContext>
695 FormatContext& ctx)
const ->
typename FormatContext::iterator {
696 return do_format(value, ctx, std::tuple_size<Tuple>());
704 std::integral_constant<size_t, 0>)
711 std::integral_constant<size_t, N>)
713 auto end = ctx.begin();
714#if FMT_TUPLE_JOIN_SPECIFIERS
715 end = std::get<std::tuple_size<Tuple>::value - N>(formatters_).parse(ctx);
717 auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
719 report_error(
"incompatible format specs for tuple elements");
725 template <
typename FormatContext>
727 std::integral_constant<size_t, 0>)
const ->
728 typename FormatContext::iterator {
732 template <
typename FormatContext,
size_t N>
734 std::integral_constant<size_t, N>)
const ->
735 typename FormatContext::iterator {
738 std::get<std::tuple_size<Tuple>::value - N>(formatters_)
739 .
format(get<std::tuple_size<Tuple>::value - N>(
value.tuple), ctx);
740 if (N <= 1)
return out;
743 return do_format(value, ctx, std::integral_constant<size_t, N - 1>());
751 template <
typename U>
static auto check(U* p) ->
typename U::container_type;
752 template <
typename>
static void check(...);
756 !std::is_void<decltype(check<T>(
nullptr))>
::value;
759template <
typename Container>
struct all {
761 auto begin() const -> typename Container::const_iterator {
return c.begin(); }
762 auto end() const -> typename Container::const_iterator {
return c.end(); }
766template <
typename T,
typename Char>
771 range_format::disabled>>::value>>
772 :
formatter<detail::all<typename T::container_type>, Char> {
774 template <
typename FormatContext>
775 auto format(
const T& t, FormatContext& ctx)
const ->
decltype(ctx.out()) {
777 static auto get(
const T& t) ->
all {
778 return {t.*(&getter::c)};
789template <
typename It,
typename Sentinel>
791 return {std::move(begin), end, sep};
808template <
typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
824template <
typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
842 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:790
An implementation of std::basic_string_view for pre-C++17.
Definition base.h:504
static constexpr const bool value
Definition ranges.h:755
static constexpr const bool value
Definition ranges.h:34
static constexpr const bool value
Definition ranges.h:43
static constexpr const bool value
Definition ranges.h:123
Parsing context consisting of a format string range being parsed and an argument counter for automati...
Definition base.h:845
std::tuple< formatter< remove_cvref_t< T >, Char >... > result_t
Definition ranges.h:208
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:1242
remove_cvref_t< range_reference_type< Range > > uncvref_type
Definition ranges.h:237
FMT_CONSTEXPR void ignore_unused(const T &...)
Definition base.h:348
decltype(*detail::range_begin(std::declval< Range & >())) range_reference_type
Definition ranges.h:230
FMT_CONSTEXPR auto write(OutputIt out, Char value, const format_specs &specs, locale_ref loc={}) -> OutputIt
Definition format.h:1824
auto range_begin(const T(&arr)[N]) -> const T *
Definition ranges.h:49
@ value
the parser finished reading a JSON value
FMT_CONSTEXPR void for_each(index_sequence< Is... >, Tuple &&t, F &&f)
Definition ranges.h:178
FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T
Definition base.h:367
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:1992
auto range_end(const T(&arr)[N]) -> const T *
Definition ranges.h:53
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:192
std::integral_constant< range_format, K > range_format_constant
Definition ranges.h:257
type
Definition base.h:937
FMT_CONSTEXPR auto maybe_set_debug_format(Formatter &f, bool set) -> decltype(f.set_debug_format(set))
Definition ranges.h:240
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
range_format
Definition ranges.h:25
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:790
auto begin() const -> typename Container::const_iterator
Definition ranges.h:761
auto end() const -> typename Container::const_iterator
Definition ranges.h:762
const Container & c
Definition ranges.h:760
Definition cpp_future.h:66
static FMT_CONSTEXPR auto size() -> size_t
Definition ranges.h:137
T value_type
Definition ranges.h:135
parse_context< Char > & ctx
Definition ranges.h:265
FMT_CONSTEXPR void operator()(Formatter &f)
Definition ranges.h:261
static constexpr const bool value
Definition ranges.h:347
static constexpr const bool value
Definition ranges.h:285
It begin
Definition ranges.h:622
join_view(It b, Sentinel e, basic_string_view< Char > s)
Definition ranges.h:626
Sentinel end
Definition ranges.h:623
basic_string_view< Char > sep
Definition ranges.h:624
const Tuple & tuple
Definition ranges.h:672
basic_string_view< Char > sep
Definition ranges.h:673
tuple_join_view(const Tuple &t, basic_string_view< Char > s)
Definition ranges.h:675
typename std::enable_if< B, T >::type enable_if_t
Definition base.h:297
#define FMT_END_EXPORT
Definition base.h:250
std::integral_constant< bool, B > bool_constant
Definition base.h:300
#define FMT_FALLTHROUGH
Definition base.h:172
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition base.h:306
#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:239
#define FMT_ENABLE_IF(...)
Definition base.h:334
#define FMT_BEGIN_EXPORT
Definition base.h:249
typename std::conditional< B, T, F >::type conditional_t
Definition base.h:299
#define FMT_END_NAMESPACE
Definition base.h:242
#define FMT_EXPORT
Definition base.h:248
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:2723