16 #include <type_traits> 19 #ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT 20 # define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256 25 template <
typename Char>
27 template <
typename ParseContext>
33 template <
typename Char,
typename Enable =
void>
45 template <
typename Char,
typename Enable =
void>
57 template <
typename RangeT,
typename OutputIterator>
58 void copy(
const RangeT &range, OutputIterator out) {
59 for (
auto it = range.begin(),
end = range.end(); it !=
end; ++it)
63 template <
typename OutputIterator>
64 void copy(
const char *str, OutputIterator out) {
65 const char *p_curr = str;
71 template <
typename OutputIterator>
72 void copy(
char ch, OutputIterator out) {
80 static auto check(U *p) ->
81 decltype(p->find(
'a'), p->length(), p->data(), int());
83 static void check(...);
90 template <
typename Char>
93 template <
typename... Ts>
96 template <
typename T,
typename _ =
void>
99 #if !FMT_MSC_VER || FMT_MSC_VER > 1800 100 template <
typename T>
101 struct is_range_<T, typename std::conditional<
103 conditional_helper<decltype(internal::declval<T>().begin()),
104 decltype(internal::declval<T>().end())>,
105 void>
::type> : std::true_type {};
109 template <
typename T>
110 class is_tuple_like_ {
111 template <
typename U>
112 static auto check(U *p) ->
113 decltype(std::tuple_size<U>::value,
116 static void check(...);
124 #if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900 125 template <
typename T, T... N>
126 using integer_sequence = std::integer_sequence<T, N...>;
127 template <std::size_t... N>
128 using index_sequence = std::index_sequence<N...>;
129 template <std::
size_t N>
130 using make_index_sequence = std::make_index_sequence<N>;
132 template <
typename T, T... N>
133 struct integer_sequence {
134 typedef T value_type;
141 template <std::size_t... N>
142 using index_sequence = integer_sequence<std::size_t, N...>;
144 template <
typename T, std::size_t N, T... Ns>
145 struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {};
146 template <
typename T, T... Ns>
147 struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {};
149 template <std::
size_t N>
150 using make_index_sequence = make_integer_sequence<std::size_t, N>;
153 template <
class Tuple,
class F,
size_t... Is>
154 void for_each(index_sequence<Is...>, Tuple &&tup, F &&f)
FMT_NOEXCEPT {
157 const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
163 get_indexes(T
const &) {
return {}; }
165 template <
class Tuple,
class F>
166 void for_each(Tuple &&tup, F &&f) {
167 const auto indexes = get_indexes(tup);
168 for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
171 template<
typename Arg>
172 FMT_CONSTEXPR const char* format_str_quoted(
bool add_space,
const Arg&,
173 typename std::enable_if<
175 return add_space ?
" {}" :
"{}";
178 template<
typename Arg>
179 FMT_CONSTEXPR const char* format_str_quoted(
bool add_space,
const Arg&,
180 typename std::enable_if<
182 return add_space ?
" \"{}\"" :
"\"{}\"";
185 FMT_CONSTEXPR const char* format_str_quoted(
bool add_space,
const char*) {
186 return add_space ?
" \"{}\"" :
"\"{}\"";
188 FMT_CONSTEXPR const wchar_t* format_str_quoted(
bool add_space,
const wchar_t*) {
189 return add_space ? L
" \"{}\"" : L
"\"{}\"";
192 FMT_CONSTEXPR const char* format_str_quoted(
bool add_space,
const char) {
193 return add_space ?
" '{}'" :
"'{}'";
195 FMT_CONSTEXPR const wchar_t* format_str_quoted(
bool add_space,
const wchar_t) {
196 return add_space ? L
" '{}'" : L
"'{}'";
201 template <
typename T>
207 template <
typename TupleT,
typename Char>
209 typename
std::enable_if<fmt::is_tuple_like<TupleT>::value>
::type> {
212 template <
typename FormatContext>
214 template <
typename T>
215 void operator()(
const T& v) {
217 if (formatting.add_prepostfix_space) {
223 internal::format_str_quoted(
224 (formatting.add_delimiter_spaces && i > 0), v),
231 typename std::add_lvalue_reference<decltype(std::declval<FormatContext>().out())>::
type out;
237 template <
typename ParseContext>
239 return formatting.
parse(ctx);
242 template <
typename FormatContext = format_context>
243 auto format(
const TupleT &values, FormatContext &ctx) -> decltype(ctx.out()) {
244 auto out = ctx.out();
248 internal::for_each(values, format_each<FormatContext>{formatting, i, out});
258 template <
typename T>
264 template <
typename RangeT,
typename Char>
266 typename
std::enable_if<fmt::is_range<RangeT>::value>
::type> {
270 template <
typename ParseContext>
272 return formatting.
parse(ctx);
275 template <
typename FormatContext>
277 const RangeT &values, FormatContext &ctx) {
278 auto out = ctx.out();
281 for (
auto it = values.begin(),
end = values.end(); it !=
end; ++it) {
289 internal::format_str_quoted(
307 #endif // FMT_RANGES_H_
std::shared_ptr< logger > get(const std::string &name)
#define FMT_CONSTEXPR_DECL
#define FMT_END_NAMESPACE
Return true value if T has std::string interface, like std::string_view.
#define FMT_RANGE_OUTPUT_LENGTH_LIMIT
std::add_rvalue_reference< T >::type declval()
std::enable_if< is_contiguous< Container >::value &&internal::is_string< S >::value, std::back_insert_iterator< Container > >::type format_to(std::back_insert_iterator< Container > out, const S &format_str, const Args &...args)
#define FMT_BEGIN_NAMESPACE
void copy(char ch, OutputIterator out)
auto end(const C &c) -> decltype(c.end())