diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -17,7 +17,7 @@ "`3120 `__","Unclear behavior of ``monotonic_buffer_resource::release()``","November 2020","","" "`3170 `__","``is_always_equal`` added to ``std::allocator`` makes the standard library treat derived types as always equal","November 2020","","" "`3036 `__","``polymorphic_allocator::destroy`` is extraneous","November 2020","","" -"`3171 `__","LWG2989 breaks ``directory_entry`` stream insertion","November 2020","","" +"`3171 `__","LWG2989 breaks ``directory_entry`` stream insertion","November 2020","|Complete|","14.0" "`3306 `__","``ranges::advance`` violates its preconditions","November 2020","","","|ranges|" "`3403 `__","Domain of ``ranges::ssize(E)`` doesn't ``match ranges::size(E)``","November 2020","","","|ranges|" "`3404 `__","Finish removing subrange's conversions from pair-like","November 2020","","","|ranges|" diff --git a/libcxx/include/__filesystem/directory_entry.h b/libcxx/include/__filesystem/directory_entry.h --- a/libcxx/include/__filesystem/directory_entry.h +++ b/libcxx/include/__filesystem/directory_entry.h @@ -23,6 +23,7 @@ #include #include #include +#include #include _LIBCPP_PUSH_MACROS @@ -239,6 +240,12 @@ return __p_ >= __rhs.__p_; } + template + _LIBCPP_INLINE_VISIBILITY + friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { + return __os << __d.path(); + } + private: friend class directory_iterator; friend class recursive_directory_iterator; diff --git a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp --- a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp +++ b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp @@ -89,6 +89,8 @@ test ('X', chars, chars+10, L"0X1X2X3X4X5X6X7X8X9"); test ('x', ints, ints+10, L"10x11x12x13x14x15x16x17x18x19"); #endif + // TODO(var-const): uncomment when it becomes possible to instantiate a `basic_ostream` object with a sized + // character type (see https://github.com/llvm/llvm-project/issues/53119). // test('X', chars, chars+10, u"0X1X2X3X4X5X6X7X8X9"); // test('x', ints, ints+10, u"10x11x12x13x14x15x16x17x18x19"); // test('X', chars, chars+10, U"0X1X2X3X4X5X6X7X8X9"); diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.io/directory_entry.io.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.io/directory_entry.io.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.io/directory_entry.io.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 +// UNSUPPORTED: libcpp-has-no-localization + +// +// +// class directory_entry +// +// template +// friend basic_ostream& +// operator<<(basic_ostream& os, const directory_entry& d); + +#include "filesystem_include.h" +#include +#include + +#include "test_macros.h" +#include "make_string.h" + +MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789"); +MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\""); + +template +void TestOutput() { + using namespace fs; + + const char* input = static_cast(InStr); + const CharT* expected_output = static_cast(OutStr); + directory_entry dir{path(input)}; + std::basic_stringstream stream; + + auto& result = stream << dir; + assert(stream.str() == expected_output); + assert(&result == &stream); +} + +int main(int, char**) { + TestOutput(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + TestOutput(); +#endif + // TODO(var-const): uncomment when it becomes possible to instantiate a `basic_ostream` object with a sized character + // type (see https://github.com/llvm/llvm-project/issues/53119). + //TestOutput(); + //TestOutput(); + //TestOutput(); + + return 0; +} diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp --- a/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp @@ -94,6 +94,8 @@ #ifndef TEST_HAS_NO_WIDE_CHARACTERS doIOTest(); #endif + // TODO(var-const): uncomment when it becomes possible to instantiate a `basic_ostream` object with a sized character + // type (see https://github.com/llvm/llvm-project/issues/53119). //doIOTest(); //doIOTest(); test_LWG2989();