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/include/filesystem b/libcxx/include/filesystem --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -42,8 +42,14 @@ path u8path(InputIterator first, InputIterator last); class filesystem_error; + class directory_entry; + // The fs.dir.entry.io operator is a friend of directory_entry. + template + friend basic_ostream& + operator<<(basic_ostream& os, const directory_entry& d); + class directory_iterator; // enable directory_iterator range-based for statements 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); + path p(input); + std::basic_stringstream stream; + + auto& result = stream << p; + 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. Currently the instantiation would fail because `ctype` only has specializations for `char` and `wchar_t`. + //TestOutput(); + //TestOutput(); + //TestOutput(); + + return 0; +}