12# include <initializer_list>
15# include <type_traits>
21#if FMT_HAS_CPP_ATTRIBUTE(clang::lifetimebound)
22# define FMT_LIFETIMEBOUND [[clang::lifetimebound]]
24# define FMT_LIFETIMEBOUND
36 template <
typename U>
static auto check(U*) ->
typename U::mapped_type;
37 template <
typename>
static void check(...);
41 !std::is_void<decltype(check<T>(
nullptr))>
::value;
45 template <
typename U>
static auto check(U*) ->
typename U::key_type;
46 template <
typename>
static void check(...);
54template <
typename T,
size_t N>
58template <
typename T,
size_t N>
auto range_end(
const T (&arr)[N]) ->
const T* {
62template <
typename T,
typename Enable =
void>
67 decltype(std::declval<T>().end())>>
72auto range_begin(T&& rng) ->
decltype(
static_cast<T&&
>(rng).begin()) {
73 return static_cast<T&&
>(rng).begin();
76auto range_end(T&& rng) ->
decltype(
static_cast<T&&
>(rng).end()) {
77 return static_cast<T&&
>(rng).end();
85 decltype(begin(
static_cast<T&&
>(rng)))> {
86 return begin(
static_cast<T&&
>(rng));
90 decltype(end(
static_cast<T&&
>(rng)))> {
91 return end(
static_cast<T&&
>(rng));
94template <
typename T,
typename Enable =
void>
96template <
typename T,
typename Enable =
void>
113 int>> : std::true_type {};
115template <
typename T,
typename _ =
void>
struct is_range_ : std::false_type {};
118 : std::integral_constant<bool, (has_const_begin_end<T>::value ||
119 has_mutable_begin_end<T>::value)> {};
123 template <typename U, typename V = typename std::remove_cv<U>::type>
124 static auto check(U*
p) ->
decltype(std::tuple_size<V>::value, 0);
125 template <
typename>
static void check(...);
129 !std::is_void<decltype(check<T>(
nullptr))>
::value;
133#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900
134template <
typename T, T... N>
136template <
size_t... N>
using index_sequence = std::index_sequence<N...>;
147template <
typename T,
size_t N, T... Ns>
149template <
typename T, T... Ns>
159template <typename T, typename C, bool = is_tuple_like_<T>::value>
162 static constexpr bool value =
false;
165 template <
size_t... Is>
168 static auto all_true(...) -> std::false_type;
170 template <
size_t... Is>
182template <
typename Tuple,
typename F,
size_t... Is>
186 const int unused[] = {0, ((void)f(
get<Is>(t)), 0)...};
190template <
typename Tuple,
typename F>
193 std::forward<Tuple>(t), std::forward<F>(f));
196template <
typename Tuple1,
typename Tuple2,
typename F,
size_t... Is>
199 const int unused[] = {0, ((void)f(
get<Is>(t1),
get<Is>(t2)), 0)...};
203template <
typename Tuple1,
typename Tuple2,
typename F>
206 std::forward<Tuple1>(t1), std::forward<Tuple2>(t2),
212template <
typename Char,
typename... T>
213using result_t = std::tuple<formatter<remove_cvref_t<T>, Char>...>;
216template <
typename Tuple,
typename Char,
size_t... Is>
221#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920
223template <
typename R>
struct range_reference_type_impl {
227template <
typename T,
size_t N>
struct range_reference_type_impl<T[N]> {
234template <
typename Range>
241template <
typename Range>
246 : std::integral_constant<range_format,
247 std::is_same<uncvref_type<T>, T>::value
248 ? range_format::disabled
249 : is_map<T>::value ? range_format::map
250 : is_set<T>::value ? range_format::set
251 : range_format::sequence> {};
253template <range_format K>
267 template <
typename T>
270 ctx.advance_to(f.format(v,
ctx));
292template <
typename Tuple,
typename Char>
295 fmt::is_tuple_formattable<Tuple, Char>::value>> {
315 opening_bracket_ = open;
316 closing_bracket_ = close;
320 auto it = ctx.begin();
321 auto end = ctx.end();
327 if (it != end && *it !=
'}')
report_error(
"invalid format specifier");
333 template <
typename FormatContext>
334 auto format(
const Tuple& value, FormatContext& ctx)
const
335 ->
decltype(ctx.out()) {
345template <
typename T,
typename Char>
struct is_range {
352template <
typename Char,
typename Element>
359template <
typename R,
typename Char>
366template <
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);
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>
539 bool no_delimiters_ =
false;
545 auto it = ctx.begin();
546 auto end = ctx.end();
549 no_delimiters_ =
true;
552 if (it != end && *it !=
'}') {
553 if (*it !=
':')
report_error(
"invalid format specifier");
562 template <
typename FormatContext>
563 auto format(map_type&
map, FormatContext& ctx)
const ->
decltype(ctx.out()) {
564 auto out = ctx.out();
569 for (
auto&& value :
map) {
584template <
typename R,
typename Char>
603 return underlying_.parse(ctx);
606 template <
typename FormatContext>
607 auto format(range_type& range, FormatContext& ctx)
const
608 ->
decltype(ctx.out()) {
609 auto out = ctx.out();
613 out = underlying_.format(
622template <
typename It,
typename Sentinel,
typename Char =
char>
632template <
typename It,
typename Sentinel,
typename Char>
636#ifdef __cpp_lib_ranges
637 std::iter_value_t<It>;
639 typename std::iterator_traits<It>::value_type;
651 return value_formatter_.parse(ctx);
654 template <
typename FormatContext>
655 auto format(view& value, FormatContext& ctx)
const ->
decltype(ctx.out()) {
658 iter it = value.begin;
659 auto out = ctx.out();
660 if (it == value.end)
return out;
661 out = value_formatter_.format(*it, ctx);
663 while (it != value.end) {
666 out = value_formatter_.format(*it, ctx);
685#ifndef FMT_TUPLE_JOIN_SPECIFIERS
686# define FMT_TUPLE_JOIN_SPECIFIERS 0
689template <
typename Tuple,
typename Char>
693 return do_parse(ctx, std::tuple_size<Tuple>());
696 template <
typename FormatContext>
698 FormatContext& ctx)
const ->
typename FormatContext::iterator {
699 return do_format(value, ctx, std::tuple_size<Tuple>());
707 std::integral_constant<size_t, 0>)
714 std::integral_constant<size_t, N>)
716 auto end = ctx.begin();
717#if FMT_TUPLE_JOIN_SPECIFIERS
718 end = std::get<std::tuple_size<Tuple>::value - N>(formatters_).parse(ctx);
720 auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
722 report_error(
"incompatible format specs for tuple elements");
728 template <
typename FormatContext>
729 auto do_format(
const tuple_join_view<Tuple, Char>&, FormatContext& ctx,
730 std::integral_constant<size_t, 0>)
const ->
731 typename FormatContext::iterator {
735 template <
typename FormatContext,
size_t N>
736 auto do_format(
const tuple_join_view<Tuple, Char>& value, FormatContext& ctx,
737 std::integral_constant<size_t, N>)
const ->
738 typename FormatContext::iterator {
741 std::get<std::tuple_size<Tuple>::value - N>(formatters_)
742 .
format(
get<std::tuple_size<Tuple>::value - N>(value.tuple), ctx);
743 if (N <= 1)
return out;
746 return do_format(value, ctx, std::integral_constant<size_t, N - 1>());
754 template <
typename U>
static auto check(U*
p) ->
typename U::container_type;
755 template <
typename>
static void check(...);
759 !std::is_void<decltype(check<T>(
nullptr))>
::value;
762template <
typename Container>
struct all {
764 auto begin() const -> typename Container::const_iterator {
return c.begin(); }
765 auto end() const -> typename Container::const_iterator {
return c.end(); }
769template <
typename T,
typename Char>
774 range_format::disabled>>::value>>
775 :
formatter<detail::all<typename T::container_type>, Char> {
777 template <
typename FormatContext>
778 auto format(
const T& value, FormatContext& ctx)
const ->
decltype(ctx.out()) {
780 static auto get(
const T& v) ->
all {
781 return {v.*(&getter::c)};
792template <
typename It,
typename Sentinel>
794 return {std::move(begin), end, sep};
811template <
typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
827template <
typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
845 return join(std::begin(list), std::end(list), sep);
constexpr T & get(wpi::util::array< T, N > &arr) noexcept
Definition array.hpp:66
typename std::enable_if< B, T >::type enable_if_t
Definition base.h:307
#define FMT_END_EXPORT
Definition base.h:267
std::integral_constant< bool, B > bool_constant
Definition base.h:310
#define FMT_PRAGMA_CLANG(x)
Definition base.h:224
basic_string_view< char > string_view
Definition base.h:620
#define FMT_FALLTHROUGH
Definition base.h:188
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition base.h:316
#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:138
#define FMT_BEGIN_NAMESPACE
Definition base.h:256
#define FMT_ENABLE_IF(...)
Definition base.h:344
#define FMT_BEGIN_EXPORT
Definition base.h:266
void void_t
Definition base.h:331
typename std::conditional< B, T, F >::type conditional_t
Definition base.h:309
@ debug
Definition base.h:668
#define FMT_END_NAMESPACE
Definition base.h:259
#define FMT_EXPORT
Definition base.h:265
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:2797
A dynamically growing memory buffer for trivially copyable/constructible types with the first SIZE el...
Definition format.h:797
An implementation of std::basic_string_view for pre-C++17.
Definition base.h:522
static constexpr bool value
Definition ranges.h:758
static constexpr bool value
Definition ranges.h:40
static constexpr bool value
Definition ranges.h:49
static constexpr bool value
Definition ranges.h:128
Parsing context consisting of a format string range being parsed and an argument counter for automati...
Definition base.h:857
std::tuple< formatter< remove_cvref_t< T >, Char >... > result_t
Definition ranges.h:213
auto get_formatters(index_sequence< Is... >) -> result_t< Char, decltype(get< Is >(std::declval< Tuple >()))... >
Converts a string literal into a format string that will be parsed at compile time and converted into...
Definition printf.h:50
make_integer_sequence< size_t, N > make_index_sequence
Definition ranges.h:153
constexpr auto to_ascii(Char c) -> char
Definition base.h:1307
integer_sequence< size_t, N... > index_sequence
Definition ranges.h:145
remove_cvref_t< range_reference_type< Range > > uncvref_type
Definition ranges.h:242
FMT_CONSTEXPR void ignore_unused(const T &...)
Definition base.h:361
decltype(*detail::range_begin(std::declval< Range & >())) range_reference_type
Definition ranges.h:235
make_index_sequence< std::tuple_size< T >::value > tuple_index_sequence
Definition ranges.h:157
auto range_begin(const T(&arr)[N]) -> const T *
Definition ranges.h:55
FMT_CONSTEXPR void for_each(index_sequence< Is... >, Tuple &&t, F &&f)
Definition ranges.h:183
FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T
Definition base.h:380
conditional_t< has_const_begin_end< R >::value, const R, R > maybe_const_range
Definition ranges.h:356
FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt
Definition base.h:2083
auto range_end(const T(&arr)[N]) -> const T *
Definition ranges.h:58
void for_each2(index_sequence< Is... >, Tuple1 &&t1, Tuple2 &&t2, F &&f)
Definition ranges.h:197
formatter< remove_cvref_t< Element >, Char > range_formatter_type
Definition ranges.h:353
std::integral_constant< range_format, K > range_format_constant
Definition ranges.h:254
FMT_CONSTEXPR FMT_INLINE auto write(basic_appender< Char > out, T value, const format_specs &specs, locale_ref loc) -> basic_appender< Char >
Definition format.h:2137
type
Definition base.h:985
FMT_CONSTEXPR auto maybe_set_debug_format(Formatter &f, bool set) -> decltype(f.set_debug_format(set))
Definition format.h:767
Definition StringMap.hpp:773
range_format
Definition ranges.h:31
@ disabled
Definition ranges.h:31
@ map
Definition ranges.h:31
@ debug_string
Definition ranges.h:31
@ string
Definition ranges.h:31
@ set
Definition ranges.h:31
@ sequence
Definition ranges.h:31
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:793
#define FMT_LIFETIMEBOUND
Definition ranges.h:24
auto begin() const -> typename Container::const_iterator
Definition ranges.h:764
auto end() const -> typename Container::const_iterator
Definition ranges.h:765
const typename T::container_type & c
Definition ranges.h:763
static FMT_CONSTEXPR auto size() -> size_t
Definition ranges.h:142
T value_type
Definition ranges.h:140
parse_context< Char > & ctx
Definition ranges.h:262
FMT_CONSTEXPR void operator()(Formatter &f)
Definition ranges.h:258
static constexpr bool value
Definition ranges.h:346
static constexpr bool value
Definition ranges.h:283
It begin
Definition ranges.h:624
join_view(It b, Sentinel e, basic_string_view< Char > s)
Definition ranges.h:628
Sentinel end
Definition ranges.h:625
basic_string_view< Char > sep
Definition ranges.h:626
tuple_join_view(const Tuple &t, basic_string_view< Char > s)
Definition ranges.h:678
const Tuple & tuple
Definition ranges.h:675
basic_string_view< Char > sep
Definition ranges.h:676