23#ifdef FMT_DEPRECATED_BRACED_RANGES
31 template <
typename ParseContext>
41 template <
typename ParseContext>
49template <
typename RangeT,
typename OutputIterator>
50OutputIterator
copy(
const RangeT& range, OutputIterator out) {
51 for (
auto it = range.begin(), end = range.end(); it != end; ++it)
56template <
typename OutputIterator>
57OutputIterator
copy(
const char* str, OutputIterator out) {
58 while (*str) *out++ = *str++;
62template <
typename OutputIterator>
63OutputIterator
copy(
char ch, OutputIterator out) {
68template <
typename OutputIterator>
69OutputIterator
copy(
wchar_t ch, OutputIterator out) {
78 ->
decltype((void)p->find(
'a'), p->length(), (void)p->data(),
int());
79 template <
typename>
static void check(...);
86template <
typename Char>
93#if !FMT_MSC_VER || FMT_MSC_VER > 1800
95# define FMT_DECLTYPE_RETURN(val) \
96 ->decltype(val) { return val; } \
102template <
typename T, std::
size_t N>
106template <
typename T, std::
size_t N>
111template <
typename T,
typename Enable =
void>
116 decltype(std::declval<T>().end())>>
129 -> enable_if_t<!has_member_fn_begin_end_t<T&&>::value,
130 decltype(begin(
static_cast<T&&
>(rng)))> {
131 return begin(
static_cast<T&&
>(rng));
134auto range_end(
T&& rng) -> enable_if_t<!has_member_fn_begin_end_t<T&&>::value,
135 decltype(end(
static_cast<T&&
>(rng)))> {
136 return end(
static_cast<T&&
>(rng));
139template <
typename T,
typename Enable =
void>
141template <
typename T,
typename Enable =
void>
147 std::declval<const remove_cvref_t<T>&>())),
148 decltype(detail::range_begin(
149 std::declval<const remove_cvref_t<T>&>()))>>
155 decltype(detail::range_begin(std::declval<T>())),
156 enable_if_t<std::is_copy_constructible<T>::value>>>
162 has_mutable_begin_end<T>::value)> {};
173 static auto view(const
T& range) -> view_t {
return {&range}; }
185 static auto view(const
T& range) -> view_t {
return {range}; }
187# undef FMT_DECLTYPE_RETURN
192 template <
typename U>
193 static auto check(U* p) ->
decltype(std::tuple_size<U>::value,
int());
194 template <
typename>
static void check(...);
202#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900
203template <
typename T,
T... N>
216template <
typename T,
size_t N,
T... Ns>
218template <
typename T,
T... Ns>
225template <
class Tuple,
class F,
size_t... Is>
229 const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
239template <
class Tuple,
class F>
void for_each(Tuple&& tup, F&& f) {
244template <
typename Range>
255 typename Char,
typename OutputIt,
typename Arg,
259 out = write<Char>(out, v);
264template <
typename Char,
typename OutputIt,
typename Arg,
274 typename Char,
typename OutputIt,
typename Arg,
277OutputIt write_range_entry(OutputIt out,
const Arg& v) {
278 return write<Char>(out, v);
288template <
typename TupleT,
typename Char>
292 template <
typename FormatContext>
struct format_each {
295 out = detail::write_range_entry<Char>(out, v);
307 template <
typename ParseContext>
309 return formatting.
parse(ctx);
312 template <
typename FormatContext = format_context>
313 auto format(
const TupleT& values, FormatContext& ctx) ->
decltype(ctx.out()) {
314 auto out = ctx.out();
325template <
typename T,
typename Char>
struct is_range {
332template <
typename T,
typename Char>
338#if !FMT_MSC_VER || FMT_MSC_VER >= 1927
339 && (has_formatter<detail::value_type<T>, format_context>::value ||
340 detail::has_fallback_formatter<detail::value_type<T>, Char>::value)
345 template <
typename ParseContext>
347 return formatting.
parse(ctx);
350 template <
typename FormatContext>
351 typename FormatContext::iterator
format(
const T& values, FormatContext& ctx) {
355 auto it =
view.begin();
356 auto end =
view.end();
357 for (; it != end; ++it) {
359 out = detail::write_range_entry<Char>(out, *it);
371 : tuple(t), sep{s} {}
374template <
typename Char,
typename...
T>
377template <
typename Char,
typename...
T>
379 template <
typename ParseContext>
384 template <
typename FormatContext>
386 typename FormatContext::iterator {
391 template <
typename FormatContext,
size_t... N>
394 typename FormatContext::iterator {
399 template <
typename FormatContext>
401 typename FormatContext::iterator {
407 template <
typename FormatContext,
typename Arg,
typename... Args>
409 const Arg&
arg,
const Args&... args) ->
410 typename FormatContext::iterator {
412 auto out = base().format(
arg, ctx);
413 if (
sizeof...(Args) > 0) {
435template <
typename...
T>
441template <
typename...
T>
Return true value if T has std::string interface, like std::string_view.
static auto check(U *p) -> decltype((void) p->find('a'), p->length(),(void) p->data(), int())
tuple_size and tuple_element check.
static auto check(U *p) -> decltype(std::tuple_size< U >::value, int())
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
#define FMT_MODULE_EXPORT_BEGIN
#define FMT_BEGIN_NAMESPACE
#define FMT_ENABLE_IF(...)
basic_format_args< format_context > format_args
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
#define FMT_END_NAMESPACE
#define FMT_MODULE_EXPORT_END
#define FMT_CONSTEXPR_DECL
OutputIt write_delimiter(OutputIt out)
remove_cvref_t< decltype(*detail::range_begin(std::declval< Range >()))> value_type
auto range_begin(const T(&arr)[N]) -> const T *
FMT_CONSTEXPR make_index_sequence< std::tuple_size< T >::value > get_indexes(T const &)
OutputIterator copy(const RangeT &range, OutputIterator out)
OutputIt write_range_entry(OutputIt out, const Arg &v)
auto range_end(const T(&arr)[N]) -> const T *
void for_each(index_sequence< Is... >, Tuple &&tup, F &&f) FMT_NOEXCEPT
#define FMT_DECLTYPE_RETURN(val)
static FMT_CONSTEXPR size_t size()
tuple_join_view(const std::tuple< T... > &t, basic_string_view< Char > s)
const std::tuple< T... > & tuple
basic_string_view< Char > sep