Implement <filesystem>

This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.

Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).

The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).

Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.

In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@338093 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2018-07-27 03:07:09 +00:00
parent 47d2a98a33
commit a0866c5fb5
178 changed files with 3978 additions and 3161 deletions

View File

@@ -107,6 +107,10 @@ option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON)
cmake_dependent_option(LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY cmake_dependent_option(LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY
"Install libc++experimental.a" ON "Install libc++experimental.a" ON
"LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY;LIBCXX_INSTALL_LIBRARY" OFF) "LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY;LIBCXX_INSTALL_LIBRARY" OFF)
cmake_dependent_option(LIBCXX_INSTALL_FILESYSTEM_LIBRARY
"Install libc++fs.a" ON
"LIBCXX_ENABLE_FILESYSTEM_LIBRARY;LIBCXX_INSTALL_LIBRARY" OFF)
if (FUCHSIA) if (FUCHSIA)
set(DEFAULT_ABI_VERSION 2) set(DEFAULT_ABI_VERSION 2)
else() else()

View File

@@ -242,11 +242,15 @@ libc++experimental Specific Options
.. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL .. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL
**Default**: ``LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY`` **Default**: ``ON``
Build filesystem as part of libc++experimental.a. This allows filesystem Build filesystem as a standalone library libc++fs.a.
to be disabled without turning off the entire experimental library.
.. option:: LIBCXX_INSTALL_FILESYSTEM_LIBRARY:BOOL
**Default**: ``LIBCXX_ENABLE_FILESYSTEM AND LIBCXX_INSTALL_LIBRARY``
Install libc++fs.a alongside libc++.
.. _ABI Library Specific Options: .. _ABI Library Specific Options:

View File

@@ -49,6 +49,24 @@ An example of using ``LD_LIBRARY_PATH``:
$ export LD_LIBRARY_PATH=<libcxx-install-prefix>/lib $ export LD_LIBRARY_PATH=<libcxx-install-prefix>/lib
$ ./a.out # Searches for libc++ along LD_LIBRARY_PATH $ ./a.out # Searches for libc++ along LD_LIBRARY_PATH
Using ``<filesystem>`` and libc++fs
====================================
Libc++ provides the implementation of the filesystem library in a separate
library. Users of ``<filesystem>`` and ``<experimental/filesystem>`` are
required to link ``-lc++fs``.
.. note::
Prior to libc++ 7.0, users of ``<experimental/filesystem>`` were required
to link libc++experimental.
.. warning::
The Filesystem library is still experimental in nature. As such normal
guarantees about ABI stability and backwards compatibility do not yet apply
to it. In the future, this restriction will be removed.
Using libc++experimental and ``<experimental/...>`` Using libc++experimental and ``<experimental/...>``
===================================================== =====================================================
@@ -65,6 +83,9 @@ installed. For information on building libc++experimental from source see
:ref:`Building Libc++ <build instructions>` and :ref:`Building Libc++ <build instructions>` and
:ref:`libc++experimental CMake Options <libc++experimental options>`. :ref:`libc++experimental CMake Options <libc++experimental options>`.
Note that as of libc++ 7.0 using the ``<experimental/filesystem>`` requires linking
libc++fs instead of libc++experimental.
Also see the `Experimental Library Implementation Status <http://libcxx.llvm.org/ts1z_status.html>`__ Also see the `Experimental Library Implementation Status <http://libcxx.llvm.org/ts1z_status.html>`__
page. page.

View File

@@ -43,6 +43,18 @@
# endif # endif
#endif #endif
#ifndef _LIBCPP_STD_VER
# if __cplusplus <= 201103L
# define _LIBCPP_STD_VER 11
# elif __cplusplus <= 201402L
# define _LIBCPP_STD_VER 14
# elif __cplusplus <= 201703L
# define _LIBCPP_STD_VER 17
# else
# define _LIBCPP_STD_VER 18 // current year, or date of c++2a ratification
# endif
#endif // _LIBCPP_STD_VER
#if defined(__ELF__) #if defined(__ELF__)
# define _LIBCPP_OBJECT_FORMAT_ELF 1 # define _LIBCPP_OBJECT_FORMAT_ELF 1
#elif defined(__MACH__) #elif defined(__MACH__)
@@ -462,6 +474,19 @@ namespace std {
} }
} }
#if _LIBCPP_STD_VER >= 17
#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
_LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
#else
#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
_LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem {
#endif
#define _LIBCPP_END_NAMESPACE_FILESYSTEM \
_LIBCPP_END_NAMESPACE_STD } }
#define _VSTD_FS _VSTD::__fs::filesystem
#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer) #if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer)
#define _LIBCPP_HAS_NO_ASAN #define _LIBCPP_HAS_NO_ASAN
#endif #endif
@@ -959,18 +984,6 @@ template <unsigned> struct __static_assert_check {};
#define _LIBCPP_WCTYPE_IS_MASK #define _LIBCPP_WCTYPE_IS_MASK
#endif #endif
#ifndef _LIBCPP_STD_VER
# if __cplusplus <= 201103L
# define _LIBCPP_STD_VER 11
# elif __cplusplus <= 201402L
# define _LIBCPP_STD_VER 14
# elif __cplusplus <= 201703L
# define _LIBCPP_STD_VER 17
# else
# define _LIBCPP_STD_VER 18 // current year, or date of c++2a ratification
# endif
#endif // _LIBCPP_STD_VER
#if _LIBCPP_STD_VER > 11 #if _LIBCPP_STD_VER > 11
# define _LIBCPP_DEPRECATED [[deprecated]] # define _LIBCPP_DEPRECATED [[deprecated]]
#else #else

View File

