Skip to content

Commit

Permalink
Add dynamic width support to FMT_COMPILE (#1809)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Aug 10, 2020
1 parent 6fb7c6f commit f1df368
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 7 deletions.
9 changes: 5 additions & 4 deletions include/fmt/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,8 @@ template <typename Char, typename T, int N> struct spec_field {
OutputIt format(OutputIt out, const Args&... args) const {
// This ensures that the argument type is convertile to `const T&`.
const T& arg = get<N>(args...);
basic_format_context<OutputIt, Char> ctx(out, {});
const auto& vargs = make_format_args(args...);
basic_format_context<OutputIt, Char> ctx(out, vargs);
return fmt.format(arg, ctx);
}
};
Expand Down Expand Up @@ -506,9 +507,9 @@ template <typename T, typename Char> struct parse_specs_result {

template <typename T, typename Char>
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
size_t pos) {
size_t pos, int arg_id) {
str.remove_prefix(pos);
auto ctx = basic_format_parse_context<Char>(str);
auto ctx = basic_format_parse_context<Char>(str, {}, arg_id + 1);
auto f = formatter<T, Char>();
auto end = f.parse(ctx);
return {f, pos + (end - str.data()) + 1};
Expand All @@ -531,7 +532,7 @@ constexpr auto compile_format_string(S format_str) {
format_str);
} else if constexpr (str[POS + 1] == ':') {
using type = get_type<ID, Args>;
constexpr auto result = parse_specs<type>(str, POS + 2);
constexpr auto result = parse_specs<type>(str, POS + 2, ID);
return parse_tail<Args, result.end, ID + 1>(
spec_field<char_type, type, ID>{result.fmt}, format_str);
} else {
Expand Down
8 changes: 5 additions & 3 deletions include/fmt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,8 @@ template <typename T> struct std_string_view {};

#ifdef FMT_USE_INT128
// Do nothing.
#elif defined(__SIZEOF_INT128__) && !FMT_NVCC && !(FMT_CLANG_VERSION && FMT_MSC_VER)
#elif defined(__SIZEOF_INT128__) && !FMT_NVCC && \
!(FMT_CLANG_VERSION && FMT_MSC_VER)
# define FMT_USE_INT128 1
using int128_t = __int128_t;
using uint128_t = __uint128_t;
Expand Down Expand Up @@ -556,8 +557,9 @@ class basic_format_parse_context : private ErrorHandler {
using iterator = typename basic_string_view<Char>::iterator;

explicit constexpr basic_format_parse_context(
basic_string_view<Char> format_str, ErrorHandler eh = {})
: ErrorHandler(eh), format_str_(format_str), next_arg_id_(0) {}
basic_string_view<Char> format_str, ErrorHandler eh = {},
int next_arg_id = 0)
: ErrorHandler(eh), format_str_(format_str), next_arg_id_(next_arg_id) {}

/**
Returns an iterator to the beginning of the format string range being
Expand Down
4 changes: 4 additions & 0 deletions test/compile-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ TEST(CompileTest, FormatSpecs) {
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{:x}"), 0x42));
}

TEST(CompileTest, DynamicWidth) {
EXPECT_EQ(" 42", fmt::format(FMT_COMPILE("{:{}}"), 42, 4));
}

TEST(CompileTest, FormatTo) {
char buf[8];
auto end = fmt::format_to(buf, FMT_COMPILE("{}"), 42);
Expand Down

0 comments on commit f1df368

Please sign in to comment.