Skip to content

Commit

Permalink
add fmt::print() overload to support compiled format
Browse files Browse the repository at this point in the history
  • Loading branch information
alexezeder committed May 21, 2021
1 parent 5a0d99f commit effd732
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 3 deletions.
14 changes: 14 additions & 0 deletions include/fmt/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,20 @@ size_t formatted_size(const S& format_str, const Args&... args) {
return format_to(detail::counting_iterator(), format_str, args...).count();
}

template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
void print(std::FILE* f, const S& format_str, const Args&... args) {
memory_buffer buffer;
format_to(std::back_inserter(buffer), format_str, args...);
detail::print_buffer(f, buffer);
}

template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
void print(const S& format_str, const Args&... args) {
print(stdout, format_str, args...);
}

#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
inline namespace literals {
template <detail::fixed_string Str>
Expand Down
12 changes: 9 additions & 3 deletions include/fmt/format-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2594,9 +2594,8 @@ extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( //
} // namespace detail
#endif

FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
memory_buffer buffer;
detail::vformat_to(buffer, format_str, args);
namespace detail {
FMT_FUNC void print_buffer(std::FILE* f, const memory_buffer& buffer) {
#ifdef _WIN32
auto fd = _fileno(f);
if (_isatty(fd)) {
Expand All @@ -2613,6 +2612,13 @@ FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
#endif
detail::fwrite_fully(buffer.data(), 1, buffer.size(), f);
}
} // namespace detail

FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
memory_buffer buffer;
detail::vformat_to(buffer, format_str, args);
detail::print_buffer(f, buffer);
}

#ifdef _WIN32
// Print assuming legacy (non-Unicode) encoding.
Expand Down
4 changes: 4 additions & 0 deletions include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,10 @@ template <typename T, size_t SIZE, typename Allocator>
struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
};

namespace detail {
FMT_API void print_buffer(std::FILE*, const memory_buffer&);
}

/** A formatting error such as invalid format string. */
FMT_CLASS_API
class FMT_API format_error : public std::runtime_error {
Expand Down
8 changes: 8 additions & 0 deletions test/compile-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "fmt/chrono.h"
#include "gmock/gmock.h"
#include "gtest-extra.h"

TEST(iterator_test, counting_iterator) {
auto it = fmt::detail::counting_iterator();
Expand Down Expand Up @@ -241,6 +242,13 @@ FMT_END_NAMESPACE
TEST(compile_test, to_string_and_formatter) {
fmt::format(FMT_COMPILE("{}"), to_stringable());
}

TEST(compile_test, print) {
EXPECT_WRITE(stdout, fmt::print(FMT_COMPILE("Don't {}!"), "panic"),
"Don't panic!");
EXPECT_WRITE(stderr, fmt::print(stderr, FMT_COMPILE("Don't {}!"), "panic"),
"Don't panic!");
}
#endif

#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
Expand Down

0 comments on commit effd732

Please sign in to comment.