-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for ranges, containers and types tuple interface... #735
Conversation
…anges.h and some tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! Looks good, but please follow the style guidelines described ]here, particularly 2-space indent (I think you can use clang-format with Google Style settings to fix this automatically). Also a few comments inline.
include/fmt/ranges.h
Outdated
template<typename OutputIterator> | ||
void copy(const char ch, OutputIterator out) { | ||
*out++ = ch; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest putting all of the above in the internal
namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
include/fmt/ranges.h
Outdated
} | ||
|
||
template<typename OutputIterator> | ||
void copy(const char ch, OutputIterator out) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
is not needed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
include/fmt/ranges.h
Outdated
|
||
|
||
namespace fmt { | ||
namespace meta { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest using internal
namespace instead of meta
here for consistency with the rest of the library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
include/fmt/ranges.h
Outdated
template<typename T> | ||
class is_like_std_string { | ||
template<typename U> static auto check(U* p) -> decltype( | ||
p->find('a') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to require find
for string-like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is length() and data() really enough to be sure that this is std::string like type?
include/fmt/ranges.h
Outdated
}; | ||
|
||
template<typename T> | ||
constexpr bool is_like_std_string_v = is_like_std_string<T>::value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and elsewhere: constexpr -> FMT_CONSTEXPR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
include/fmt/ranges.h
Outdated
Char prefix = '{'; | ||
Char delimiter = ','; | ||
Char postfix = '}'; | ||
bool add_spaces = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Containers are usually formatted without embedded spaces, in particular in Python format which this library is modeled after:
>>> '{}'.format([1, 2])
'[1, 2]'
so I suggest dropping this flag (or at least setting it to false).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, set add_spaces to false per default.
include/fmt/ranges.h
Outdated
template <typename ParseContext> | ||
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin()) { | ||
return formating.parse(ctx); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't be needed if you inherit from formatting_tuple.
include/fmt/ranges.h
Outdated
template <typename FormatContext = format_context> | ||
auto format(const TupleT &values, FormatContext &ctx) -> decltype(ctx.out()) { | ||
auto out = ctx.out(); | ||
std::ptrdiff_t i = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not size_t?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, replaced by size_t.
I needed signed type in older implementation but now it can be size_t.
include/fmt/ranges.h
Outdated
|
||
|
||
|
||
namespace fmt { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be merged with the above namespace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
include/fmt/ranges.h
Outdated
template<typename RangeT, typename Char> | ||
struct formatter <RangeT, Char, std::enable_if_t<fmt::meta::is_range_v<RangeT>> > | ||
{ | ||
static constexpr std::ptrdiff_t range_length_limit = FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the range. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not size_t?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, ditto.
Renames namespace meta to internal and put copy functions int it. Replaced constexpr by FMT_CONSTEXPR. Replaced std::ptrdiff_t by std::size_t.
Replaced std::enable_if_t by std::std::enable_if<>::type. Replaced variable templates by structs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update. Just a few more comments/questions.
include/fmt/ranges.h
Outdated
struct formatting_tuple : formatting_base<Char> { | ||
Char prefix = '['; | ||
Char delimiter = ','; | ||
Char postfix = ']'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tuples are normally delimited by parentheses ()
rather than square brackets []
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using ()
in last commit now.
include/fmt/ranges.h
Outdated
internal::copy(formatting.prefix, out); | ||
internal::for_each(values, [&](const auto &v) { | ||
if (i++ > 0) { | ||
internal::copy(formatting.delimiter, out); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest adding a space after delimiter as in (1, 2)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be configured now by bool add_delimiter_spaces
include/fmt/ranges.h
Outdated
typename std::enable_if<fmt::internal::is_range<RangeT>::value>::type> { | ||
|
||
static FMT_CONSTEXPR_DECL const std::size_t range_length_limit = | ||
FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the range. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need a limit? User can always pass a subrange to fmt::join
if they don't want to format everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it could be and infinite range, or nested range where user can not use fmt::join.
std::tuple<std::vector<std::vector<int>>>
test/ranges-test.cc
Outdated
} | ||
|
||
#if (__cplusplus > 201402L) || \ | ||
(defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this to check if constexpr
is supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to check if if constexpr
is supported.
test/ranges-test.cc
Outdated
// {fmt} support for ranges, containers and types tuple interface. | ||
|
||
#ifdef WIN32 | ||
#define _CRT_SECURE_NO_WARNINGS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be removed.
Added add_delimiter_spaces and add_prepostfix_space.
Merged with minor formatting tweaks in e3f7f3a. Thanks! |
No description provided.