@@ -52,8 +52,6 @@
#define _VSTD_CORO _VSTD_EXPERIMENTAL::coroutines_v1 #define _VSTD_CORO _VSTD_EXPERIMENTAL::coroutines_v1
#define _VSTD_FS ::std::experimental::filesystem::v1
#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD \ #define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD \
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 { _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 {

File diff suppressed because it is too large Load Diff

2682
include/filesystem Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -38,6 +38,7 @@ public:
bool is_open() const; bool is_open() const;
basic_filebuf* open(const char* s, ios_base::openmode mode); basic_filebuf* open(const char* s, ios_base::openmode mode);
basic_filebuf* open(const string& s, ios_base::openmode mode); basic_filebuf* open(const string& s, ios_base::openmode mode);
basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17
basic_filebuf* close(); basic_filebuf* close();
protected: protected:
@@ -77,6 +78,8 @@ public:
basic_ifstream(); basic_ifstream();
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
explicit basic_ifstream(const filesystem::path& p,
ios_base::openmode mode = ios_base::in); // C++17
basic_ifstream(basic_ifstream&& rhs); basic_ifstream(basic_ifstream&& rhs);
basic_ifstream& operator=(basic_ifstream&& rhs); basic_ifstream& operator=(basic_ifstream&& rhs);
@@ -86,6 +89,8 @@ public:
bool is_open() const; bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::in); void open(const char* s, ios_base::openmode mode = ios_base::in);
void open(const string& s, ios_base::openmode mode = ios_base::in); void open(const string& s, ios_base::openmode mode = ios_base::in);
void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17
void close(); void close();
}; };
@@ -110,6 +115,8 @@ public:
basic_ofstream(); basic_ofstream();
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
explicit basic_ofstream(const filesystem::path& p,
ios_base::openmode mode = ios_base::out); // C++17
basic_ofstream(basic_ofstream&& rhs); basic_ofstream(basic_ofstream&& rhs);
basic_ofstream& operator=(basic_ofstream&& rhs); basic_ofstream& operator=(basic_ofstream&& rhs);
@@ -119,6 +126,9 @@ public:
bool is_open() const; bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::out); void open(const char* s, ios_base::openmode mode = ios_base::out);
void open(const string& s, ios_base::openmode mode = ios_base::out); void open(const string& s, ios_base::openmode mode = ios_base::out);
void open(const filesystem::path& p,
ios_base::openmode mode = ios_base::out); // C++17
void close(); void close();
}; };
@@ -143,6 +153,8 @@ public:
basic_fstream(); basic_fstream();
explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
explicit basic_fstream(const filesystem::path& p,
ios_base::openmode mode = ios_base::in|ios_base::out); C++17
basic_fstream(basic_fstream&& rhs); basic_fstream(basic_fstream&& rhs);
basic_fstream& operator=(basic_fstream&& rhs); basic_fstream& operator=(basic_fstream&& rhs);
@@ -152,6 +164,9 @@ public:
bool is_open() const; bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
void open(const filesystem::path& s,
ios_base::openmode mode = ios_base::in|ios_base::out); // C++17
void close(); void close();
}; };
@@ -171,6 +186,7 @@ typedef basic_fstream<wchar_t> wfstream;
#include <__locale> #include <__locale>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <filesystem>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header #pragma GCC system_header
@@ -219,6 +235,12 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
basic_filebuf* open(const string& __s, ios_base::openmode __mode); basic_filebuf* open(const string& __s, ios_base::openmode __mode);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) {
return open(__p.c_str(), __mode);
}
#endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
basic_filebuf* __open(int __fd, ios_base::openmode __mode); basic_filebuf* __open(int __fd, ios_base::openmode __mode);
#endif #endif
@@ -1128,6 +1150,11 @@ public:
#endif #endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in); explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
: basic_ifstream(__p.c_str(), __mode) {}
#endif // _LIBCPP_STD_VER >= 17
#endif #endif
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
@@ -1149,6 +1176,13 @@ public:
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in); void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
#endif #endif
void open(const string& __s, ios_base::openmode __mode = ios_base::in); void open(const string& __s, ios_base::openmode __mode = ios_base::in);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
void open(const filesystem::path& __p,
ios_base::openmode __mode = ios_base::in) {
return open(__p.c_str(), __mode);
}
#endif // _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
void __open(int __fd, ios_base::openmode __mode); void __open(int __fd, ios_base::openmode __mode);
@@ -1329,6 +1363,13 @@ public:
#endif #endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out); explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
: basic_ofstream(__p.c_str(), __mode) {}
#endif // _LIBCPP_STD_VER >= 17
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
basic_ofstream(basic_ofstream&& __rhs); basic_ofstream(basic_ofstream&& __rhs);
@@ -1350,6 +1391,12 @@ public:
#endif #endif
void open(const string& __s, ios_base::openmode __mode = ios_base::out); void open(const string& __s, ios_base::openmode __mode = ios_base::out);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
{ return open(__p.c_str(), __mode); }
#endif // _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
void __open(int __fd, ios_base::openmode __mode); void __open(int __fd, ios_base::openmode __mode);
#endif #endif
@@ -1530,6 +1577,13 @@ public:
#endif #endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
: basic_fstream(__p.c_str(), __mode) {}
#endif // _LIBCPP_STD_VER >= 17
#endif #endif
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
@@ -1551,6 +1605,13 @@ public:
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#endif #endif
void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in|ios_base::out)
{ return open(__p.c_str(), __mode); }
#endif // _LIBCPP_STD_VER >= 17
#endif #endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
void close(); void close();

View File

