15#include <initializer_list>
25template <
typename Range,
typename OutputIt>
26auto copy(
const Range& range, OutputIt out) -> OutputIt {
27 for (
auto it = range.begin(), end = range.end(); it != end; ++it)
32template <
typename OutputIt>
33auto copy(
const char* str, OutputIt out) -> OutputIt {
34 while (*str) *out++ = *str++;
38template <
typename OutputIt>
auto copy(
char ch, OutputIt out) -> OutputIt {
43template <
typename OutputIt>
auto copy(
wchar_t ch, OutputIt out) -> OutputIt {
51 static auto check(U* p)
52 ->
decltype((void)p->find(
'a'), p->length(), (void)p->data(), int());
53 template <
typename>
static void check(...);
56 static constexpr const bool value =
58 std::is_convertible<T, std_string_view<char>>
::value ||
59 !std::is_void<decltype(check<T>(
nullptr))>
::value;
62template <
typename Char>
66 template <
typename U>
static auto check(U*) ->
typename U::mapped_type;
67 template <
typename>
static void check(...);
70#ifdef FMT_FORMAT_MAP_AS_LIST
71 static constexpr const bool value =
false;
73 static constexpr const bool value =
74 !std::is_void<decltype(check<T>(
nullptr))>
::value;
79 template <
typename U>
static auto check(U*) ->
typename U::key_type;
80 template <
typename>
static void check(...);
83#ifdef FMT_FORMAT_SET_AS_LIST
84 static constexpr const bool value =
false;
86 static constexpr const bool value =
93template <
typename T,
typename _ =
void>
struct is_range_ : std::false_type {};
95#if !FMT_MSC_VERSION || FMT_MSC_VERSION > 1800
97# define FMT_DECLTYPE_RETURN(val) \
98 ->decltype(val) { return val; } \
104template <
typename T, std::
size_t N>
108template <
typename T, std::
size_t N>
113template <
typename T,
typename Enable =
void>
118 decltype(std::declval<T>().end())>>
132 decltype(begin(
static_cast<T&&
>(rng)))> {
133 return begin(
static_cast<T&&
>(rng));
137 decltype(end(
static_cast<T&&
>(rng)))> {
138 return end(
static_cast<T&&
>(rng));
141template <
typename T,
typename Enable =
void>
143template <
typename T,
typename Enable =
void>
151 decltype(detail::range_end(std::declval<const remove_cvref_t<T>&>()))>>
157 decltype(detail::range_end(std::declval<T>())),
160 int>> : std::true_type {};
164 : std::integral_constant<bool, (has_const_begin_end<T>::value ||
165 has_mutable_begin_end<T>::value)> {};
166# undef FMT_DECLTYPE_RETURN
171 template <
typename U>
172 static auto check(U* p) ->
decltype(std::tuple_size<U>::value, int());
173 template <
typename>
static void check(...);
177 !std::is_void<decltype(check<T>(
nullptr))>
::value;
181#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900
182template <
typename T, T... N>
195template <
typename T,
size_t N, T... Ns>
197template <
typename T, T... Ns>
207template <typename T, typename C, bool = is_tuple_like_<T>::value>
210 static constexpr const bool value =
false;
213 template <std::size_t... Is>
216 static std::false_type check2(...);
217 template <std::size_t... Is>
218 static decltype(check2(
229template <
typename Tuple,
typename F,
size_t... Is>
233 const int unused[] = {0, ((void)f(get<Is>(t)), 0)...};
237template <
typename Tuple,
typename F>
240 std::forward<Tuple>(t), std::forward<F>(f));
243template <
typename Tuple1,
typename Tuple2,
typename F,
size_t... Is>
246 const int unused[] = {0, ((void)f(get<Is>(t1), get<Is>(t2)), 0)...};
250template <
typename Tuple1,
typename Tuple2,
typename F>
253 std::forward<Tuple1>(t1), std::forward<Tuple2>(t2),
259template <
typename Char,
typename... T>
260using result_t = std::tuple<formatter<remove_cvref_t<T>, Char>...>;
263template <
typename Tuple,
typename Char, std::size_t... Is>
268#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920
270template <
typename R>
struct range_reference_type_impl {
274template <
typename T, std::
size_t N>
struct range_reference_type_impl<T[N]> {
281template <
typename Range>
288template <
typename Range>
291template <
typename Formatter>
293 ->
decltype(f.set_debug_format(
set)) {
294 f.set_debug_format(
set);
296template <
typename Formatter>
310 template <
typename T>
314 ctx.advance_to(f.format(v,
ctx));
335template <
typename Tuple,
typename Char>
338 fmt::is_tuple_formattable<Tuple, Char>::value>> {
340 decltype(detail::tuple::get_formatters<Tuple, Char>(
358 opening_bracket_ = open;
359 closing_bracket_ = close;
362 template <
typename ParseContext>
364 auto it = ctx.begin();
365 if (it != ctx.end() && *it !=
'}')
366 FMT_THROW(format_error(
"invalid format specifier"));
371 template <
typename FormatContext>
372 auto format(
const Tuple& value, FormatContext& ctx)
const
373 ->
decltype(ctx.out()) {
374 ctx.advance_to(detail::copy_str<Char>(opening_bracket_, ctx.out()));
378 return detail::copy_str<Char>(closing_bracket_, ctx.out());
382template <
typename T,
typename Char>
struct is_range {
385 !std::is_convertible<T, std::basic_string<Char>>
::value &&
386 !std::is_convertible<T, detail::std_string_view<Char>>
::value;
393 template <
typename T,
396 return static_cast<T&&
>(
value);
398 template <
typename T,
401 ->
decltype(
mapper().map(
static_cast<T&&
>(
value))) {
406template <
typename Char,
typename Element>
409 std::declval<Element>()))>,
417#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
418template <
typename R,
typename Char>
424template <
typename T,
typename Char,
typename Enable =
void>
427template <
typename T,
typename Char>
453 opening_bracket_ = open;
454 closing_bracket_ = close;
457 template <
typename ParseContext>
459 auto it = ctx.begin();
460 auto end = ctx.end();
462 if (it != end && *it ==
'n') {
463 set_brackets({}, {});
467 if (it != end && *it !=
'}') {
468 if (*it !=
':')
FMT_THROW(format_error(
"invalid format specifier"));
475 return underlying_.parse(ctx);
478 template <
typename R,
typename FormatContext>
479 auto format(
R&& range, FormatContext& ctx)
const ->
decltype(ctx.out()) {
481 auto out = ctx.out();
482 out = detail::copy_str<Char>(opening_bracket_, out);
486 for (; it != end; ++it) {
487 if (i > 0) out = detail::copy_str<Char>(separator_, out);
489 out = underlying_.format(mapper.
map(*it), ctx);
492 out = detail::copy_str<Char>(closing_bracket_, out);
502 : std::integral_constant<range_format,
503 std::is_same<uncvref_type<T>, T>::value
504 ? range_format::disabled
505 : is_map<T>::value ? range_format::map
506 : is_set<T>::value ? range_format::set
507 : range_format::sequence> {};
509template <range_format K,
typename R,
typename Char,
typename Enable =
void>
512template <range_format K>
515template <range_format K,
typename R,
typename Char>
533 underlying_.underlying().set_brackets({}, {});
534 underlying_.underlying().set_separator(
540 template <
typename ParseContext>
542 return underlying_.parse(ctx);
545 template <
typename FormatContext>
547 ->
decltype(ctx.out()) {
548 return underlying_.format(range, ctx);
553template <
typename T,
typename Char,
typename Enable =
void>
556 is_range<T, Char>::value, detail::range_format_kind_<T>,
557 std::integral_constant<range_format, range_format::disabled>> {};
559template <
typename R,
typename Char>
565#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
585#ifndef FMT_TUPLE_JOIN_SPECIFIERS
586# define FMT_TUPLE_JOIN_SPECIFIERS 0
589template <
typename Char,
typename... T>
591 template <
typename ParseContext>
593 return do_parse(ctx, std::integral_constant<
size_t,
sizeof...(T)>());
596 template <
typename FormatContext>
598 FormatContext& ctx)
const ->
typename FormatContext::iterator {
599 return do_format(value, ctx,
600 std::integral_constant<
size_t,
sizeof...(T)>());
606 template <
typename ParseContext>
608 std::integral_constant<size_t, 0>)
609 ->
decltype(ctx.begin()) {
613 template <
typename ParseContext,
size_t N>
615 std::integral_constant<size_t, N>)
616 ->
decltype(ctx.begin()) {
617 auto end = ctx.begin();
618#if FMT_TUPLE_JOIN_SPECIFIERS
619 end =
std::get<
sizeof...(T) - N>(formatters_).parse(ctx);
621 auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
623 FMT_THROW(format_error(
"incompatible format specs for tuple elements"));
629 template <
typename FormatContext>
631 std::integral_constant<size_t, 0>)
const ->
632 typename FormatContext::iterator {
636 template <
typename FormatContext,
size_t N>
638 std::integral_constant<size_t, N>)
const ->
639 typename FormatContext::iterator {
640 auto out =
std::get<
sizeof...(T) - N>(formatters_)
645 return do_format(value, ctx, std::integral_constant<size_t, N - 1>());
655 template <
typename U>
static auto check(U* p) ->
typename U::container_type;
656 template <
typename>
static void check(...);
660 !std::is_void<decltype(check<T>(
nullptr))>
::value;
663template <
typename Container>
struct all {
665 auto begin() const -> typename Container::const_iterator {
return c.begin(); }
666 auto end() const -> typename Container::const_iterator {
return c.end(); }
670template <
typename T,
typename Char>
675 range_format::disabled>>::value>>
676 :
formatter<detail::all<typename T::container_type>, Char> {
678 template <
typename FormatContext>
679 auto format(
const T& t, FormatContext& ctx)
const ->
decltype(ctx.out()) {
681 static auto get(
const T& t) ->
all {
702template <
typename... T>
708template <
typename... T>
729 return join(std::begin(list), std::end(list), sep);
constexpr T & get(wpi::array< T, N > &arr) noexcept
Definition: array.h:66
An implementation of std::basic_string_view for pre-C++17.
Definition: core.h:398
static constexpr const bool value
Definition: ranges.h:659
static constexpr const bool value
Definition: ranges.h:73
static constexpr const bool value
Definition: ranges.h:86
static constexpr const bool value
Definition: ranges.h:56
static constexpr const bool value
Definition: ranges.h:176
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:256
#define FMT_END_EXPORT
Definition: core.h:185
std::integral_constant< bool, B > bool_constant
Definition: core.h:259
#define FMT_CONSTEXPR
Definition: core.h:105
std::is_constructible< typename Context::template formatter_type< T > > has_formatter
Definition: core.h:1077
#define FMT_BEGIN_NAMESPACE
Definition: core.h:174
#define FMT_ENABLE_IF(...)
Definition: core.h:286
#define FMT_BEGIN_EXPORT
Definition: core.h:184
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:258
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition: core.h:265
#define FMT_END_NAMESPACE
Definition: core.h:177
bool_constant<!std::is_base_of< detail::unformattable, decltype(detail::arg_mapper< buffer_context< Char > >() .map(std::declval< T & >()))>::value > is_formattable
Definition: core.h:1764
auto get_formatters(index_sequence< Is... >) -> result_t< Char, decltype(get< Is >(std::declval< Tuple >()))... >
std::tuple< formatter< remove_cvref_t< T >, Char >... > result_t
Definition: ranges.h:260
detail namespace with internal helper functions
Definition: xchar.h:20
void void_t
Definition: core.h:1510
auto copy(const Range &range, OutputIt out) -> OutputIt
Definition: ranges.h:26
FMT_CONSTEXPR void ignore_unused(const T &...)
Definition: core.h:302
auto range_begin(const T(&arr)[N]) -> const T *
Definition: ranges.h:105
auto copy(wchar_t ch, OutputIt out) -> OutputIt
Definition: ranges.h:43
@ value
the parser finished reading a JSON value
integer_sequence< size_t, N... > index_sequence
Definition: ranges.h:193
FMT_CONSTEXPR void for_each(index_sequence< Is... >, Tuple &&t, F &&f)
Definition: ranges.h:230
typename std::enable_if< B, T >::type enable_if_t
Definition: cpp_future.h:38
remove_cvref_t< range_reference_type< Range > > uncvref_type
Definition: ranges.h:289
auto range_end(const T(&arr)[N]) -> const T *
Definition: ranges.h:109
conditional_t< has_const_begin_end< R >::value, const R, R > maybe_const_range
Definition: ranges.h:414
void for_each2(index_sequence< Is... >, Tuple1 &&t1, Tuple2 &&t2, F &&f)
Definition: ranges.h:244
constexpr auto set(type rhs) -> int
Definition: core.h:610
std::integral_constant< range_format, K > range_format_constant
Definition: ranges.h:513
type
Definition: core.h:556
decltype(*detail::range_begin(std::declval< Range & >())) range_reference_type
Definition: ranges.h:283
FMT_CONSTEXPR auto maybe_set_debug_format(Formatter &f, bool set) -> decltype(f.set_debug_format(set))
Definition: ranges.h:292
static constexpr const unit_t< compound_unit< energy::joules, inverse< temperature::kelvin >, inverse< substance::moles > > > R(8.3144598)
Gas constant.
static constexpr const unit_t< compound_unit< charge::coulomb, inverse< substance::mol > > > F(N_A *e)
Faraday constant.
static constexpr const velocity::meters_per_second_t c(299792458.0)
Speed of light in vacuum.
range_format
Definition: ranges.h:497
#define FMT_DECLTYPE_RETURN(val)
Definition: ranges.h:97
FMT_BEGIN_EXPORT FMT_CONSTEXPR auto join(const std::tuple< T... > &tuple, string_view sep) -> tuple_join_view< char, T... >
\rst Returns an object that formats tuple with elements separated by sep.
Definition: ranges.h:703
auto begin() const -> typename Container::const_iterator
Definition: ranges.h:665
auto end() const -> typename Container::const_iterator
Definition: ranges.h:666
const Container & c
Definition: ranges.h:664
static FMT_CONSTEXPR size_t size()
Definition: ranges.h:190
T value_type
Definition: ranges.h:188
ParseContext & ctx
Definition: ranges.h:305
FMT_CONSTEXPR void operator()(Formatter &f)
Definition: ranges.h:301
arg_mapper< Context > mapper
Definition: ranges.h:391
static auto map(T &&value) -> decltype(mapper().map(static_cast< T && >(value)))
Definition: ranges.h:400
static auto map(T &&value) -> T &&
Definition: ranges.h:395
static constexpr const bool value
Definition: ranges.h:383
static constexpr const bool value
Definition: ranges.h:326
Definition: format.h:4210
tuple_join_view(const std::tuple< T... > &t, basic_string_view< Char > s)
Definition: ranges.h:578
const std::tuple< T... > & tuple
Definition: ranges.h:575
basic_string_view< Char > sep
Definition: ranges.h:576
auto format(wformat_string< T... > fmt, T &&... args) -> std::wstring
Definition: xchar.h:108