forked from fmtlib/fmt
Add join argument allowing formating list of values separated by a (#466)
Add join argument allowing formating list of values separated by a string. Each value is formated according the format specifier.
This commit is contained in:
committed by
Victor Zverovich
parent
bc6af7548b
commit
a00006119f
60
fmt/format.h
60
fmt/format.h
@ -3865,6 +3865,66 @@ void BasicFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
|
|||||||
}
|
}
|
||||||
write(writer_, start, s);
|
write(writer_, start, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Char, typename It>
|
||||||
|
struct ArgJoin {
|
||||||
|
It first;
|
||||||
|
It last;
|
||||||
|
BasicCStringRef<Char> sep;
|
||||||
|
|
||||||
|
ArgJoin(It first, It last, const BasicCStringRef<Char>& sep) :
|
||||||
|
first(first),
|
||||||
|
last(last),
|
||||||
|
sep(sep) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
ArgJoin<char, It> join(It first, It last, const BasicCStringRef<char>& sep) {
|
||||||
|
return ArgJoin<char, It>(first, last, sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
ArgJoin<wchar_t, It> join(It first, It last, const BasicCStringRef<wchar_t>& sep) {
|
||||||
|
return ArgJoin<wchar_t, It>(first, last, sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if FMT_HAS_GXX_CXX11
|
||||||
|
template <typename Range>
|
||||||
|
auto join(const Range& range, const BasicCStringRef<char>& sep)
|
||||||
|
-> ArgJoin<char, decltype(std::begin(range))> {
|
||||||
|
return join(std::begin(range), std::end(range), sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Range>
|
||||||
|
auto join(const Range& range, const BasicCStringRef<wchar_t>& sep)
|
||||||
|
-> ArgJoin<wchar_t, decltype(std::begin(range))> {
|
||||||
|
return join(std::begin(range), std::end(range), sep);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename ArgFormatter, typename Char, typename It>
|
||||||
|
void format_arg(fmt::BasicFormatter<Char, ArgFormatter> &f,
|
||||||
|
const Char *&format_str, const ArgJoin<Char, It>& e) {
|
||||||
|
const Char* end = format_str;
|
||||||
|
if (*end == ':')
|
||||||
|
++end;
|
||||||
|
while (*end && *end != '}')
|
||||||
|
++end;
|
||||||
|
if (*end != '}')
|
||||||
|
FMT_THROW(FormatError("missing '}' in format string"));
|
||||||
|
|
||||||
|
It it = e.first;
|
||||||
|
if (it != e.last) {
|
||||||
|
const Char* save = format_str;
|
||||||
|
f.format(format_str, internal::MakeArg<fmt::BasicFormatter<Char, ArgFormatter> >(*it++));
|
||||||
|
while (it != e.last) {
|
||||||
|
f.writer().write(e.sep);
|
||||||
|
format_str = save;
|
||||||
|
f.format(format_str, internal::MakeArg<fmt::BasicFormatter<Char, ArgFormatter> >(*it++));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
format_str = end + 1;
|
||||||
|
}
|
||||||
} // namespace fmt
|
} // namespace fmt
|
||||||
|
|
||||||
#if FMT_USE_USER_DEFINED_LITERALS
|
#if FMT_USE_USER_DEFINED_LITERALS
|
||||||
|
@ -1552,6 +1552,27 @@ TEST(FormatTest, Variadic) {
|
|||||||
EXPECT_EQ(L"abc1", format(L"{}c{}", L"ab", 1));
|
EXPECT_EQ(L"abc1", format(L"{}c{}", L"ab", 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatTest, JoinArg) {
|
||||||
|
using fmt::join;
|
||||||
|
int v1[3] = { 1, 2, 3 };
|
||||||
|
std::vector<float> v2;
|
||||||
|
v2.push_back(1.2);
|
||||||
|
v2.push_back(3.4);
|
||||||
|
|
||||||
|
EXPECT_EQ("(1, 2, 3)", format("({})", join(v1 + 0, v1 + 3, ", ")));
|
||||||
|
EXPECT_EQ("(1)", format("({})", join(v1 + 0, v1 + 1, ", ")));
|
||||||
|
EXPECT_EQ("()", format("({})", join(v1 + 0, v1 + 0, ", ")));
|
||||||
|
EXPECT_EQ("(001, 002, 003)", format("({:03})", join(v1 + 0, v1 + 3, ", ")));
|
||||||
|
EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2.begin(), v2.end(), ", ")));
|
||||||
|
|
||||||
|
EXPECT_EQ(L"(1, 2, 3)", format(L"({})", join(v1 + 0, v1 + 3, L", ")));
|
||||||
|
|
||||||
|
#if FMT_HAS_GXX_CXX11
|
||||||
|
EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, ", ")));
|
||||||
|
EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2, ", ")));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string str(const T &value) {
|
std::string str(const T &value) {
|
||||||
return fmt::format("{}", value);
|
return fmt::format("{}", value);
|
||||||
|
Reference in New Issue
Block a user