Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mt complex p2197 r0 #4034

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions include/fmt/std.h
Original file line number Diff line number Diff line change
Expand Up @@ -634,30 +634,55 @@ FMT_EXPORT
template <typename F, typename Char>
struct formatter<std::complex<F>, Char> : nested_formatter<F, Char> {
private:
bool compat_iostreams_ = false;
// Functor because C++11 doesn't support generic lambdas.
struct writer {
const formatter<std::complex<F>, Char>* f;
const std::complex<F>& c;
const bool compat_iostreams;

template <typename OutputIt>
FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt {
if (c.real() != 0) {
auto format_full = detail::string_literal<Char, '(', '{', '}', '+', '{',
'}', 'i', ')'>{};
return fmt::format_to(out, basic_string_view<Char>(format_full),
f->nested(c.real()), f->nested(c.imag()));
if (c.real() != 0 || compat_iostreams) {
auto format_full_ = detail::string_literal<Char, '(', '{', '}', '+', '{',
'}', 'i', ')'>{};
auto format_neg_ = detail::string_literal<Char, '(', '{', '}', '{', '}',
'i', ')'>{};
auto pformat_full_ = detail::string_literal<Char, '(', '{', '}', ',', '{',
'}', ')'>{};
if (compat_iostreams)
return fmt::format_to(out, basic_string_view<Char>(pformat_full_),
f->nested(c.real()), f->nested(c.imag()));
else if (c.imag() >= 0 /* check format_specs.sign */)
return fmt::format_to(out, basic_string_view<Char>(format_full_),
f->nested(c.real()), f->nested(c.imag()));
else
return fmt::format_to(out, basic_string_view<Char>(format_neg_),
f->nested(c.real()), f->nested(c.imag()));
}
auto format_imag = detail::string_literal<Char, '{', '}', 'i'>{};
return fmt::format_to(out, basic_string_view<Char>(format_imag),
auto format_imag_ = detail::string_literal<Char, '{', '}', 'i'>{};
return fmt::format_to(out, basic_string_view<Char>(format_imag_),
f->nested(c.imag()));
}
};

public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
auto it = ctx.begin();
auto end = ctx.end();
if (it != end && *it == 'p') {
++it;
compat_iostreams_ = 1;
ctx.advance_to(it);
}
return nested_formatter<F, Char>::parse(ctx);
}

template <typename FormatContext>
auto format(const std::complex<F>& c, FormatContext& ctx) const
-> decltype(ctx.out()) {
return this->write_padded(ctx, writer{this, c});
return this->write_padded(ctx, writer{this, c, compat_iostreams_});
}
};

Expand Down
2 changes: 2 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ if (FMT_PEDANTIC)
endif ()
if (HAVE_FNO_EXCEPTIONS_FLAG)
add_library(noexception-test ../src/format.cc noexception-test.cc)
target_compile_features(noexception-test PUBLIC cxx_std_11)
target_include_directories(
noexception-test PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_compile_options(noexception-test PRIVATE -fno-exceptions)
Expand All @@ -171,6 +172,7 @@ if (FMT_PEDANTIC)

# Test that the library compiles without locale.
add_library(nolocale-test ../src/format.cc)
target_compile_features(nolocale-test PUBLIC cxx_std_11)
target_include_directories(
nolocale-test PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_compile_definitions(
Expand Down
26 changes: 26 additions & 0 deletions test/std-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,35 @@ TEST(std_test, thread_id) {

TEST(std_test, complex) {
EXPECT_EQ(fmt::format("{}", std::complex<double>(1, 2.2)), "(1+2.2i)");
EXPECT_EQ(fmt::format("{}", std::complex<double>(1, -2.2)), "(1-2.2i)");
EXPECT_EQ(fmt::format("{}", std::complex<double>(0, 2.2)), "2.2i");
EXPECT_EQ(fmt::format("{}", std::complex<double>(0, -2.2)), "-2.2i");
EXPECT_EQ(fmt::format("{:+}", std::complex<double>(0, 2.2)), "+2.2i");
EXPECT_EQ(fmt::format("{:+}", std::complex<double>(0, -2.2)), "-2.2i");
EXPECT_EQ(fmt::format("{:+}", std::complex<double>(1, -2.2)), "(+1-2.2i)");
//EXPECT_EQ(fmt::format("{:+}", std::complex<double>(1, 2.2)), "(+1+2.2i)"); // TODO
//EXPECT_EQ(fmt::format("{: }", std::complex<double>(1, 2.2)), "( 1+2.2i)"); // TODO
EXPECT_EQ(fmt::format("{: }", std::complex<double>(1, -2.2)), "( 1-2.2i)");
EXPECT_EQ(fmt::format("{:>20.2f}", std::complex<double>(1, 2.2)),
" (1.00+2.20i)");
EXPECT_EQ(fmt::format("{:<20.2f}", std::complex<double>(1, 2.2)),
"(1.00+2.20i) ");
EXPECT_EQ(fmt::format("{:<20.2f}", std::complex<double>(1, -2.2)),
"(1.00-2.20i) ");
// :p
EXPECT_EQ(fmt::format("{:>p}", std::complex<double>(1, 2.2)), "(1,2.2)");
EXPECT_EQ(fmt::format("{:>p}", std::complex<double>(1, -2.2)), "(1,-2.2)");
EXPECT_EQ(fmt::format("{:>p}", std::complex<double>(0, 2.2)), "(0,2.2)");
EXPECT_EQ(fmt::format("{:>p}", std::complex<double>(2.2, 0)), "(2.2,0)");
EXPECT_EQ(fmt::format("{:>p}", std::complex<double>(0, 0)), "(0,0)");
// :p + format + align
EXPECT_EQ(fmt::format("{:p<20.2f}", std::complex<double>(1, 2.2)),
"(1.00,2.20) ");
EXPECT_EQ(fmt::format("{:p+<20.2f}", std::complex<double>(1, 2.2)),
"(1.00,2.20) ");
// TODO
// *
// i or j
}

#ifdef __cpp_lib_source_location
Expand Down
Loading