mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-05 09:40:40 +00:00
Add fmt::join to format ranges (#466)
This commit is contained in:
parent
87eab90ea8
commit
a980d3b46b
@ -26,6 +26,11 @@
|
|||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||||
|
# if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__
|
||||||
|
# define FMT_HAS_GXX_CXX11 1
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define FMT_HAS_GXX_CXX11 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -3045,6 +3045,60 @@ constexpr fill_spec_factory fill;
|
|||||||
constexpr format_spec_factory<width_spec> width;
|
constexpr format_spec_factory<width_spec> width;
|
||||||
constexpr format_spec_factory<type_spec> type;
|
constexpr format_spec_factory<type_spec> type;
|
||||||
|
|
||||||
|
template <typename It, typename Char>
|
||||||
|
struct arg_join {
|
||||||
|
It begin;
|
||||||
|
It end;
|
||||||
|
basic_string_view<Char> sep;
|
||||||
|
|
||||||
|
arg_join(It begin, It end, basic_string_view<Char> sep)
|
||||||
|
: begin(begin), end(end), sep(sep) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename It, typename Char>
|
||||||
|
struct formatter<arg_join<It, Char>, Char>:
|
||||||
|
formatter<typename std::iterator_traits<It>::value_type, Char> {
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const arg_join<It, Char> &value, FormatContext &ctx) {
|
||||||
|
using base = formatter<typename std::iterator_traits<It>::value_type, Char>;
|
||||||
|
auto it = value.begin;
|
||||||
|
auto out = ctx.begin();
|
||||||
|
if (it != value.end) {
|
||||||
|
out = base::format(*it++, ctx);
|
||||||
|
while (it != value.end) {
|
||||||
|
out = std::copy(value.sep.begin(), value.sep.end(), out);
|
||||||
|
ctx.advance_to(out);
|
||||||
|
out = base::format(*it++, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
arg_join<It, char> join(It begin, It end, string_view sep) {
|
||||||
|
return arg_join<It, char>(begin, end, sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
arg_join<It, wchar_t> join(It begin, It end, wstring_view sep) {
|
||||||
|
return arg_join<It, wchar_t>(begin, end, sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if FMT_HAS_GXX_CXX11
|
||||||
|
template <typename Range>
|
||||||
|
auto join(const Range &range, string_view sep)
|
||||||
|
-> arg_join<decltype(std::begin(range)), char> {
|
||||||
|
return join(std::begin(range), std::end(range), sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Range>
|
||||||
|
auto join(const Range &range, wstring_view sep)
|
||||||
|
-> arg_join<decltype(std::begin(range)), wchar_t> {
|
||||||
|
return join(std::begin(range), std::end(range), sep);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
Converts *value* to ``std::string`` using the default format for type *T*.
|
Converts *value* to ``std::string`` using the default format for type *T*.
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
// Test that the library compiles if None is defined to 0 as done by xlib.h.
|
// Test that the library compiles if None is defined to 0 as done by xlib.h.
|
||||||
#define None 0
|
#define None 0
|
||||||
|
|
||||||
#include "fmt/core.h"
|
#include "fmt/format.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "mock-allocator.h"
|
#include "mock-allocator.h"
|
||||||
@ -1403,6 +1403,29 @@ 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.2f);
|
||||||
|
v2.push_back(3.4f);
|
||||||
|
|
||||||
|
EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, v1 + 3, ", ")));
|
||||||
|
EXPECT_EQ("(1)", format("({})", join(v1, v1 + 1, ", ")));
|
||||||
|
EXPECT_EQ("()", format("({})", join(v1, v1, ", ")));
|
||||||
|
EXPECT_EQ("(001, 002, 003)", format("({:03})", join(v1, 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, v1 + 3, L", ")));
|
||||||
|
EXPECT_EQ("1, 2, 3", format("{0:{1}}", join(v1, v1 + 3, ", "), 1));
|
||||||
|
|
||||||
|
#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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user