15 #include <initializer_list> 16 #include <type_traits> 21 #ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT 22 # define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256 28 template <
typename ParseContext>
34 template <
typename Char,
typename Enable =
void>
47 template <
typename Char,
typename Enable =
void>
59 template <
typename RangeT,
typename OutputIterator>
60 OutputIterator
copy(
const RangeT& range, OutputIterator out) {
61 for (
auto it = range.begin(), end = range.end(); it != end; ++it)
66 template <
typename OutputIterator>
67 OutputIterator
copy(
const char* str, OutputIterator out) {
68 while (*str) *out++ = *str++;
72 template <
typename OutputIterator>
73 OutputIterator
copy(
char ch, OutputIterator out) {
81 static auto check(U* p)
82 -> decltype((
void)p->find(
'a'), p->length(), (void)p->data(), int());
83 template <
typename>
static void check(...);
90 template <
typename Char>
95 template <
typename T,
typename _ =
void>
struct is_range_ : std::false_type {};
97 #if !FMT_MSC_VER || FMT_MSC_VER > 1800 102 decltype(std::declval<T>().end())>,
103 void>> : std::true_type {};
108 template <
typename U>
109 static auto check(U* p) -> decltype(std::tuple_size<U>::value,
int());
110 template <
typename>
static void check(...);
114 !std::is_void<decltype(check<T>(
nullptr))>
::value;
118 #if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900 119 template <
typename T, T... N>
132 template <
typename T,
size_t N, T... Ns>
134 template <
typename T, T... Ns>
141 template <
class Tuple,
class F,
size_t... Is>
145 const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
155 template <
class Tuple,
class F>
void for_each(Tuple&& tup, F&& f) {
157 for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
160 template <
typename Range>
166 return add_space ?
" {}" :
"{}";
172 return add_space ?
" \"{}\"" :
"\"{}\"";
176 return add_space ?
" \"{}\"" :
"\"{}\"";
179 return add_space ? L
" \"{}\"" : L
"\"{}\"";
183 return add_space ?
" '{}'" :
"'{}'";
186 return add_space ? L
" '{}'" : L
"'{}'";
195 template <
typename TupleT,
typename Char>
199 template <
typename FormatContext>
struct format_each {
202 if (formatting.add_prepostfix_space) {
209 (formatting.add_delimiter_spaces && i > 0), v),
216 typename std::add_lvalue_reference<decltype(
223 template <
typename ParseContext>
225 return formatting.
parse(ctx);
228 template <
typename FormatContext = format_context>
229 auto format(
const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) {
230 auto out = ctx.out();
244 template <
typename T,
typename Char>
struct is_range {
247 !std::is_convertible<T, std::basic_string<Char>>::value &&
248 !std::is_constructible<detail::std_string_view<Char>, T>::value;
251 template <
typename T,
typename Char>
256 #if !FMT_MSC_VER || FMT_MSC_VER >= 1927 258 (has_formatter<detail::value_type<T>, format_context>::value ||
259 detail::has_fallback_formatter<detail::value_type<T>,
260 format_context>::value)
265 template <
typename ParseContext>
267 return formatting.
parse(ctx);
270 template <
typename FormatContext>
271 typename FormatContext::iterator
format(
const T& values, FormatContext& ctx) {
274 auto it = values.begin();
275 auto end = values.end();
276 for (; it != end; ++it) {
286 out =
format_to(out,
" ... <other elements>");
300 : tuple{t}, sep{s} {}
303 template <
typename Char,
typename... T>
305 template <
typename ParseContext>
310 template <
typename FormatContext>
317 template <
typename FormatContext,
size_t... N>
324 template <
typename FormatContext>
332 template <
typename FormatContext,
typename Arg,
typename... Args>
335 const Arg&
arg,
const Args&... args) {
337 auto out = ctx.out();
338 out = base{}.format(arg, ctx);
339 if (
sizeof...(Args) > 0) {
359 template <
typename... T>
365 template <
typename... T>
382 template <
typename T>
385 return join(std::begin(list), std::end(list), sep);
388 template <
typename T>
391 return join(std::begin(list), std::end(list), sep);
396 #endif // FMT_RANGES_H_
#define FMT_BEGIN_NAMESPACE
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
FMT_CONSTEXPR tuple_arg_join< char, T... > join(const std::tuple< T... > &tuple, string_view sep)
void for_each(Tuple &&tup, F &&f)
#define FMT_RANGE_OUTPUT_LENGTH_LIMIT
integer_sequence< size_t, N... > index_sequence
FMT_CONSTEXPR const wchar_t * format_str_quoted(bool add_space, const wchar_t)
#define FMT_CONSTEXPR_DECL
void for_each(index_sequence< Is... >, Tuple &&tup, F &&f) FMT_NOEXCEPT
OutputIterator copy(char ch, OutputIterator out)
basic_string_view< Char > sep
#define FMT_END_NAMESPACE
OutputIterator copy(const RangeT &range, OutputIterator out)
typename std::enable_if< B, T >::type enable_if_t
tuple_size and tuple_element check.
#define FMT_ENABLE_IF(...)
typename std::conditional< B, T, F >::type conditional_t
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
tuple_arg_join(const std::tuple< T... > &t, basic_string_view< Char > s)
FMT_CONSTEXPR const char * format_str_quoted(bool add_space, const Arg &)
static FMT_CONSTEXPR size_t size()
remove_cvref_t< decltype(*std::declval< Range >().begin())> value_type
Return true value if T has std::string interface, like std::string_view.
detail::named_arg< Char, T > arg(const Char *name, const T &arg)
FMT_CONSTEXPR make_index_sequence< std::tuple_size< T >::value > get_indexes(T const &)
const std::tuple< T... > & tuple
auto format_to(OutputIt out, const text_style &ts, const S &format_str, Args &&... args) -> typename std::enable_if< enable, OutputIt >::type