Skip to content

Commit

Permalink
P3142R0: Printing Blank Lines with println (#4611)
Browse files Browse the repository at this point in the history
Co-authored-by: Hristo Hristov <[email protected]>
Co-authored-by: Stephan T. Lavavej <[email protected]>
  • Loading branch information
3 people authored Apr 26, 2024
1 parent d74be47 commit 34917ee
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 6 deletions.
5 changes: 5 additions & 0 deletions stl/inc/ostream
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,11 @@ void println(ostream& _Ostr, const format_string<_Types...> _Fmt, _Types&&... _A
_STD _Print_impl(_Add_newline::_Yes, _Ostr, _Fmt, _STD forward<_Types>(_Args)...);
}

_EXPORT_STD template <int = 0> // improves throughput, see GH-2329
void println(ostream& _Ostr) {
_STD print(_Ostr, "\n");
}

_EXPORT_STD template <int = 0> // improves throughput, see GH-2329
void vprint_unicode(ostream& _Ostr, const string_view _Fmt_str, const format_args _Fmt_args) {
_STD _Vprint_unicode_impl(_Add_newline::_Nope, _Ostr, _Fmt_str, _Fmt_args);
Expand Down
10 changes: 10 additions & 0 deletions stl/inc/print
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ void println(FILE* const _Stream, const format_string<_Types...> _Fmt, _Types&&.
_STD _Print_impl(_Add_newline::_Yes, _Stream, _Fmt, _STD forward<_Types>(_Args)...);
}

_EXPORT_STD template <int = 0> // improves throughput, see GH-2329
void println(FILE* _Stream) {
_STD print(_Stream, "\n");
}

_EXPORT_STD template <int = 0> // improves throughput, see GH-2329
void println() {
_STD println(stdout);
}

_EXPORT_STD template <class... _Types>
void println(const format_string<_Types...> _Fmt, _Types&&... _Args) {
_STD println(stdout, _Fmt, _STD forward<_Types>(_Args)...);
Expand Down
1 change: 1 addition & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@
// P2713R1 Escaping Improvements In std::format
// P2763R1 Fixing layout_stride's Default Constructor For Fully Static Extents
// P2836R1 basic_const_iterator Should Follow Its Underlying Type's Convertibility
// P3142R0 Printing Blank Lines With println()

// _HAS_CXX23 and _SILENCE_ALL_CXX23_DEPRECATION_WARNINGS control:
// P1413R3 Deprecate aligned_storage And aligned_union
Expand Down
2 changes: 2 additions & 0 deletions tests/std/include/test_header_units_and_modules.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,9 +545,11 @@ void test_print() {
using namespace std;
puts("Testing <print>.");
println("Hello, world!");
println();

#ifdef _CPPRTTI
println(cout, "The answer to life, the universe, and everything: {}", 42);
println(cout);
#endif // _CPPRTTI
}
#endif // TEST_STANDARD >= 23
Expand Down
66 changes: 60 additions & 6 deletions tests/std/tests/P2093R14_formatted_output/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,17 +403,19 @@ void test_invalid_code_points_console() {
test_invalid_sequence_closure("\xF0\x28\x8C\x25");
}

FILE* checked_fopen_s(const string& filename, const char* const mode) {
FILE* ret;
const errno_t fopen_result = fopen_s(&ret, filename.c_str(), mode);
assert(fopen_result == 0);
return ret;
}

void test_invalid_code_points_file() {
// Unlike for the console API when the ordinary literal encoding is UTF-8, invalid code points shouldn't
// be replaced when writing to a file.
const string temp_file_name_str = temp_file_name();

FILE* temp_file_stream;

{
const errno_t fopen_result = fopen_s(&temp_file_stream, temp_file_name_str.c_str(), "w+b");
assert(fopen_result == 0);
}
FILE* temp_file_stream = checked_fopen_s(temp_file_name_str, "w+b");

using printed_string_type = format_string<>;

Expand Down Expand Up @@ -509,6 +511,38 @@ void test_stream_flush_console() {
const wstring extractedStr{temp_console.get_console_line(0)};
assert(extractedStr == L"Hello, world!");
}

print(console_file_stream, "kitty");
println(console_file_stream);
println(console_file_stream, "cat");

{
const wstring line0{temp_console.get_console_line(0)};
const wstring line1{temp_console.get_console_line(1)};
const wstring line2{temp_console.get_console_line(2)};

assert(line0 == L"Hello, world!");

if constexpr (_Is_ordinary_literal_encoding_utf8()) {
assert(line1 == L"kitty");
assert(line2 == L"cat");
} else {
assert(line1.empty());
assert(line2.empty());
}
}

maybe_flush_console_file_stream(temp_console);

{
const wstring line0{temp_console.get_console_line(0)};
const wstring line1{temp_console.get_console_line(1)};
const wstring line2{temp_console.get_console_line(2)};

assert(line0 == L"Hello, world!");
assert(line1 == L"kitty");
assert(line2 == L"cat");
}
}

void test_stream_flush_file() {
Expand Down Expand Up @@ -567,13 +601,28 @@ void test_empty_strings_and_newlines() {
print(output_file_stream, "-D\n");
print(output_file_stream, "{{}} for {}!\n", "impact");

println(output_file_stream);
println(output_file_stream, "I have {} cute {} kittens.", 1729, "fluffy");
println(output_file_stream, "");
println(output_file_stream, "What are an orthodontist's favorite characters? '{{' and '}}', of course!");
println(output_file_stream, "ONE\nTWO\n");
println(output_file_stream, "THREE");
}

{
FILE* temp_file_stream = checked_fopen_s(temp_file_name_str, "a");

print(temp_file_stream, "space");
print(temp_file_stream, "");
print(temp_file_stream, "time\n");

println(temp_file_stream, "general");
println(temp_file_stream);
println(temp_file_stream, "relativity");

fclose(temp_file_stream);
}

{
ifstream input_file_stream{temp_file_name_str};

Expand All @@ -585,13 +634,18 @@ void test_empty_strings_and_newlines() {
const vector<string> expected_lines{
"NCC-1701-D",
"{} for impact!",
"",
"I have 1729 cute fluffy kittens.",
"",
"What are an orthodontist's favorite characters? '{' and '}', of course!",
"ONE",
"TWO",
"",
"THREE",
"spacetime",
"general",
"",
"relativity",
};

assert(lines == expected_lines);
Expand Down

0 comments on commit 34917ee

Please sign in to comment.