@@ -264,6 +264,10 @@ module std [system] {
header "exception" header "exception"
export * export *
} }
module filesystem {
header "filesystem"
export *
}
module forward_list { module forward_list {
header "forward_list" header "forward_list"
export initializer_list export initializer_list

View File

@@ -291,12 +291,43 @@ endif()
# Add a meta-target for both libraries. # Add a meta-target for both libraries.
add_custom_target(cxx DEPENDS cxx-headers ${LIBCXX_BUILD_TARGETS}) add_custom_target(cxx DEPENDS cxx-headers ${LIBCXX_BUILD_TARGETS})
if (LIBCXX_ENABLE_FILESYSTEM)
set(LIBCXX_FILESYSTEM_SOURCES
../src/filesystem/operations.cpp
../src/filesystem/directory_iterator.cpp)
# Filesystem uses __int128_t, which requires a definition of __muloi4 when
# compiled with UBSAN. This definition is not provided by libgcc_s, but is
# provided by compiler-rt. So we need to disable it to avoid having multiple
# definitions. See filesystem/int128_builtins.cpp.
if (NOT LIBCXX_USE_COMPILER_RT)
list(APPEND LIBCXX_FILESYSTEM_SOURCES ../src/filesystem/int128_builtins.cpp)
endif()
add_library(cxx_filesystem STATIC ${LIBCXX_FILESYSTEM_SOURCES})
if (LIBCXX_ENABLE_SHARED)
target_link_libraries(cxx_filesystem cxx_shared)
else()
target_link_libraries(cxx_filesystem cxx_static)
endif()
set(filesystem_flags "${LIBCXX_COMPILE_FLAGS}")
check_flag_supported(-std=c++14)
if (NOT MSVC AND LIBCXX_SUPPORTS_STD_EQ_CXX14_FLAG)
string(REPLACE "-std=c++11" "-std=c++14" filesystem_flags "${LIBCXX_COMPILE_FLAGS}")
endif()
set_target_properties(cxx_filesystem
PROPERTIES
COMPILE_FLAGS "${filesystem_flags}"
OUTPUT_NAME "c++fs"
)
endif()
if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
file(GLOB LIBCXX_EXPERIMENTAL_SOURCES ../src/experimental/*.cpp) file(GLOB LIBCXX_EXPERIMENTAL_SOURCES ../src/experimental/*.cpp)
if (LIBCXX_ENABLE_FILESYSTEM) add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES})
file(GLOB LIBCXX_FILESYSTEM_SOURCES ../src/experimental/filesystem/*.cpp)
endif()
add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES} ${LIBCXX_FILESYSTEM_SOURCES})
if (LIBCXX_ENABLE_SHARED) if (LIBCXX_ENABLE_SHARED)
target_link_libraries(cxx_experimental cxx_shared) target_link_libraries(cxx_experimental cxx_shared)
else() else()
@@ -315,6 +346,7 @@ if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
) )
endif() endif()
if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY) if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
file(GLOB LIBCXX_EXTERNAL_THREADING_SUPPORT_SOURCES ../test/support/external_threads.cpp) file(GLOB LIBCXX_EXTERNAL_THREADING_SUPPORT_SOURCES ../test/support/external_threads.cpp)
@@ -362,10 +394,13 @@ if (LIBCXX_ENABLE_SHARED AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
endif() endif()
if (LIBCXX_INSTALL_LIBRARY) if (LIBCXX_INSTALL_LIBRARY)
if (LIBCXX_INSTALL_FILESYSTEM_LIBRARY)
set(filesystem_lib cxx_filesystem)
endif()
if (LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY) if (LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY)
set(experimental_lib cxx_experimental) set(experimental_lib cxx_experimental)
endif() endif()
install(TARGETS ${LIBCXX_INSTALL_TARGETS} ${experimental_lib} install(TARGETS ${LIBCXX_INSTALL_TARGETS} ${filesystem_lib} ${experimental_lib}
LIBRARY DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT cxx LIBRARY DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT cxx
ARCHIVE DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT cxx ARCHIVE DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT cxx
) )
@@ -385,6 +420,9 @@ if (NOT CMAKE_CONFIGURATION_TYPES AND (LIBCXX_INSTALL_LIBRARY OR
if(LIBCXX_INSTALL_LIBRARY) if(LIBCXX_INSTALL_LIBRARY)
set(lib_install_target cxx) set(lib_install_target cxx)
endif() endif()
if (LIBCXX_INSTALL_FILESYSTEM_LIBRARY)
set(filesystem_lib_install_target cxx_filesystem)
endif()
if (LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY) if (LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY)
set(experimental_lib_install_target cxx_experimental) set(experimental_lib_install_target cxx_experimental)
endif() endif()
@@ -394,6 +432,7 @@ if (NOT CMAKE_CONFIGURATION_TYPES AND (LIBCXX_INSTALL_LIBRARY OR
add_custom_target(install-cxx add_custom_target(install-cxx
DEPENDS ${lib_install_target} DEPENDS ${lib_install_target}
${experimental_lib_install_target} ${experimental_lib_install_target}
${filesystem_lib_install_target}
${header_install_target} ${header_install_target}
COMMAND "${CMAKE_COMMAND}" COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=cxx -DCMAKE_INSTALL_COMPONENT=cxx
@@ -401,6 +440,7 @@ if (NOT CMAKE_CONFIGURATION_TYPES AND (LIBCXX_INSTALL_LIBRARY OR
add_custom_target(install-cxx-stripped add_custom_target(install-cxx-stripped
DEPENDS ${lib_install_target} DEPENDS ${lib_install_target}
${experimental_lib_install_target} ${experimental_lib_install_target}
${filesystem_lib_install_target}
${header_install_target} ${header_install_target}
COMMAND "${CMAKE_COMMAND}" COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=cxx -DCMAKE_INSTALL_COMPONENT=cxx

View File

@@ -7,7 +7,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "experimental/filesystem" #include "filesystem"
#include "__config" #include "__config"
#if defined(_LIBCPP_WIN32API) #if defined(_LIBCPP_WIN32API)
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@@ -19,7 +19,7 @@
#include "filesystem_common.h" #include "filesystem_common.h"
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail { namespace detail {
namespace { namespace {
@@ -56,8 +56,8 @@ static file_type get_file_type(DirEntT *ent, long) {
return file_type::none; return file_type::none;
} }
static pair<string_view, file_type> static pair<string_view, file_type> posix_readdir(DIR* dir_stream,
posix_readdir(DIR *dir_stream, error_code& ec) { error_code& ec) {
struct dirent* dir_entry_ptr = nullptr; struct dirent* dir_entry_ptr = nullptr;
errno = 0; // zero errno in order to detect errors errno = 0; // zero errno in order to detect errors
ec.clear(); ec.clear();
@@ -97,12 +97,11 @@ using detail::ErrorHandler;
#if defined(_LIBCPP_WIN32API) #if defined(_LIBCPP_WIN32API)
class __dir_stream { class __dir_stream {
public: public:
__dir_stream() = delete; __dir_stream() = delete;
__dir_stream& operator=(const __dir_stream&) = delete; __dir_stream& operator=(const __dir_stream&) = delete;
__dir_stream(__dir_stream&& __ds) noexcept __dir_stream(__dir_stream&& __ds) noexcept : __stream_(__ds.__stream_),
: __stream_(__ds.__stream_), __root_(move(__ds.__root_)), __root_(move(__ds.__root_)),
__entry_(move(__ds.__entry_)) { __entry_(move(__ds.__entry_)) {
__ds.__stream_ = INVALID_HANDLE_VALUE; __ds.__stream_ = INVALID_HANDLE_VALUE;
} }
@@ -169,18 +168,14 @@ public:
__dir_stream() = delete; __dir_stream() = delete;
__dir_stream& operator=(const __dir_stream&) = delete; __dir_stream& operator=(const __dir_stream&) = delete;
__dir_stream(__dir_stream&& other) noexcept __dir_stream(__dir_stream&& other) noexcept : __stream_(other.__stream_),
: __stream_(other.__stream_), __root_(move(other.__root_)), __root_(move(other.__root_)),
__entry_(move(other.__entry_)) __entry_(move(other.__entry_)) {
{
other.__stream_ = nullptr; other.__stream_ = nullptr;
} }
__dir_stream(const path& root, directory_options opts, error_code& ec) __dir_stream(const path& root, directory_options opts, error_code& ec)
: __stream_(nullptr), : __stream_(nullptr), __root_(root) {
__root_(root)
{
if ((__stream_ = ::opendir(root.c_str())) == nullptr) { if ((__stream_ = ::opendir(root.c_str())) == nullptr) {
ec = detail::capture_errno(); ec = detail::capture_errno();
const bool allow_eacess = const bool allow_eacess =
@@ -192,8 +187,10 @@ public:
advance(ec); advance(ec);
} }
~__dir_stream() noexcept ~__dir_stream() noexcept {
{ if (__stream_) close(); } if (__stream_)
close();
}
bool good() const noexcept { return __stream_ != nullptr; } bool good() const noexcept { return __stream_ != nullptr; }
@@ -214,6 +211,7 @@ public:
} }
} }
} }
private: private:
error_code close() noexcept { error_code close() noexcept {
error_code m_ec; error_code m_ec;
@@ -224,6 +222,7 @@ private:
} }
DIR* __stream_{nullptr}; DIR* __stream_{nullptr};
public: public:
path __root_; path __root_;
directory_entry __entry_; directory_entry __entry_;
@@ -233,8 +232,7 @@ public:
// directory_iterator // directory_iterator
directory_iterator::directory_iterator(const path& p, error_code* ec, directory_iterator::directory_iterator(const path& p, error_code* ec,
directory_options opts) directory_options opts) {
{
ErrorHandler<void> err("directory_iterator::directory_iterator(...)", ec, &p); ErrorHandler<void> err("directory_iterator::directory_iterator(...)", ec, &p);
error_code m_ec; error_code m_ec;
@@ -248,8 +246,7 @@ directory_iterator::directory_iterator(const path& p, error_code *ec,
} }
} }
directory_iterator& directory_iterator::__increment(error_code *ec) directory_iterator& directory_iterator::__increment(error_code* ec) {
{
_LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator"); _LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator");
ErrorHandler<void> err("directory_iterator::operator++()", ec); ErrorHandler<void> err("directory_iterator::operator++()", ec);
@@ -261,7 +258,6 @@ directory_iterator& directory_iterator::__increment(error_code *ec)
err.report(m_ec, "at root \"%s\"", root); err.report(m_ec, "at root \"%s\"", root);
} }
return *this; return *this;
} }
directory_entry const& directory_iterator::__dereference() const { directory_entry const& directory_iterator::__dereference() const {
@@ -276,10 +272,9 @@ struct recursive_directory_iterator::__shared_imp {
directory_options __options_; directory_options __options_;
}; };
recursive_directory_iterator::recursive_directory_iterator(const path& p, recursive_directory_iterator::recursive_directory_iterator(
directory_options opt, error_code *ec) const path& p, directory_options opt, error_code* ec)
: __imp_(nullptr), __rec_(true) : __imp_(nullptr), __rec_(true) {
{
ErrorHandler<void> err("recursive_directory_iterator", ec, &p); ErrorHandler<void> err("recursive_directory_iterator", ec, &p);
error_code m_ec; error_code m_ec;
@@ -294,10 +289,10 @@ recursive_directory_iterator::recursive_directory_iterator(const path& p,
__imp_->__stack_.push(move(new_s)); __imp_->__stack_.push(move(new_s));
} }
void recursive_directory_iterator::__pop(error_code* ec) void recursive_directory_iterator::__pop(error_code* ec) {
{
_LIBCPP_ASSERT(__imp_, "Popping the end iterator"); _LIBCPP_ASSERT(__imp_, "Popping the end iterator");
if (ec) ec->clear(); if (ec)
ec->clear();
__imp_->__stack_.pop(); __imp_->__stack_.pop();
if (__imp_->__stack_.size() == 0) if (__imp_->__stack_.size() == 0)
__imp_.reset(); __imp_.reset();
@@ -318,9 +313,9 @@ const directory_entry& recursive_directory_iterator::__dereference() const {
} }
recursive_directory_iterator& recursive_directory_iterator&
recursive_directory_iterator::__increment(error_code *ec) recursive_directory_iterator::__increment(error_code* ec) {
{ if (ec)
if (ec) ec->clear(); ec->clear();
if (recursion_pending()) { if (recursion_pending()) {
if (__try_recursion(ec) || (ec && *ec)) if (__try_recursion(ec) || (ec && *ec))
return *this; return *this;
@@ -384,10 +379,11 @@ bool recursive_directory_iterator::__try_recursion(error_code *ec) {
} }
} }
if (m_ec) { if (m_ec) {
const bool allow_eacess = bool(__imp_->__options_ const bool allow_eacess =
& directory_options::skip_permission_denied); bool(__imp_->__options_ & directory_options::skip_permission_denied);
if (m_ec.value() == EACCES && allow_eacess) { if (m_ec.value() == EACCES && allow_eacess) {
if (ec) ec->clear(); if (ec)
ec->clear();
} else { } else {
path at_ent = move(curr_it.__entry_.__p_); path at_ent = move(curr_it.__entry_.__p_);
__imp_.reset(); __imp_.reset();
@@ -397,5 +393,4 @@ bool recursive_directory_iterator::__try_recursion(error_code *ec) {
return false; return false;
} }
_LIBCPP_END_NAMESPACE_FILESYSTEM
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM

View File

@@ -10,7 +10,8 @@
#ifndef FILESYSTEM_COMMON_H #ifndef FILESYSTEM_COMMON_H
#define FILESYSTEM_COMMON_H #define FILESYSTEM_COMMON_H
#include "experimental/__config" #include "__config"
#include "filesystem"
#include "array" #include "array"
#include "chrono" #include "chrono"
#include "cstdlib" #include "cstdlib"
@@ -22,9 +23,7 @@
#include <sys/time.h> // for ::utimes as used in __last_write_time #include <sys/time.h> // for ::utimes as used in __last_write_time
#include <fcntl.h> /* values for fchmodat */ #include <fcntl.h> /* values for fchmodat */
#include <experimental/filesystem> #include "../include/apple_availability.h"
#include "../../include/apple_availability.h"
#if !defined(__APPLE__) #if !defined(__APPLE__)
// We can use the presence of UTIME_OMIT to detect platforms that provide // We can use the presence of UTIME_OMIT to detect platforms that provide
@@ -39,7 +38,7 @@
#pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-function"
#endif #endif
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail { namespace detail {
namespace { namespace {
@@ -405,8 +404,7 @@ bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
#if defined(_LIBCPP_USE_UTIMENSAT) #if defined(_LIBCPP_USE_UTIMENSAT)
bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS, bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
error_code& ec) { error_code& ec) {
if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) {
{
ec = capture_errno(); ec = capture_errno();
return true; return true;
} }
@@ -423,10 +421,9 @@ bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
#endif #endif
} }
} // namespace } // namespace
} // end namespace detail } // end namespace detail
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM _LIBCPP_END_NAMESPACE_FILESYSTEM
#endif // FILESYSTEM_COMMON_H #endif // FILESYSTEM_COMMON_H

View File

@@ -17,7 +17,7 @@
#include "__config" #include "__config"
#include "climits" #include "climits"
#ifndef _LIBCPP_HAS_NO_INT128 #if !defined(_LIBCPP_HAS_NO_INT128)
extern "C" __attribute__((no_sanitize("undefined"))) extern "C" __attribute__((no_sanitize("undefined")))
__int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) { __int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) {

View File

@@ -7,7 +7,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "experimental/filesystem" #include "filesystem"
#include "array" #include "array"
#include "iterator" #include "iterator"
#include "fstream" #include "fstream"
@@ -51,10 +51,10 @@
#endif #endif
#endif #endif
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace { namespace parser namespace {
{ namespace parser {
using string_view_t = path::__string_view; using string_view_t = path::__string_view;
using string_view_pair = pair<string_view_t, string_view_t>; using string_view_pair = pair<string_view_t, string_view_t>;
@@ -76,8 +76,8 @@ struct PathParser {
ParserState State; ParserState State;
private: private:
PathParser(string_view_t P, ParserState State) noexcept PathParser(string_view_t P, ParserState State) noexcept : Path(P),
: Path(P), State(State) {} State(State) {}
public: public:
PathParser(string_view_t P, string_view_t E, unsigned char S) PathParser(string_view_t P, string_view_t E, unsigned char S)
@@ -157,7 +157,8 @@ public:
} }
} }
case PS_InTrailingSep: case PS_InTrailingSep:
return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1, RStart + 1); return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1,
RStart + 1);
case PS_InFilenames: { case PS_InFilenames: {
PosPtr SepEnd = consumeSeparator(RStart, REnd); PosPtr SepEnd = consumeSeparator(RStart, REnd);
if (SepEnd == REnd) if (SepEnd == REnd)
@@ -219,13 +220,9 @@ private:
RawEntry = {}; RawEntry = {};
} }
PosPtr getAfterBack() const noexcept { PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); }
return Path.data() + Path.size();
}
PosPtr getBeforeFront() const noexcept { PosPtr getBeforeFront() const noexcept { return Path.data() - 1; }
return Path.data() - 1;
}
/// \brief Return a pointer to the first character after the currently /// \brief Return a pointer to the first character after the currently
/// lexed element. /// lexed element.
@@ -283,7 +280,8 @@ private:
}; };
string_view_pair separate_filename(string_view_t const& s) { string_view_pair separate_filename(string_view_t const& s) {
if (s == "." || s == ".." || s.empty()) return string_view_pair{s, ""}; if (s == "." || s == ".." || s.empty())
return string_view_pair{s, ""};
auto pos = s.find_last_of('.'); auto pos = s.find_last_of('.');
if (pos == string_view_t::npos || pos == 0) if (pos == string_view_t::npos || pos == 0)
return string_view_pair{s, string_view_t{}}; return string_view_pair{s, string_view_t{}};
@@ -294,12 +292,13 @@ string_view_t createView(PosPtr S, PosPtr E) noexcept {
return {S, static_cast<size_t>(E - S) + 1}; return {S, static_cast<size_t>(E - S) + 1};
} }
}} // namespace parser } // namespace parser
} // namespace
// POSIX HELPERS // POSIX HELPERS
namespace detail { namespace { namespace detail {
namespace {
using value_type = path::value_type; using value_type = path::value_type;
using string_type = path::string_type; using string_type = path::string_type;
@@ -429,8 +428,7 @@ file_status posix_lstat(path const& p, error_code* ec) {
return posix_lstat(p, path_stat, ec); return posix_lstat(p, path_stat, ec);
} }
bool posix_ftruncate(const FileDescriptor& fd, size_t to_size, bool posix_ftruncate(const FileDescriptor& fd, size_t to_size, error_code& ec) {
error_code& ec) {
if (::ftruncate(fd.fd, to_size) == -1) { if (::ftruncate(fd.fd, to_size) == -1) {
ec = capture_errno(); ec = capture_errno();
return true; return true;
@@ -462,7 +460,8 @@ file_status FileDescriptor::refresh_status(error_code& ec) {
m_status = create_file_status(m_ec, name, m_stat, &ec); m_status = create_file_status(m_ec, name, m_stat, &ec);
return m_status; return m_status;
} }
}} // end namespace detail } // namespace
} // end namespace detail
using detail::capture_errno; using detail::capture_errno;
using detail::ErrorHandler; using detail::ErrorHandler;
@@ -512,7 +511,8 @@ void filesystem_error::__create_what(int __num_paths) {
} }
static path __do_absolute(const path& p, path* cwd, error_code* ec) { static path __do_absolute(const path& p, path* cwd, error_code* ec) {
if (ec) ec->clear(); if (ec)
ec->clear();
if (p.is_absolute()) if (p.is_absolute())
return p; return p;
*cwd = __current_path(ec); *cwd = __current_path(ec);
@@ -526,8 +526,7 @@ path __absolute(const path& p, error_code *ec) {
return __do_absolute(p, &cwd, ec); return __do_absolute(p, &cwd, ec);
} }
path __canonical(path const & orig_p, error_code *ec) path __canonical(path const& orig_p, error_code* ec) {
{
path cwd; path cwd;
ErrorHandler<path> err("canonical", ec, &orig_p, &cwd); ErrorHandler<path> err("canonical", ec, &orig_p, &cwd);
@@ -540,8 +539,7 @@ path __canonical(path const & orig_p, error_code *ec)
} }
void __copy(const path& from, const path& to, copy_options options, void __copy(const path& from, const path& to, copy_options options,
error_code *ec) error_code* ec) {
{
ErrorHandler<void> err("copy", ec, &from, &to); ErrorHandler<void> err("copy", ec, &from, &to);
const bool sym_status = bool( const bool sym_status = bool(
@@ -570,7 +568,8 @@ void __copy(const path& from, const path& to, copy_options options,
return err.report(errc::function_not_supported); return err.report(errc::function_not_supported);
} }
if (ec) ec->clear(); if (ec)
ec->clear();
if (is_symlink(f)) { if (is_symlink(f)) {
if (bool(copy_options::skip_symlinks & options)) { if (bool(copy_options::skip_symlinks & options)) {
@@ -581,38 +580,36 @@ void __copy(const path& from, const path& to, copy_options options,
return err.report(errc::file_exists); return err.report(errc::file_exists);
} }
return; return;
} } else if (is_regular_file(f)) {
else if (is_regular_file(f)) {
if (bool(copy_options::directories_only & options)) { if (bool(copy_options::directories_only & options)) {
// do nothing // do nothing
} } else if (bool(copy_options::create_symlinks & options)) {
else if (bool(copy_options::create_symlinks & options)) {
__create_symlink(from, to, ec); __create_symlink(from, to, ec);
} } else if (bool(copy_options::create_hard_links & options)) {
else if (bool(copy_options::create_hard_links & options)) {
__create_hard_link(from, to, ec); __create_hard_link(from, to, ec);
} } else if (is_directory(t)) {
else if (is_directory(t)) {
__copy_file(from, to / from.filename(), options, ec); __copy_file(from, to / from.filename(), options, ec);
} else { } else {
__copy_file(from, to, options, ec); __copy_file(from, to, options, ec);
} }
return; return;
} } else if (is_directory(f) && bool(copy_options::create_symlinks & options)) {
else if (is_directory(f) && bool(copy_options::create_symlinks & options)) {
return err.report(errc::is_a_directory); return err.report(errc::is_a_directory);
} } else if (is_directory(f) && (bool(copy_options::recursive & options) ||
else if (is_directory(f) && (bool(copy_options::recursive & options) ||
copy_options::none == options)) { copy_options::none == options)) {
if (!exists(t)) { if (!exists(t)) {
// create directory to with attributes from 'from'. // create directory to with attributes from 'from'.
__create_directory(to, from, ec); __create_directory(to, from, ec);
if (ec && *ec) { return; } if (ec && *ec) {
return;
}
}
directory_iterator it =
ec ? directory_iterator(from, *ec) : directory_iterator(from);
if (ec && *ec) {
return;
} }
directory_iterator it = ec ? directory_iterator(from, *ec)
: directory_iterator(from);
if (ec && *ec) { return; }
error_code m_ec2; error_code m_ec2;
for (; it != directory_iterator(); it.increment(m_ec2)) { for (; it != directory_iterator(); it.increment(m_ec2)) {
if (m_ec2) { if (m_ec2) {
@@ -620,7 +617,9 @@ void __copy(const path& from, const path& to, copy_options options,
} }
__copy(it->path(), to / it->path().filename(), __copy(it->path(), to / it->path().filename(),
options | copy_options::__in_recursive_copy, ec); options | copy_options::__in_recursive_copy, ec);
if (ec && *ec) { return; } if (ec && *ec) {
return;
}
} }
} }
} }
@@ -628,7 +627,6 @@ void __copy(const path& from, const path& to, copy_options options,
namespace detail { namespace detail {
namespace { namespace {
#ifdef _LIBCPP_USE_SENDFILE #ifdef _LIBCPP_USE_SENDFILE
bool copy_file_impl_sendfile(FileDescriptor& read_fd, FileDescriptor& write_fd, bool copy_file_impl_sendfile(FileDescriptor& read_fd, FileDescriptor& write_fd,
error_code& ec) { error_code& ec) {
@@ -721,8 +719,7 @@ bool copy_file_impl(FileDescriptor& from, FileDescriptor& to, error_code& ec) {
} // namespace detail } // namespace detail
bool __copy_file(const path& from, const path& to, copy_options options, bool __copy_file(const path& from, const path& to, copy_options options,
error_code *ec) error_code* ec) {
{
using detail::FileDescriptor; using detail::FileDescriptor;
ErrorHandler<bool> err("copy_file", ec, &to, &from); ErrorHandler<bool> err("copy_file", ec, &to, &from);
@@ -811,18 +808,18 @@ bool __copy_file(const path& from, const path& to, copy_options options,
} }
void __copy_symlink(const path& existing_symlink, const path& new_symlink, void __copy_symlink(const path& existing_symlink, const path& new_symlink,
error_code *ec) error_code* ec) {
{
const path real_path(__read_symlink(existing_symlink, ec)); const path real_path(__read_symlink(existing_symlink, ec));
if (ec && *ec) { return; } if (ec && *ec) {
return;
}
// NOTE: proposal says you should detect if you should call // NOTE: proposal says you should detect if you should call
// create_symlink or create_directory_symlink. I don't think this // create_symlink or create_directory_symlink. I don't think this
// is needed with POSIX // is needed with POSIX
__create_symlink(real_path, new_symlink, ec); __create_symlink(real_path, new_symlink, ec);
} }
bool __create_directories(const path& p, error_code *ec) bool __create_directories(const path& p, error_code* ec) {
{
ErrorHandler<bool> err("create_directories", ec, &p); ErrorHandler<bool> err("create_directories", ec, &p);
error_code m_ec; error_code m_ec;
@@ -849,8 +846,7 @@ bool __create_directories(const path& p, error_code *ec)
return __create_directory(p, ec); return __create_directory(p, ec);
} }
bool __create_directory(const path& p, error_code *ec) bool __create_directory(const path& p, error_code* ec) {
{
ErrorHandler<bool> err("create_directory", ec, &p); ErrorHandler<bool> err("create_directory", ec, &p);
if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0) if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
@@ -860,9 +856,7 @@ bool __create_directory(const path& p, error_code *ec)
return false; return false;
} }
bool __create_directory(path const & p, path const & attributes, bool __create_directory(path const& p, path const& attributes, error_code* ec) {
error_code *ec)
{
ErrorHandler<bool> err("create_directory", ec, &p, &attributes); ErrorHandler<bool> err("create_directory", ec, &p, &attributes);
StatT attr_stat; StatT attr_stat;
@@ -871,7 +865,8 @@ bool __create_directory(path const & p, path const & attributes,
if (!status_known(st)) if (!status_known(st))
return err.report(mec); return err.report(mec);
if (!is_directory(st)) if (!is_directory(st))
return err.report(errc::not_a_directory, "the specified attribute path is invalid"); return err.report(errc::not_a_directory,
"the specified attribute path is invalid");
if (::mkdir(p.c_str(), attr_stat.st_mode) == 0) if (::mkdir(p.c_str(), attr_stat.st_mode) == 0)
return true; return true;
@@ -919,8 +914,7 @@ void __current_path(const path& p, error_code *ec) {
err.report(capture_errno()); err.report(capture_errno());
} }
bool __equivalent(const path& p1, const path& p2, error_code *ec) bool __equivalent(const path& p1, const path& p2, error_code* ec) {
{
ErrorHandler<bool> err("equivalent", ec, &p1, &p2); ErrorHandler<bool> err("equivalent", ec, &p1, &p2);
error_code ec1, ec2; error_code ec1, ec2;
@@ -935,9 +929,7 @@ bool __equivalent(const path& p1, const path& p2, error_code *ec)
return detail::stat_equivalent(st1, st2); return detail::stat_equivalent(st1, st2);
} }
uintmax_t __file_size(const path& p, error_code* ec) {
uintmax_t __file_size(const path& p, error_code *ec)
{
ErrorHandler<uintmax_t> err("file_size", ec, &p); ErrorHandler<uintmax_t> err("file_size", ec, &p);
error_code m_ec; error_code m_ec;
@@ -954,8 +946,7 @@ uintmax_t __file_size(const path& p, error_code *ec)
return static_cast<uintmax_t>(st.st_size); return static_cast<uintmax_t>(st.st_size);
} }
uintmax_t __hard_link_count(const path& p, error_code *ec) uintmax_t __hard_link_count(const path& p, error_code* ec) {
{
ErrorHandler<uintmax_t> err("hard_link_count", ec, &p); ErrorHandler<uintmax_t> err("hard_link_count", ec, &p);
error_code m_ec; error_code m_ec;
@@ -966,9 +957,7 @@ uintmax_t __hard_link_count(const path& p, error_code *ec)
return static_cast<uintmax_t>(st.st_nlink); return static_cast<uintmax_t>(st.st_nlink);
} }
bool __fs_is_empty(const path& p, error_code* ec) {
bool __fs_is_empty(const path& p, error_code *ec)
{
ErrorHandler<bool> err("is_empty", ec, &p); ErrorHandler<bool> err("is_empty", ec, &p);
error_code m_ec; error_code m_ec;
@@ -1001,8 +990,7 @@ static file_time_type __extract_last_write_time(const path& p, const StatT& st,
return fs_time::convert_from_timespec(ts); return fs_time::convert_from_timespec(ts);
} }
file_time_type __last_write_time(const path& p, error_code *ec) file_time_type __last_write_time(const path& p, error_code* ec) {
{
using namespace chrono; using namespace chrono;
ErrorHandler<file_time_type> err("last_write_time", ec, &p); ErrorHandler<file_time_type> err("last_write_time", ec, &p);
@@ -1014,9 +1002,7 @@ file_time_type __last_write_time(const path& p, error_code *ec)
return __extract_last_write_time(p, st, ec); return __extract_last_write_time(p, st, ec);
} }
void __last_write_time(const path& p, file_time_type new_time, void __last_write_time(const path& p, file_time_type new_time, error_code* ec) {
error_code *ec)
{
using detail::fs_time; using detail::fs_time;
ErrorHandler<void> err("last_write_time", ec, &p); ErrorHandler<void> err("last_write_time", ec, &p);
@@ -1043,10 +1029,8 @@ void __last_write_time(const path& p, file_time_type new_time,
return err.report(m_ec); return err.report(m_ec);
} }
void __permissions(const path& p, perms prms, perm_options opts, void __permissions(const path& p, perms prms, perm_options opts,
error_code *ec) error_code* ec) {
{
ErrorHandler<void> err("permissions", ec, &p); ErrorHandler<void> err("permissions", ec, &p);
auto has_opt = [&](perm_options o) { return bool(o & opts); }; auto has_opt = [&](perm_options o) { return bool(o & opts); };
@@ -1090,7 +1074,6 @@ void __permissions(const path& p, perms prms, perm_options opts,
#endif #endif
} }
path __read_symlink(const path& p, error_code* ec) { path __read_symlink(const path& p, error_code* ec) {
ErrorHandler<path> err("read_symlink", ec, &p); ErrorHandler<path> err("read_symlink", ec, &p);
@@ -1106,7 +1089,6 @@ path __read_symlink(const path& p, error_code *ec) {
return {buff}; return {buff};
} }
bool __remove(const path& p, error_code* ec) { bool __remove(const path& p, error_code* ec) {
ErrorHandler<bool> err("remove", ec, &p); ErrorHandler<bool> err("remove", ec, &p);
if (::remove(p.c_str()) == -1) { if (::remove(p.c_str()) == -1) {
@@ -1119,22 +1101,25 @@ bool __remove(const path& p, error_code *ec) {
namespace { namespace {
uintmax_t remove_all_impl(path const & p, error_code& ec) uintmax_t remove_all_impl(path const& p, error_code& ec) {
{
const auto npos = static_cast<uintmax_t>(-1); const auto npos = static_cast<uintmax_t>(-1);
const file_status st = __symlink_status(p, &ec); const file_status st = __symlink_status(p, &ec);
if (ec) return npos; if (ec)
return npos;
uintmax_t count = 1; uintmax_t count = 1;
if (is_directory(st)) { if (is_directory(st)) {
for (directory_iterator it(p, ec); !ec && it != directory_iterator(); for (directory_iterator it(p, ec); !ec && it != directory_iterator();
it.increment(ec)) { it.increment(ec)) {
auto other_count = remove_all_impl(it->path(), ec); auto other_count = remove_all_impl(it->path(), ec);
if (ec) return npos; if (ec)
return npos;
count += other_count; count += other_count;
} }
if (ec) return npos; if (ec)
return npos;
} }
if (!__remove(p, &ec)) return npos; if (!__remove(p, &ec))
return npos;
return count; return count;
} }
@@ -1219,7 +1204,6 @@ path __temp_directory_path(error_code* ec) {
return p; return p;
} }
path __weakly_canonical(const path& p, error_code* ec) { path __weakly_canonical(const path& p, error_code* ec) {
ErrorHandler<path> err("weakly_canonical", ec, &p); ErrorHandler<path> err("weakly_canonical", ec, &p);
@@ -1248,7 +1232,8 @@ path __weakly_canonical(const path& p, error_code *ec) {
} }
if (PP.State == PathParser::PS_BeforeBegin) if (PP.State == PathParser::PS_BeforeBegin)
result = __canonical("", ec); result = __canonical("", ec);
if (ec) ec->clear(); if (ec)
ec->clear();
if (DNEParts.empty()) if (DNEParts.empty())
return result; return result;
for (auto It = DNEParts.rbegin(); It != DNEParts.rend(); ++It) for (auto It = DNEParts.rbegin(); It != DNEParts.rend(); ++It)
@@ -1262,8 +1247,7 @@ path __weakly_canonical(const path& p, error_code *ec) {
constexpr path::value_type path::preferred_separator; constexpr path::value_type path::preferred_separator;
path & path::replace_extension(path const & replacement) path& path::replace_extension(path const& replacement) {
{
path p = extension(); path p = extension();
if (not p.empty()) { if (not p.empty()) {
__pn_.erase(__pn_.size() - p.native().size()); __pn_.erase(__pn_.size() - p.native().size());
@@ -1280,16 +1264,14 @@ path & path::replace_extension(path const & replacement)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// path.decompose // path.decompose
string_view_t path::__root_name() const string_view_t path::__root_name() const {
{
auto PP = PathParser::CreateBegin(__pn_); auto PP = PathParser::CreateBegin(__pn_);
if (PP.State == PathParser::PS_InRootName) if (PP.State == PathParser::PS_InRootName)
return *PP; return *PP;
return {}; return {};
} }
string_view_t path::__root_directory() const string_view_t path::__root_directory() const {
{
auto PP = PathParser::CreateBegin(__pn_); auto PP = PathParser::CreateBegin(__pn_);
if (PP.State == PathParser::PS_InRootName) if (PP.State == PathParser::PS_InRootName)
++PP; ++PP;
@@ -1298,8 +1280,7 @@ string_view_t path::__root_directory() const
return {}; return {};
} }
string_view_t path::__root_path_raw() const string_view_t path::__root_path_raw() const {
{
auto PP = PathParser::CreateBegin(__pn_); auto PP = PathParser::CreateBegin(__pn_);
if (PP.State == PathParser::PS_InRootName) { if (PP.State == PathParser::PS_InRootName) {
auto NextCh = PP.peek(); auto NextCh = PP.peek();
@@ -1320,16 +1301,14 @@ static bool ConsumeRootDir(PathParser* PP) {
return PP->State == PathParser::PS_AtEnd; return PP->State == PathParser::PS_AtEnd;
} }
string_view_t path::__relative_path() const string_view_t path::__relative_path() const {
{
auto PP = PathParser::CreateBegin(__pn_); auto PP = PathParser::CreateBegin(__pn_);
if (ConsumeRootDir(&PP)) if (ConsumeRootDir(&PP))
return {}; return {};
return createView(PP.RawEntry.data(), &__pn_.back()); return createView(PP.RawEntry.data(), &__pn_.back());
} }
string_view_t path::__parent_path() const string_view_t path::__parent_path() const {
{
if (empty()) if (empty())
return {}; return {};
// Determine if we have a root path but not a relative path. In that case // Determine if we have a root path but not a relative path. In that case
@@ -1351,9 +1330,9 @@ string_view_t path::__parent_path() const
} }
} }
string_view_t path::__filename() const string_view_t path::__filename() const {
{ if (empty())
if (empty()) return {}; return {};
{ {
PathParser PP = PathParser::CreateBegin(__pn_); PathParser PP = PathParser::CreateBegin(__pn_);
if (ConsumeRootDir(&PP)) if (ConsumeRootDir(&PP))
@@ -1362,20 +1341,17 @@ string_view_t path::__filename() const
return *(--PathParser::CreateEnd(__pn_)); return *(--PathParser::CreateEnd(__pn_));
} }
string_view_t path::__stem() const string_view_t path::__stem() const {
{
return parser::separate_filename(__filename()).first; return parser::separate_filename(__filename()).first;
} }
string_view_t path::__extension() const string_view_t path::__extension() const {
{
return parser::separate_filename(__filename()).second; return parser::separate_filename(__filename()).second;
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// path.gen // path.gen
enum PathPartKind : unsigned char { enum PathPartKind : unsigned char {
PK_None, PK_None,
PK_RootSep, PK_RootSep,
@@ -1490,8 +1466,8 @@ path path::lexically_relative(const path& base) const {
auto PP = PathParser::CreateBegin(__pn_); auto PP = PathParser::CreateBegin(__pn_);
auto PPBase = PathParser::CreateBegin(base.__pn_); auto PPBase = PathParser::CreateBegin(base.__pn_);
auto CheckIterMismatchAtBase = [&]() { auto CheckIterMismatchAtBase = [&]() {
return PP.State != PPBase.State && ( return PP.State != PPBase.State &&
PP.inRootPath() || PPBase.inRootPath()); (PP.inRootPath() || PPBase.inRootPath());
}; };
if (PP.State == PathParser::PS_InRootName && if (PP.State == PathParser::PS_InRootName &&
PPBase.State == PathParser::PS_InRootName) { PPBase.State == PathParser::PS_InRootName) {
@@ -1500,8 +1476,10 @@ path path::lexically_relative(const path& base) const {
} else if (CheckIterMismatchAtBase()) } else if (CheckIterMismatchAtBase())
return {}; return {};
if (PP.inRootPath()) ++PP; if (PP.inRootPath())
if (PPBase.inRootPath()) ++PPBase; ++PP;
if (PPBase.inRootPath())
++PPBase;
if (CheckIterMismatchAtBase()) if (CheckIterMismatchAtBase())
return {}; return {};
} }
@@ -1509,8 +1487,7 @@ path path::lexically_relative(const path& base) const {
// Find the first mismatching element // Find the first mismatching element
auto PP = PathParser::CreateBegin(__pn_); auto PP = PathParser::CreateBegin(__pn_);
auto PPBase = PathParser::CreateBegin(base.__pn_); auto PPBase = PathParser::CreateBegin(base.__pn_);
while (PP && PPBase && PP.State == PPBase.State && while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) {
*PP == *PPBase) {
++PP; ++PP;
++PPBase; ++PPBase;
} }
@@ -1543,8 +1520,10 @@ int path::__compare(string_view_t __s) const {
auto PP2 = PathParser::CreateBegin(__s); auto PP2 = PathParser::CreateBegin(__s);
while (PP && PP2) { while (PP && PP2) {
int res = (*PP).compare(*PP2); int res = (*PP).compare(*PP2);
if (res != 0) return res; if (res != 0)
++PP; ++PP2; return res;
++PP;
++PP2;
} }
if (PP.State == PP2.State && !PP) if (PP.State == PP2.State && !PP)
return 0; return 0;
@@ -1568,8 +1547,7 @@ size_t hash_value(const path& __p) noexcept {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// path.itr // path.itr
path::iterator path::begin() const path::iterator path::begin() const {
{
auto PP = PathParser::CreateBegin(__pn_); auto PP = PathParser::CreateBegin(__pn_);
iterator it; iterator it;
it.__path_ptr_ = this; it.__path_ptr_ = this;
@@ -1579,8 +1557,7 @@ path::iterator path::begin() const
return it; return it;
} }
path::iterator path::end() const path::iterator path::end() const {
{
iterator it{}; iterator it{};
it.__state_ = path::iterator::_AtEnd; it.__state_ = path::iterator::_AtEnd;
it.__path_ptr_ = this; it.__path_ptr_ = this;
@@ -1706,4 +1683,4 @@ error_code directory_entry::__do_refresh() noexcept {
} }
#endif #endif
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM _LIBCPP_END_NAMESPACE_FILESYSTEM

View File

@@ -62,6 +62,7 @@
#include <deque> #include <deque>
#include <errno.h> #include <errno.h>
#include <exception> #include <exception>
#include <filesystem>
#include <float.h> #include <float.h>
#include <forward_list> #include <forward_list>
#include <fstream> #include <fstream>

View File

@@ -7,8 +7,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <experimental/filesystem>
#include <experimental/filesystem> #include <experimental/filesystem>

View File

@@ -9,11 +9,11 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry
// RUN: %build -I%libcxx_src_root/src/experimental/filesystem // RUN: %build -I%libcxx_src_root/src/filesystem
// RUN: %run // RUN: %run
#include "filesystem_include.hpp" #include "filesystem_include.hpp"

View File

@@ -13,13 +13,13 @@
// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS // MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
// MODULES_DEFINES: _LIBCPP_DEBUG=0 // MODULES_DEFINES: _LIBCPP_DEBUG=0
// <experimental/filesystem> // <filesystem>
// class path // class path
#define _LIBCPP_DEBUG 0 #define _LIBCPP_DEBUG 0
#define _LIBCPP_DEBUG_USE_EXCEPTIONS #define _LIBCPP_DEBUG_USE_EXCEPTIONS
#include <experimental/filesystem> #include "filesystem_include.hpp"
#include <iterator> #include <iterator>
#include <type_traits> #include <type_traits>
#include <cassert> #include <cassert>
@@ -27,8 +27,6 @@
#include "test_macros.h" #include "test_macros.h"
#include "filesystem_test_helper.hpp" #include "filesystem_test_helper.hpp"
namespace fs = std::experimental::filesystem;
int main() { int main() {
using namespace fs; using namespace fs;
using ExType = std::__libcpp_debug_exception; using ExType = std::__libcpp_debug_exception;

View File

@@ -9,16 +9,14 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path
#include <experimental/filesystem> #include "filesystem_include.hpp"
#include <iterator> #include <iterator>
namespace fs = std::experimental::filesystem;
int main() { int main() {
using namespace fs; using namespace fs;
using RIt = std::reverse_iterator<path::iterator>; using RIt = std::reverse_iterator<path::iterator>;

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// template <class Tp> struct __is_pathable // template <class Tp> struct __is_pathable
@@ -21,7 +21,7 @@
// * A character array, which points to a NTCTS after array-to-pointer decay. // * A character array, which points to a NTCTS after array-to-pointer decay.
#include <experimental/filesystem> #include "filesystem_include.hpp"
#include <type_traits> #include <type_traits>
#include <cassert> #include <cassert>
@@ -30,8 +30,6 @@
#include "min_allocator.h" #include "min_allocator.h"
#include "constexpr_char_traits.hpp" #include "constexpr_char_traits.hpp"
namespace fs = std::experimental::filesystem;
using fs::__is_pathable; using fs::__is_pathable;
template <class Tp> template <class Tp>

View File

@@ -9,14 +9,14 @@
// UNSUPPORTED: c++98, c++03, c++11 // UNSUPPORTED: c++98, c++03, c++11
// <experimental/filesystem> // <filesystem>
// typedef TrivialClock file_time_type; // typedef TrivialClock file_time_type;
// RUN: %build -I%libcxx_src_root/src/experimental/filesystem // RUN: %build -I%libcxx_src_root/src/filesystem
// RUN: %run // RUN: %run
#include <experimental/filesystem> #include <filesystem>
#include <chrono> #include <chrono>
#include <type_traits> #include <type_traits>
#include <limits> #include <limits>
@@ -30,7 +30,7 @@
#endif #endif
using namespace std::chrono; using namespace std::chrono;
namespace fs = std::experimental::filesystem; namespace fs = std::__fs::filesystem;
using fs::file_time_type; using fs::file_time_type;
using fs::detail::time_util; using fs::detail::time_util;

View File

@@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <filesystem>
#include <filesystem>
#ifndef _LIBCPP_VERSION
#error _LIBCPP_VERSION not defined
#endif
int main()
{
}

View File

@@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <fstream>
// basic_filebuf<charT,traits>* open(const filesystem::path& p, ios_base::openmode mode);
#include <fstream>
#include <filesystem>
#include <cassert>
#include "platform_support.h"
namespace fs = std::filesystem;
int main() {
fs::path p = get_temp_file_name();
{
std::filebuf f;
assert(f.open(p, std::ios_base::out) != 0);
assert(f.is_open());
assert(f.sputn("123", 3) == 3);
}
{
std::filebuf f;
assert(f.open(p, std::ios_base::in) != 0);
assert(f.is_open());
assert(f.sbumpc() == '1');
assert(f.sbumpc() == '2');
assert(f.sbumpc() == '3');
}
std::remove(p.c_str());
{
std::wfilebuf f;
assert(f.open(p, std::ios_base::out) != 0);
assert(f.is_open());
assert(f.sputn(L"123", 3) == 3);
}
{
std::wfilebuf f;
assert(f.open(p, std::ios_base::in) != 0);
assert(f.is_open());
assert(f.sbumpc() == L'1');
assert(f.sbumpc() == L'2');
assert(f.sbumpc() == L'3');
}
remove(p.c_str());
}

View File

@@ -0,0 +1,49 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <fstream>
// plate <class charT, class traits = char_traits<charT> >
// class basic_fstream
// explicit basic_fstream(const filesystem::path& s,
// ios_base::openmode mode = ios_base::in|ios_base::out);
#include <fstream>
#include <filesystem>
#include <cassert>
#include "platform_support.h"
namespace fs = std::filesystem;
int main() {
fs::path p = get_temp_file_name();
{
std::fstream fs(p, std::ios_base::in | std::ios_base::out |
std::ios_base::trunc);
double x = 0;
fs << 3.25;
fs.seekg(0);
fs >> x;
assert(x == 3.25);
}
std::remove(p.c_str());
{
std::wfstream fs(p, std::ios_base::in | std::ios_base::out |
std::ios_base::trunc);
double x = 0;
fs << 3.25;
fs.seekg(0);
fs >> x;
assert(x == 3.25);
}
std::remove(p.c_str());
}

View File

@@ -0,0 +1,52 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <fstream>
// plate <class charT, class traits = char_traits<charT> >
// class basic_fstream
// void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in|ios_base::out);
#include <fstream>
#include <filesystem>
#include <cassert>
#include "platform_support.h"
int main() {
std::filesystem::path p = get_temp_file_name();
{
std::fstream stream;
assert(!stream.is_open());
stream.open(p,
std::ios_base::in | std::ios_base::out | std::ios_base::trunc);
assert(stream.is_open());
double x = 0;
stream << 3.25;
stream.seekg(0);
stream >> x;
assert(x == 3.25);
}
std::remove(p.c_str());
{
std::wfstream stream;
assert(!stream.is_open());
stream.open(p,
std::ios_base::in | std::ios_base::out | std::ios_base::trunc);
assert(stream.is_open());
double x = 0;
stream << 3.25;
stream.seekg(0);
stream >> x;
assert(x == 3.25);
}
std::remove(p.c_str());
}

View File

@@ -0,0 +1,53 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <fstream>
// template <class charT, class traits = char_traits<charT> >
// class basic_ifstream
// explicit basic_ifstream(const filesystem::path& s,
// ios_base::openmode mode = ios_base::in);
#include <fstream>
#include <filesystem>
#include <cassert>
namespace fs = std::filesystem;
int main() {
{
fs::path p;
static_assert(!std::is_convertible<fs::path, std::ifstream>::value,
"ctor should be explicit");
static_assert(std::is_constructible<std::ifstream, fs::path const&,
std::ios_base::openmode>::value,
"");
}
{
std::ifstream fs(fs::path("test.dat"));
double x = 0;
fs >> x;
assert(x == 3.25);
}
// std::ifstream(const fs::path&, std::ios_base::openmode) is tested in
// test/std/input.output/file.streams/fstreams/ofstream.cons/string.pass.cpp
// which creates writable files.
{
std::wifstream fs(fs::path("test.dat"));
double x = 0;
fs >> x;
assert(x == 3.25);
}
// std::wifstream(const fs::path&, std::ios_base::openmode) is tested in
// test/std/input.output/file.streams/fstreams/ofstream.cons/string.pass.cpp
// which creates writable files.
}

View File

@@ -0,0 +1,48 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <fstream>
// template <class charT, class traits = char_traits<charT> >
// class basic_ifstream
// void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in);
#include <fstream>
#include <filesystem>
#include <cassert>
int main() {
{
std::ifstream fs;
assert(!fs.is_open());
char c = 'a';
fs >> c;
assert(fs.fail());
assert(c == 'a');
fs.open(std::filesystem::path("test.dat"));
assert(fs.is_open());
fs >> c;
assert(c == 'r');
}
{
std::wifstream fs;
assert(!fs.is_open());
wchar_t c = L'a';
fs >> c;
assert(fs.fail());
assert(c == L'a');
fs.open(std::filesystem::path("test.dat"));
assert(fs.is_open());
fs >> c;
assert(c == L'r');
}
}

View File

@@ -0,0 +1,69 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <fstream>
// plate <class charT, class traits = char_traits<charT> >
// class basic_ofstream
// explicit basic_ofstream(const filesystem::path& s, ios_base::openmode mode = ios_base::out);
#include <fstream>
#include <filesystem>
#include <cassert>
#include "platform_support.h"
namespace fs = std::filesystem;
int main() {
fs::path p = get_temp_file_name();
{
static_assert(!std::is_convertible<fs::path, std::ofstream>::value,
"ctor should be explicit");
static_assert(std::is_constructible<std::ofstream, fs::path const&,
std::ios_base::openmode>::value,
"");
}
{
std::ofstream stream(p);
stream << 3.25;
}
{
std::ifstream stream(p);
double x = 0;
stream >> x;
assert(x == 3.25);
}
{
std::ifstream stream(p, std::ios_base::out);
double x = 0;
stream >> x;
assert(x == 3.25);
}
std::remove(p.c_str());
{
std::wofstream stream(p);
stream << 3.25;
}
{
std::wifstream stream(p);
double x = 0;
stream >> x;
assert(x == 3.25);
}
{
std::wifstream stream(p, std::ios_base::out);
double x = 0;
stream >> x;
assert(x == 3.25);
}
std::remove(p.c_str());
}

View File

@@ -0,0 +1,62 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <fstream>
// plate <class charT, class traits = char_traits<charT> >
// class basic_ofstream
// void open(const filesystem::path& s, ios_base::openmode mode = ios_base::out);
#include <fstream>
#include <filesystem>
#include <cassert>
#include "platform_support.h"
namespace fs = std::filesystem;
int main() {
fs::path p = get_temp_file_name();
{
std::ofstream fs;
assert(!fs.is_open());
char c = 'a';
fs << c;
assert(fs.fail());
fs.open(p);
assert(fs.is_open());
fs << c;
}
{
std::ifstream fs(p.c_str());
char c = 0;
fs >> c;
assert(c == 'a');
}
std::remove(p.c_str());
{
std::wofstream fs;
assert(!fs.is_open());
wchar_t c = L'a';
fs << c;
assert(fs.fail());
fs.open(p);
assert(fs.is_open());
fs << c;
}
{
std::wifstream fs(p.c_str());
wchar_t c = 0;
fs >> c;
assert(c == L'a');
}
std::remove(p.c_str());
}

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// XFAIL: apple-clang-7, clang-3.7, clang-3.8 // XFAIL: apple-clang-7, clang-3.7, clang-3.8
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_entry // class directory_entry

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_iterator // class directory_iterator

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_iterator // class directory_iterator

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_iterator // class directory_iterator

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_iterator // class directory_iterator

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_iterator // class directory_iterator

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_iterator // class directory_iterator

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_iterator // class directory_iterator

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_iterator // class directory_iterator

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class directory_iterator // class directory_iterator

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class file_status // class file_status

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class file_status // class file_status

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class file_status // class file_status

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class filesystem_error // class filesystem_error

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -8,7 +8,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -9,7 +9,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// <experimental/filesystem> // <filesystem>
// class path // class path

Some files were not shown because too many files have changed in this diff Show More