mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-24 03:17:53 +00:00
Clean API
This commit is contained in:
parent
9a53a706fc
commit
c2fecb9b2a
@ -11,6 +11,7 @@
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
@ -265,6 +266,25 @@ class basic_buffer {
|
||||
const T &operator[](std::size_t index) const { return ptr_[index]; }
|
||||
};
|
||||
|
||||
using buffer = internal::basic_buffer<char>;
|
||||
using wbuffer = internal::basic_buffer<wchar_t>;
|
||||
|
||||
template <typename Container>
|
||||
class container_buffer
|
||||
: public internal::basic_buffer<typename Container::value_type> {
|
||||
private:
|
||||
Container &container_;
|
||||
|
||||
protected:
|
||||
virtual void grow(std::size_t capacity) {
|
||||
container_.resize(capacity);
|
||||
this->set(&container_[0], capacity);
|
||||
}
|
||||
|
||||
public:
|
||||
explicit container_buffer(Container &c) : container_(c) {}
|
||||
};
|
||||
|
||||
// A helper function to suppress bogus "conditional expression is constant"
|
||||
// warnings.
|
||||
template <typename T>
|
||||
@ -875,11 +895,8 @@ class basic_context :
|
||||
format_arg get_arg(basic_string_view<char_type> name);
|
||||
};
|
||||
|
||||
using buffer = internal::basic_buffer<char>;
|
||||
using wbuffer = internal::basic_buffer<wchar_t>;
|
||||
|
||||
using context = basic_context<internal::dynamic_range<buffer>>;
|
||||
using wcontext = basic_context<internal::dynamic_range<wbuffer>>;
|
||||
using context = basic_context<internal::dynamic_range<internal::buffer>>;
|
||||
using wcontext = basic_context<internal::dynamic_range<internal::wbuffer>>;
|
||||
|
||||
template <typename Context, typename ...Args>
|
||||
class arg_store {
|
||||
@ -1060,19 +1077,24 @@ inline void print_colored(Color c, string_view format_str,
|
||||
vprint_colored(c, format_str, make_args(args...));
|
||||
}
|
||||
|
||||
void vformat_to(buffer &buf, string_view format_str, format_args args);
|
||||
void vformat_to(wbuffer &buf, wstring_view format_str, wformat_args args);
|
||||
void vformat_to(internal::buffer &buf, string_view format_str,
|
||||
format_args args);
|
||||
void vformat_to(internal::wbuffer &buf, wstring_view format_str,
|
||||
wformat_args args);
|
||||
|
||||
template <typename... Args>
|
||||
inline void format_to(buffer &buf, string_view format_str,
|
||||
const Args & ... args) {
|
||||
vformat_to(buf, format_str, make_args(args...));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void format_to(wbuffer &buf, wstring_view format_str,
|
||||
const Args & ... args) {
|
||||
vformat_to(buf, format_str, make_args<wcontext>(args...));
|
||||
/**
|
||||
Formats a string and writes the output to out.
|
||||
*/
|
||||
template <typename Container>
|
||||
void vformat_to(std::back_insert_iterator<Container> out,
|
||||
string_view format_str, format_args args) {
|
||||
using iterator = std::back_insert_iterator<Container>;
|
||||
struct container_accessor : iterator {
|
||||
container_accessor(iterator it) : iterator(it) {}
|
||||
using iterator::container;
|
||||
} accessor(out);
|
||||
internal::container_buffer<Container> buf(*accessor.container);
|
||||
vformat_to(buf, format_str, args);
|
||||
}
|
||||
|
||||
std::string vformat(string_view format_str, format_args args);
|
||||
|
@ -91,7 +91,7 @@ inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
|
||||
|
||||
const char RESET_COLOR[] = "\x1b[0m";
|
||||
|
||||
typedef void (*FormatFunc)(buffer &, int, string_view);
|
||||
typedef void (*FormatFunc)(internal::buffer &, int, string_view);
|
||||
|
||||
// Portable thread-safe version of strerror.
|
||||
// Sets buffer to point to a string describing the error code.
|
||||
@ -161,7 +161,7 @@ int safe_strerror(
|
||||
return StrError(error_code, buffer, buffer_size).run();
|
||||
}
|
||||
|
||||
void format_error_code(buffer &out, int error_code,
|
||||
void format_error_code(internal::buffer &out, int error_code,
|
||||
string_view message) FMT_NOEXCEPT {
|
||||
// Report error code making sure that the output fits into
|
||||
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
|
||||
@ -358,7 +358,7 @@ FMT_FUNC void internal::format_windows_error(
|
||||
#endif // FMT_USE_WINDOWS_H
|
||||
|
||||
FMT_FUNC void format_system_error(
|
||||
buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
|
||||
internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
|
||||
FMT_TRY {
|
||||
memory_buffer buf;
|
||||
buf.resize(internal::INLINE_BUFFER_SIZE);
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
@ -307,22 +306,6 @@ void basic_buffer<T>::append(const U *begin, const U *end) {
|
||||
internal::make_ptr(ptr_, capacity_) + size_);
|
||||
size_ = new_size;
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
class container_buffer
|
||||
: public internal::basic_buffer<typename Container::value_type> {
|
||||
private:
|
||||
Container &container_;
|
||||
|
||||
protected:
|
||||
virtual void grow(std::size_t capacity) {
|
||||
container_.resize(capacity);
|
||||
this->set(&container_[0], capacity);
|
||||
}
|
||||
|
||||
public:
|
||||
explicit container_buffer(Container &c) : container_(c) {}
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
// A wrapper around std::locale used to reduce compile times since <locale>
|
||||
@ -2061,7 +2044,7 @@ class system_error : public std::runtime_error {
|
||||
may look like "Unknown error -1" and is platform-dependent.
|
||||
\endrst
|
||||
*/
|
||||
FMT_API void format_system_error(fmt::buffer &out, int error_code,
|
||||
FMT_API void format_system_error(fmt::internal::buffer &out, int error_code,
|
||||
fmt::string_view message) FMT_NOEXCEPT;
|
||||
|
||||
/**
|
||||
@ -2582,8 +2565,8 @@ void basic_writer<Range>::write_double(T value, const format_specs &spec) {
|
||||
});
|
||||
}
|
||||
|
||||
using writer = basic_writer<internal::dynamic_range<buffer>>;
|
||||
using wwriter = basic_writer<internal::dynamic_range<wbuffer>>;
|
||||
using writer = basic_writer<internal::dynamic_range<internal::buffer>>;
|
||||
using wwriter = basic_writer<internal::dynamic_range<internal::wbuffer>>;
|
||||
|
||||
// Reports a system error without throwing an exception.
|
||||
// Can be used to report errors from destructors.
|
||||
@ -3019,27 +3002,28 @@ std::basic_string<Char> to_string(const basic_memory_buffer<Char> &buffer) {
|
||||
return std::basic_string<Char>(buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
inline void vformat_to(buffer &buf, string_view format_str, format_args args) {
|
||||
using range = internal::dynamic_range<buffer>;
|
||||
inline void vformat_to(internal::buffer &buf, string_view format_str,
|
||||
format_args args) {
|
||||
using range = internal::dynamic_range<internal::buffer>;
|
||||
do_vformat_to<arg_formatter<range>>(buf, format_str, args);
|
||||
}
|
||||
|
||||
inline void vformat_to(wbuffer &buf, wstring_view format_str,
|
||||
inline void vformat_to(internal::wbuffer &buf, wstring_view format_str,
|
||||
wformat_args args) {
|
||||
using range = internal::dynamic_range<wbuffer>;
|
||||
using range = internal::dynamic_range<internal::wbuffer>;
|
||||
do_vformat_to<arg_formatter<range>>(buf, format_str, args);
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void vformat_to(std::back_insert_iterator<Container> out,
|
||||
string_view format_str, format_args args) {
|
||||
using iterator = std::back_insert_iterator<Container>;
|
||||
struct container_extractor : iterator {
|
||||
container_extractor(iterator it) : iterator(it) {}
|
||||
using iterator::container;
|
||||
} extractor(out);
|
||||
internal::container_buffer<Container> buf(*extractor.container);
|
||||
vformat_to(buf, format_str, args);
|
||||
template <typename... Args>
|
||||
inline void format_to(memory_buffer &buf, string_view format_str,
|
||||
const Args & ... args) {
|
||||
vformat_to(buf, format_str, make_args(args...));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void format_to(wmemory_buffer &buf, wstring_view format_str,
|
||||
const Args & ... args) {
|
||||
vformat_to(buf, format_str, make_args<wcontext>(args...));
|
||||
}
|
||||
|
||||
template <typename Container, typename... Args>
|
||||
|
@ -530,7 +530,7 @@ void printf(internal::basic_buffer<Char> &buf, basic_string_view<Char> format,
|
||||
template <typename Buffer>
|
||||
using printf_context = basic_printf_context<internal::dynamic_range<Buffer>>;
|
||||
|
||||
using printf_args = basic_format_args<printf_context<buffer>>;
|
||||
using printf_args = basic_format_args<printf_context<internal::buffer>>;
|
||||
|
||||
inline std::string vsprintf(string_view format, printf_args args) {
|
||||
memory_buffer buffer;
|
||||
@ -549,11 +549,13 @@ inline std::string vsprintf(string_view format, printf_args args) {
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline std::string sprintf(string_view format_str, const Args & ... args) {
|
||||
return vsprintf(format_str, make_args<printf_context<buffer>>(args...));
|
||||
return vsprintf(format_str,
|
||||
make_args<printf_context<internal::buffer>>(args...));
|
||||
}
|
||||
|
||||
inline std::wstring vsprintf(wstring_view format,
|
||||
basic_format_args<printf_context<wbuffer>> args) {
|
||||
inline std::wstring vsprintf(
|
||||
wstring_view format,
|
||||
basic_format_args<printf_context<internal::wbuffer>> args) {
|
||||
wmemory_buffer buffer;
|
||||
printf(buffer, format, args);
|
||||
return to_string(buffer);
|
||||
@ -561,7 +563,7 @@ inline std::wstring vsprintf(wstring_view format,
|
||||
|
||||
template <typename... Args>
|
||||
inline std::wstring sprintf(wstring_view format_str, const Args & ... args) {
|
||||
auto vargs = make_args<printf_context<wbuffer>>(args...);
|
||||
auto vargs = make_args<printf_context<internal::wbuffer>>(args...);
|
||||
return vsprintf(format_str, vargs);
|
||||
}
|
||||
|
||||
@ -584,7 +586,7 @@ inline int vfprintf(std::FILE *f, string_view format, printf_args args) {
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline int fprintf(std::FILE *f, string_view format_str, const Args & ... args) {
|
||||
auto vargs = make_args<printf_context<buffer>>(args...);
|
||||
auto vargs = make_args<printf_context<internal::buffer>>(args...);
|
||||
return vfprintf(f, format_str, vargs);
|
||||
}
|
||||
|
||||
@ -603,7 +605,8 @@ inline int vprintf(string_view format, printf_args args) {
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline int printf(string_view format_str, const Args & ... args) {
|
||||
return vprintf(format_str, make_args<printf_context<buffer>>(args...));
|
||||
return vprintf(format_str,
|
||||
make_args<printf_context<internal::buffer>>(args...));
|
||||
}
|
||||
|
||||
inline int vfprintf(std::ostream &os, string_view format_str,
|
||||
@ -626,7 +629,7 @@ inline int vfprintf(std::ostream &os, string_view format_str,
|
||||
template <typename... Args>
|
||||
inline int fprintf(std::ostream &os, string_view format_str,
|
||||
const Args & ... args) {
|
||||
auto vargs = make_args<printf_context<buffer>>(args...);
|
||||
auto vargs = make_args<printf_context<internal::buffer>>(args...);
|
||||
return vfprintf(os, format_str, vargs);
|
||||
}
|
||||
} // namespace fmt
|
||||
|
@ -31,7 +31,7 @@ struct formatter<std::tm> {
|
||||
}
|
||||
|
||||
auto format(const std::tm &tm, context &ctx) -> decltype(ctx.begin()) {
|
||||
buffer &buf = ctx.range().container();
|
||||
internal::buffer &buf = ctx.range().container();
|
||||
std::size_t start = buf.size();
|
||||
for (;;) {
|
||||
std::size_t size = buf.capacity() - start;
|
||||
|
@ -15,9 +15,10 @@ using fmt::printf_arg_formatter;
|
||||
// A custom argument formatter that doesn't print `-` for floating-point values
|
||||
// rounded to 0.
|
||||
class CustomArgFormatter :
|
||||
public fmt::arg_formatter<fmt::internal::dynamic_range<fmt::buffer>> {
|
||||
public fmt::arg_formatter<
|
||||
fmt::internal::dynamic_range<fmt::internal::buffer>> {
|
||||
public:
|
||||
using range = fmt::internal::dynamic_range<fmt::buffer>;
|
||||
using range = fmt::internal::dynamic_range<fmt::internal::buffer>;
|
||||
using base = fmt::arg_formatter<range>;
|
||||
|
||||
CustomArgFormatter(range r, fmt::basic_context<range> &ctx,
|
||||
|
@ -374,20 +374,17 @@ TEST(WriterTest, WWriter) {
|
||||
}
|
||||
|
||||
TEST(FormatToTest, FormatWithoutArgs) {
|
||||
fmt::memory_buffer buffer;
|
||||
format_to(buffer, "test");
|
||||
EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
|
||||
std::string s;
|
||||
fmt::format_to(std::back_inserter(s), "test");
|
||||
EXPECT_EQ("test", s);
|
||||
}
|
||||
|
||||
TEST(FormatToTest, Format) {
|
||||
fmt::memory_buffer buffer;
|
||||
format_to(buffer, "part{0}", 1);
|
||||
EXPECT_EQ(strlen("part1"), buffer.size());
|
||||
EXPECT_EQ("part1", std::string(buffer.data(), buffer.size()));
|
||||
format_to(buffer, "part{0}", 2);
|
||||
EXPECT_EQ(strlen("part1part2"), buffer.size());
|
||||
EXPECT_EQ("part1part2", std::string(buffer.data(), buffer.size()));
|
||||
EXPECT_EQ("part1part2", to_string(buffer));
|
||||
std::string s;
|
||||
fmt::format_to(std::back_inserter(s), "part{0}", 1);
|
||||
EXPECT_EQ("part1", s);
|
||||
fmt::format_to(std::back_inserter(s), "part{0}", 2);
|
||||
EXPECT_EQ("part1part2", s);
|
||||
}
|
||||
|
||||
TEST(FormatterTest, Escape) {
|
||||
@ -1484,7 +1481,7 @@ TEST(FormatTest, Enum) {
|
||||
EXPECT_EQ("0", fmt::format("{}", A));
|
||||
}
|
||||
|
||||
using buffer_range = fmt::internal::dynamic_range<fmt::buffer>;
|
||||
using buffer_range = fmt::internal::dynamic_range<fmt::internal::buffer>;
|
||||
|
||||
class mock_arg_formatter :
|
||||
public fmt::internal::arg_formatter_base<buffer_range> {
|
||||
@ -1908,17 +1905,6 @@ TEST(FormatTest, FormatStringErrors) {
|
||||
int, int);
|
||||
}
|
||||
|
||||
TEST(FormatTest, OutputIterator) {
|
||||
|
||||
std::string s;
|
||||
fmt::format_to(std::back_inserter(s), "{}", 42);
|
||||
std::vector<char> v;
|
||||
fmt::format_to(std::back_inserter(v), "{}", 42);
|
||||
|
||||
EXPECT_EQ("42", s);
|
||||
EXPECT_EQ("42", std::string(v.begin(), v.end()));
|
||||
}
|
||||
|
||||
TEST(StringTest, ToString) {
|
||||
EXPECT_EQ("42", fmt::to_string(42));
|
||||
}
|
||||
|
@ -58,10 +58,10 @@ TEST(OStreamTest, Enum) {
|
||||
EXPECT_EQ("0", fmt::format("{}", A));
|
||||
}
|
||||
|
||||
struct TestArgFormatter
|
||||
: fmt::arg_formatter<fmt::internal::dynamic_range<fmt::buffer>> {
|
||||
using base = fmt::arg_formatter<fmt::internal::dynamic_range<fmt::buffer>>;
|
||||
TestArgFormatter(fmt::buffer &buf, fmt::context &ctx, fmt::format_specs &s)
|
||||
struct test_arg_formatter : fmt::arg_formatter<fmt::context::range_type> {
|
||||
using base = fmt::arg_formatter<fmt::context::range_type>;
|
||||
test_arg_formatter(fmt::internal::buffer &buf, fmt::context &ctx,
|
||||
fmt::format_specs &s)
|
||||
: base(buf, ctx, s) {}
|
||||
};
|
||||
|
||||
@ -69,7 +69,7 @@ TEST(OStreamTest, CustomArg) {
|
||||
fmt::memory_buffer buffer;
|
||||
fmt::context ctx(buffer, "", fmt::format_args());
|
||||
fmt::format_specs spec;
|
||||
TestArgFormatter af(buffer, ctx, spec);
|
||||
test_arg_formatter af(buffer, ctx, spec);
|
||||
visit(af, fmt::internal::make_arg<fmt::context>(TestEnum()));
|
||||
EXPECT_EQ("TestEnum", std::string(buffer.data(), buffer.size()));
|
||||
}
|
||||
@ -136,7 +136,7 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
|
||||
if (max_size <= fmt::internal::to_unsigned(max_streamsize))
|
||||
return;
|
||||
|
||||
struct test_buffer : fmt::buffer {
|
||||
struct test_buffer : fmt::internal::buffer {
|
||||
explicit test_buffer(std::size_t size) { resize(size); }
|
||||
void grow(std::size_t) {}
|
||||
} buffer(max_size);
|
||||
|
@ -720,7 +720,7 @@ TEST(UtilTest, UTF16ToUTF8Convert) {
|
||||
#endif // _WIN32
|
||||
|
||||
typedef void (*FormatErrorMessage)(
|
||||
fmt::buffer &out, int error_code, string_view message);
|
||||
fmt::internal::buffer &out, int error_code, string_view message);
|
||||
|
||||
template <typename Error>
|
||||
void check_throw_error(int error_code, FormatErrorMessage format) {
|
||||
|
Loading…
Reference in New Issue
Block a user