[libcxx] r273034 - Add Filesystem TS -- Complete
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 17 12:46:42 PDT 2016
Author: ericwf
Date: Fri Jun 17 14:46:40 2016
New Revision: 273034
URL: http://llvm.org/viewvc/llvm-project?rev=273034&view=rev
Log:
Add Filesystem TS -- Complete
Add the completed std::experimental::filesystem implementation and tests.
The implementation supports C++11 or newer.
The TS is built as part of 'libc++experimental.a'. Users of the TS need to
manually link this library. Building and testing the TS can be disabled using
the CMake option '-DLIBCXX_ENABLE_FILESYSTEM=OFF'.
Currently 'libc++experimental.a' is not installed by default. To turn on the
installation of the library use '-DLIBCXX_INSTALL_EXPERIMENTAL_LIBRARY=ON'.
Added:
libcxx/trunk/include/experimental/filesystem
libcxx/trunk/src/experimental/filesystem/
libcxx/trunk/src/experimental/filesystem/directory_iterator.cpp
libcxx/trunk/src/experimental/filesystem/operations.cpp
libcxx/trunk/src/experimental/filesystem/path.cpp
libcxx/trunk/test/libcxx/experimental/filesystem/
libcxx/trunk/test/libcxx/experimental/filesystem/class.path/
libcxx/trunk/test/libcxx/experimental/filesystem/class.path/path.req/
libcxx/trunk/test/libcxx/experimental/filesystem/class.path/path.req/is_pathable.pass.cpp
libcxx/trunk/test/libcxx/experimental/filesystem/lit.local.cfg
libcxx/trunk/test/libcxx/experimental/filesystem/version.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/
libcxx/trunk/test/std/experimental/filesystem/Inputs/
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink (with props)
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/afile3
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/file5
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/file4
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 (with props)
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file1
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/empty_file
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir (with props)
libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file (with props)
libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/
libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/
libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.file_status/
libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.filesystem_error/
libcxx/trunk/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.itr/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.decompose/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.query/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.path/synop.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.enum/
libcxx/trunk/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp
libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.error.report/
libcxx/trunk/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.filesystem.synopsis/
libcxx/trunk/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.req.macros/
libcxx/trunk/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/fs.req.namespace/
libcxx/trunk/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp
libcxx/trunk/test/std/experimental/filesystem/lit.local.cfg
libcxx/trunk/test/support/filesystem_dynamic_test_helper.py
libcxx/trunk/test/support/filesystem_test_helper.hpp
libcxx/trunk/test/support/rapid-cxx-test.hpp
libcxx/trunk/test/support/test_convertible.hpp
libcxx/trunk/test/support/test_convertible_header.pass.cpp
Modified:
libcxx/trunk/CMakeLists.txt
libcxx/trunk/docs/BuildingLibcxx.rst
libcxx/trunk/include/experimental/__config
libcxx/trunk/include/iomanip
libcxx/trunk/lib/CMakeLists.txt
libcxx/trunk/test/CMakeLists.txt
libcxx/trunk/test/libcxx/test/config.py
libcxx/trunk/test/lit.site.cfg.in
libcxx/trunk/test/support/count_new.hpp
libcxx/trunk/test/support/min_allocator.h
libcxx/trunk/test/support/test_macros.h
libcxx/trunk/www/ts1z_status.html
Modified: libcxx/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/CMakeLists.txt?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/CMakeLists.txt (original)
+++ libcxx/trunk/CMakeLists.txt Fri Jun 17 14:46:40 2016
@@ -53,6 +53,8 @@ MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
option(LIBCXX_ENABLE_ASSERTIONS "Enable assertions independent of build mode." ON)
option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ON)
+option(LIBCXX_ENABLE_FILESYSTEM
+ "Build filesystem as part of libc++experimental.a" ${LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY})
option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
option(LIBCXX_INCLUDE_DOCS "Build the libc++ documentation." ${LLVM_INCLUDE_DOCS})
set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING
@@ -166,6 +168,11 @@ option(LIBCXX_CONFIGURE_IDE "Configure l
# Check option configurations
#===============================================================================
+if (LIBCXX_ENABLE_FILESYSTEM AND NOT LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
+ message(FATAL_ERROR
+ "LIBCXX_ENABLE_FILESYSTEM cannot be turned on when LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF")
+endif()
+
# Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON only when
# LIBCXX_ENABLE_THREADS is on.
if(LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK)
@@ -302,7 +309,7 @@ add_compile_flags_if_supported(-nostdinc
add_definitions(-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
add_compile_flags_if_supported(
-Wall -W -Wwrite-strings
- -Wno-unused-parameter -Wno-long-long
+ -Wno-unused-parameter -Wno-long-long -Wno-user-defined-literals
-Werror=return-type)
if (LIBCXX_ENABLE_WERROR)
add_compile_flags_if_supported(-Werror)
Modified: libcxx/trunk/docs/BuildingLibcxx.rst
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/docs/BuildingLibcxx.rst?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/docs/BuildingLibcxx.rst (original)
+++ libcxx/trunk/docs/BuildingLibcxx.rst Fri Jun 17 14:46:40 2016
@@ -177,6 +177,14 @@ libc++experimental Specific Options
Install libc++experimental.a alongside libc++.
+.. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL
+
+ **Default**: ``LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY``
+
+ Build filesystem as part of libc++experimental.a. This allows filesystem
+ to be disabled without turning off the entire experimental library.
+
+
.. _ABI Library Specific Options:
ABI Library Specific Options
Modified: libcxx/trunk/include/experimental/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/__config?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/include/experimental/__config (original)
+++ libcxx/trunk/include/experimental/__config Fri Jun 17 14:46:40 2016
@@ -33,4 +33,14 @@
namespace chrono { namespace experimental { inline namespace fundamentals_v1 {
#define _LIBCPP_END_NAMESPACE_CHRONO_LFTS _LIBCPP_END_NAMESPACE_STD } } }
+#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM \
+ _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace filesystem { \
+ inline namespace v1 {
+
+#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM \
+ } } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
+
+
+#define _VSTD_FS ::std::experimental::filesystem::v1
+
#endif
Added: libcxx/trunk/include/experimental/filesystem
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/filesystem?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/include/experimental/filesystem (added)
+++ libcxx/trunk/include/experimental/filesystem Fri Jun 17 14:46:40 2016
@@ -0,0 +1,2050 @@
+// -*- C++ -*-
+//===--------------------------- filesystem -------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_EXPERIMENTAL_FILESYSTEM
+#define _LIBCPP_EXPERIMENTAL_FILESYSTEM
+/*
+ filesystem synopsis
+
+ namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
+
+ class path;
+
+ void swap(path& lhs, path& rhs) _NOEXCEPT;
+ size_t hash_value(const path& p) _NOEXCEPT;
+
+ bool operator==(const path& lhs, const path& rhs) _NOEXCEPT;
+ bool operator!=(const path& lhs, const path& rhs) _NOEXCEPT;
+ bool operator< (const path& lhs, const path& rhs) _NOEXCEPT;
+ bool operator<=(const path& lhs, const path& rhs) _NOEXCEPT;
+ bool operator> (const path& lhs, const path& rhs) _NOEXCEPT;
+ bool operator>=(const path& lhs, const path& rhs) _NOEXCEPT;
+
+ path operator/ (const path& lhs, const path& rhs);
+
+ template <class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const path& p);
+
+ template <class charT, class traits>
+ basic_istream<charT, traits>&
+ operator>>(basic_istream<charT, traits>& is, path& p);
+
+ template <class Source>
+ path u8path(const Source& source);
+ template <class InputIterator>
+ path u8path(InputIterator first, InputIterator last);
+
+ class filesystem_error;
+ class directory_entry;
+
+ class directory_iterator;
+
+ // enable directory_iterator range-based for statements
+ directory_iterator begin(directory_iterator iter) noexcept;
+ directory_iterator end(const directory_iterator&) noexcept;
+
+ class recursive_directory_iterator;
+
+ // enable recursive_directory_iterator range-based for statements
+ recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
+ recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
+
+ class file_status;
+
+ struct space_info
+ {
+ uintmax_t capacity;
+ uintmax_t free;
+ uintmax_t available;
+ };
+
+ enum class file_type;
+ enum class perms;
+ enum class copy_options;
+ enum class directory_options;
+
+ typedef chrono::time_point<trivial-clock> file_time_type;
+
+ // operational functions
+
+ path absolute(const path& p, const path& base=current_path());
+
+ path canonical(const path& p, const path& base = current_path());
+ path canonical(const path& p, error_code& ec);
+ path canonical(const path& p, const path& base, error_code& ec);
+
+ void copy(const path& from, const path& to);
+ void copy(const path& from, const path& to, error_code& ec) _NOEXCEPT;
+ 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) _NOEXCEPT;
+
+ bool copy_file(const path& from, const path& to);
+ bool copy_file(const path& from, const path& to, error_code& ec) _NOEXCEPT;
+ bool copy_file(const path& from, const path& to, copy_options option);
+ bool copy_file(const path& from, const path& to, copy_options option,
+ error_code& ec) _NOEXCEPT;
+
+ 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) _NOEXCEPT;
+
+ bool create_directories(const path& p);
+ bool create_directories(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool create_directory(const path& p);
+ bool create_directory(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool create_directory(const path& p, const path& attributes);
+ bool create_directory(const path& p, const path& attributes,
+ error_code& ec) _NOEXCEPT;
+
+ void create_directory_symlink(const path& to, const path& new_symlink);
+ void create_directory_symlink(const path& to, const path& new_symlink,
+ error_code& ec) _NOEXCEPT;
+
+ void create_hard_link(const path& to, const path& new_hard_link);
+ void create_hard_link(const path& to, const path& new_hard_link,
+ error_code& ec) _NOEXCEPT;
+
+ void create_symlink(const path& to, const path& new_symlink);
+ void create_symlink(const path& to, const path& new_symlink,
+ error_code& ec) _NOEXCEPT;
+
+ path current_path();
+ path current_path(error_code& ec);
+ void current_path(const path& p);
+ void current_path(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool exists(file_status s) _NOEXCEPT;
+ bool exists(const path& p);
+ bool exists(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool equivalent(const path& p1, const path& p2);
+ bool equivalent(const path& p1, const path& p2, error_code& ec) _NOEXCEPT;
+
+ uintmax_t file_size(const path& p);
+ uintmax_t file_size(const path& p, error_code& ec) _NOEXCEPT;
+
+ uintmax_t hard_link_count(const path& p);
+ uintmax_t hard_link_count(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool is_block_file(file_status s) _NOEXCEPT;
+ bool is_block_file(const path& p);
+ bool is_block_file(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool is_character_file(file_status s) _NOEXCEPT;
+ bool is_character_file(const path& p);
+ bool is_character_file(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool is_directory(file_status s) _NOEXCEPT;
+ bool is_directory(const path& p);
+ bool is_directory(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool is_empty(const path& p);
+ bool is_empty(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool is_fifo(file_status s) _NOEXCEPT;
+ bool is_fifo(const path& p);
+ bool is_fifo(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool is_other(file_status s) _NOEXCEPT;
+ bool is_other(const path& p);
+ bool is_other(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool is_regular_file(file_status s) _NOEXCEPT;
+ bool is_regular_file(const path& p);
+ bool is_regular_file(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool is_socket(file_status s) _NOEXCEPT;
+ bool is_socket(const path& p);
+ bool is_socket(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool is_symlink(file_status s) _NOEXCEPT;
+ bool is_symlink(const path& p);
+ bool is_symlink(const path& p, error_code& ec) _NOEXCEPT;
+
+ file_time_type last_write_time(const path& p);
+ file_time_type last_write_time(const path& p, error_code& ec) _NOEXCEPT;
+ 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) _NOEXCEPT;
+
+ void permissions(const path& p, perms prms);
+ void permissions(const path& p, perms prms, error_code& ec) _NOEXCEPT;
+
+ path read_symlink(const path& p);
+ path read_symlink(const path& p, error_code& ec);
+
+ bool remove(const path& p);
+ bool remove(const path& p, error_code& ec) _NOEXCEPT;
+
+ uintmax_t remove_all(const path& p);
+ uintmax_t remove_all(const path& p, error_code& ec) _NOEXCEPT;
+
+ void rename(const path& from, const path& to);
+ void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT;
+
+ void resize_file(const path& p, uintmax_t size);
+ void resize_file(const path& p, uintmax_t size, error_code& ec) _NOEXCEPT;
+
+ space_info space(const path& p);
+ space_info space(const path& p, error_code& ec) _NOEXCEPT;
+
+ file_status status(const path& p);
+ file_status status(const path& p, error_code& ec) _NOEXCEPT;
+
+ bool status_known(file_status s) _NOEXCEPT;
+
+ file_status symlink_status(const path& p);
+ file_status symlink_status(const path& p, error_code& ec) _NOEXCEPT;
+
+ path system_complete(const path& p);
+ path system_complete(const path& p, error_code& ec);
+
+ path temp_directory_path();
+ path temp_directory_path(error_code& ec);
+
+} } } } // namespaces std::experimental::filesystem::v1
+
+*/
+
+#include <experimental/__config>
+#include <cstddef>
+#include <chrono>
+#include <iterator>
+#include <iosfwd>
+#include <locale>
+#include <memory>
+#include <stack>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <iomanip> // for quoted
+#include <experimental/string_view>
+
+#include <__debug>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#define __cpp_lib_experimental_filesystem 201406
+
+_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
+
+typedef chrono::time_point<std::chrono::system_clock> file_time_type;
+
+struct _LIBCPP_TYPE_VIS space_info
+{
+ uintmax_t capacity;
+ uintmax_t free;
+ uintmax_t available;
+};
+
+enum class _LIBCPP_TYPE_VIS file_type : signed char
+{
+ none = 0,
+ not_found = -1,
+ regular = 1,
+ directory = 2,
+ symlink = 3,
+ block = 4,
+ character = 5,
+ fifo = 6,
+ socket = 7,
+ unknown = 8
+};
+
+enum class _LIBCPP_TYPE_VIS perms : unsigned
+{
+ none = 0,
+
+ owner_read = 0400,
+ owner_write = 0200,
+ owner_exec = 0100,
+ owner_all = 0700,
+
+ group_read = 040,
+ group_write = 020,
+ group_exec = 010,
+ group_all = 070,
+
+ others_read = 04,
+ others_write = 02,
+ others_exec = 01,
+ others_all = 07,
+
+ all = 0777,
+
+ set_uid = 04000,
+ set_gid = 02000,
+ sticky_bit = 01000,
+ mask = 07777,
+ unknown = 0xFFFF,
+
+ add_perms = 0x10000,
+ remove_perms = 0x20000,
+ resolve_symlinks = 0x40000
+};
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS)
+{ return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS)
+{ return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS)
+{ return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS)
+{ return static_cast<perms>(~static_cast<unsigned>(_LHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline perms& operator&=(perms& _LHS, perms _RHS)
+{ return _LHS = _LHS & _RHS; }
+
+_LIBCPP_INLINE_VISIBILITY
+inline perms& operator|=(perms& _LHS, perms _RHS)
+{ return _LHS = _LHS | _RHS; }
+
+_LIBCPP_INLINE_VISIBILITY
+inline perms& operator^=(perms& _LHS, perms _RHS)
+{ return _LHS = _LHS ^ _RHS; }
+
+enum class _LIBCPP_TYPE_VIS copy_options : unsigned short
+{
+ none = 0,
+ skip_existing = 1,
+ overwrite_existing = 2,
+ update_existing = 4,
+ recursive = 8,
+ copy_symlinks = 16,
+ skip_symlinks = 32,
+ directories_only = 64,
+ create_symlinks = 128,
+ create_hard_links = 256,
+ __in_recursive_copy = 512,
+};
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS)
+{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS)
+{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS)
+{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS)
+{ return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS)
+{ return _LHS = _LHS & _RHS; }
+
+_LIBCPP_INLINE_VISIBILITY
+inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS)
+{ return _LHS = _LHS | _RHS; }
+
+_LIBCPP_INLINE_VISIBILITY
+inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS)
+{ return _LHS = _LHS ^ _RHS; }
+
+
+enum class directory_options : unsigned char
+{
+ none = 0,
+ follow_directory_symlink = 1,
+ skip_permission_denied = 2
+};
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS)
+{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS)
+{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS)
+{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS)
+{ return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); }
+
+_LIBCPP_INLINE_VISIBILITY
+inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS)
+{ return _LHS = _LHS & _RHS; }
+
+_LIBCPP_INLINE_VISIBILITY
+inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS)
+{ return _LHS = _LHS | _RHS; }
+
+_LIBCPP_INLINE_VISIBILITY
+inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS)
+{ return _LHS = _LHS ^ _RHS; }
+
+
+class _LIBCPP_TYPE_VIS file_status
+{
+public:
+ // constructors
+ _LIBCPP_INLINE_VISIBILITY
+ explicit file_status(file_type __ft = file_type::none,
+ perms __prms = perms::unknown) _NOEXCEPT
+ : __ft_(__ft), __prms_(__prms)
+ {}
+
+ file_status(const file_status&) _NOEXCEPT = default;
+ file_status(file_status&&) _NOEXCEPT = default;
+
+ _LIBCPP_INLINE_VISIBILITY
+ ~file_status() {}
+
+ file_status& operator=(const file_status&) _NOEXCEPT = default;
+ file_status& operator=(file_status&&) _NOEXCEPT = default;
+
+ // observers
+ _LIBCPP_ALWAYS_INLINE
+ file_type type() const _NOEXCEPT {
+ return __ft_;
+ }
+
+ _LIBCPP_ALWAYS_INLINE
+ perms permissions() const _NOEXCEPT {
+ return __prms_;
+ }
+
+ // modifiers
+ _LIBCPP_ALWAYS_INLINE
+ void type(file_type __ft) _NOEXCEPT {
+ __ft_ = __ft;
+ }
+
+ _LIBCPP_ALWAYS_INLINE
+ void permissions(perms __p) _NOEXCEPT {
+ __prms_ = __p;
+ }
+private:
+ file_type __ft_;
+ perms __prms_;
+};
+
+class _LIBCPP_TYPE_VIS directory_entry;
+
+template <class _Tp> struct __can_convert_char {
+ static const bool value = false;
+};
+template <> struct __can_convert_char<char> {
+ static const bool value = true;
+ using __char_type = char;
+};
+template <> struct __can_convert_char<wchar_t> {
+ static const bool value = true;
+ using __char_type = wchar_t;
+};
+template <> struct __can_convert_char<char16_t> {
+ static const bool value = true;
+ using __char_type = char16_t;
+};
+template <> struct __can_convert_char<char32_t> {
+ static const bool value = true;
+ using __char_type = char32_t;
+};
+
+template <class _ECharT>
+typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
+__is_separator(_ECharT __e) {
+ return __e == _ECharT('/');
+};
+
+struct _NullSentinal {};
+
+template <class _Tp>
+using _Void = void;
+
+template <class _Tp, class = void>
+struct __is_pathable_string : public false_type {};
+
+template <class _ECharT, class _Traits, class _Alloc>
+struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>,
+ _Void<typename __can_convert_char<_ECharT>::__char_type>>
+: public __can_convert_char<_ECharT>
+{
+ using _Str = basic_string<_ECharT, _Traits, _Alloc>;
+ using _Base = __can_convert_char<_ECharT>;
+ static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
+ static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
+ static _ECharT __first_or_null(_Str const& __s) {
+ return __s.empty() ? _ECharT{} : __s[0];
+ }
+};
+
+template <class _Source,
+ class _DS = typename decay<_Source>::type,
+ class _UnqualPtrType = typename remove_const<
+ typename remove_pointer<_DS>::type>::type,
+ bool _IsCharPtr = is_pointer<_DS>::value &&
+ __can_convert_char<_UnqualPtrType>::value
+ >
+struct __is_pathable_char_array : false_type {};
+
+template <class _Source, class _ECharT, class _UPtr>
+struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
+ : __can_convert_char<typename remove_const<_ECharT>::type>
+{
+ using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
+
+ static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
+ static _ECharT const* __range_end(const _ECharT* __b)
+ {
+ using _Iter = const _ECharT*;
+ const _ECharT __sentinal = _ECharT{};
+ _Iter __e = __b;
+ for (; *__e != __sentinal; ++__e)
+ ;
+ return __e;
+ }
+
+ static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
+};
+
+template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void>
+struct __is_pathable_iter : false_type {};
+
+template <class _Iter>
+struct __is_pathable_iter<_Iter, true,
+ _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>>
+ : __can_convert_char<typename iterator_traits<_Iter>::value_type>
+{
+ using _ECharT = typename iterator_traits<_Iter>::value_type;
+ using _Base = __can_convert_char<_ECharT>;
+
+ static _Iter __range_begin(_Iter __b) { return __b; }
+ static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; }
+
+ static _ECharT __first_or_null(_Iter __b) { return *__b; }
+};
+
+template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
+ bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
+ bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value
+ >
+struct __is_pathable : false_type {
+ static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
+};
+
+template <class _Tp>
+struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
+
+
+template <class _Tp>
+struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {};
+
+
+template <class _Tp>
+struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
+
+
+template <class _ECharT>
+struct _PathCVT {
+ static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible");
+
+ typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower;
+
+ static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e) {
+ _Narrower()(back_inserter(__dest), __b, __e);
+ }
+
+ template <class _Iter>
+ static void __append_range(string& __dest, _Iter __b, _Iter __e) {
+ static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
+ if (__b == __e) return;
+ basic_string<_ECharT> __tmp(__b, __e);
+ _Narrower()(back_inserter(__dest), __tmp.data(),
+ __tmp.data() + __tmp.length());
+ }
+
+ template <class _Iter>
+ static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
+ static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
+ const _ECharT __sentinal = _ECharT{};
+ if (*__b == __sentinal) return;
+ basic_string<_ECharT> __tmp;
+ for (; *__b != __sentinal; ++__b)
+ __tmp.push_back(*__b);
+ _Narrower()(back_inserter(__dest), __tmp.data(),
+ __tmp.data() + __tmp.length());
+ }
+
+ template <class _Source>
+ static void __append_source(string& __dest, _Source const& __s)
+ {
+ using _Traits = __is_pathable<_Source>;
+ __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
+ }
+};
+
+template <>
+struct _PathCVT<char> {
+ template <class _Iter>
+ static void __append_range(string& __dest, _Iter __b, _Iter __e) {
+ for (; __b != __e; ++__b)
+ __dest.push_back(*__b);
+ }
+
+ template <class _Iter>
+ static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
+ const char __sentinal = char{};
+ for (; *__b != __sentinal; ++__b)
+ __dest.push_back(*__b);
+ }
+
+ template <class _Source>
+ static void __append_source(string& __dest, _Source const& __s)
+ {
+ using _Traits = __is_pathable<_Source>;
+ __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
+ }
+};
+
+
+class _LIBCPP_TYPE_VIS path
+{
+ template <class _SourceOrIter, class _Tp = path&>
+ using _EnableIfPathable = typename
+ enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
+
+ template <class _Tp>
+ using _SourceChar = typename __is_pathable<_Tp>::__char_type;
+
+ template <class _Tp>
+ using _SourceCVT = _PathCVT<_SourceChar<_Tp>>;
+
+public:
+ typedef char value_type;
+ typedef basic_string<value_type> string_type;
+ static _LIBCPP_CONSTEXPR value_type preferred_separator = '/';
+
+ // constructors and destructor
+ _LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {}
+ _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
+ _LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {}
+
+ _LIBCPP_INLINE_VISIBILITY
+ path(string_type&& __s) _NOEXCEPT : __pn_(_VSTD::move(__s)) {}
+
+ template <
+ class _Source,
+ class = _EnableIfPathable<_Source, void>
+ >
+ path(const _Source& __src) {
+ _SourceCVT<_Source>::__append_source(__pn_, __src);
+ }
+
+ template <class _InputIt>
+ path(_InputIt __first, _InputIt __last) {
+ typedef typename iterator_traits<_InputIt>::value_type _ItVal;
+ _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
+ }
+
+ // TODO Implement locale conversions.
+ template <class _Source,
+ class = _EnableIfPathable<_Source, void>
+ >
+ path(const _Source& __src, const locale& __loc);
+ template <class _InputIt>
+ path(_InputIt __first, _InputIt _last, const locale& __loc);
+
+ _LIBCPP_INLINE_VISIBILITY
+ ~path() = default;
+
+ // assignments
+ _LIBCPP_INLINE_VISIBILITY
+ path& operator=(const path& __p) {
+ __pn_ = __p.__pn_;
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ path& operator=(path&& __p) _NOEXCEPT {
+ __pn_ = _VSTD::move(__p.__pn_);
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ path& operator=(string_type&& __s) _NOEXCEPT {
+ __pn_ = _VSTD::move(__s);
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ path& assign(string_type&& __s) _NOEXCEPT {
+ __pn_ = _VSTD::move(__s);
+ return *this;
+ }
+
+ template <class _Source>
+ _LIBCPP_INLINE_VISIBILITY
+ _EnableIfPathable<_Source>
+ operator=(const _Source& __src)
+ { return this->assign(__src); }
+
+
+ template <class _Source>
+ _EnableIfPathable<_Source>
+ assign(const _Source& __src) {
+ __pn_.clear();
+ _SourceCVT<_Source>::__append_source(__pn_, __src);
+ return *this;
+ }
+
+ template <class _InputIt>
+ path& assign(_InputIt __first, _InputIt __last) {
+ typedef typename iterator_traits<_InputIt>::value_type _ItVal;
+ __pn_.clear();
+ _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
+ return *this;
+ }
+
+private:
+ template <class _ECharT>
+ void __append_sep_if_needed(_ECharT __first_or_null) {
+ const _ECharT __null_val = {};
+ bool __append_sep = !empty() &&
+ !__is_separator(__pn_.back()) &&
+ __first_or_null != __null_val && // non-empty
+ !__is_separator(__first_or_null);
+ if (__append_sep)
+ __pn_ += preferred_separator;
+ }
+
+public:
+ // appends
+ path& operator/=(const path& __p) {
+ __append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]);
+ __pn_ += __p.native();
+ return *this;
+ }
+
+ template <class _Source>
+ _LIBCPP_INLINE_VISIBILITY
+ _EnableIfPathable<_Source>
+ operator/=(const _Source& __src) {
+ return this->append(__src);
+ }
+
+ template <class _Source>
+ _EnableIfPathable<_Source>
+ append(const _Source& __src) {
+ using _Traits = __is_pathable<_Source>;
+ using _CVT = _PathCVT<_SourceChar<_Source>>;
+ __append_sep_if_needed(_Traits::__first_or_null(__src));
+ _CVT::__append_source(__pn_, __src);
+ return *this;
+ }
+
+ template <class _InputIt>
+ path& append(_InputIt __first, _InputIt __last) {
+ typedef typename iterator_traits<_InputIt>::value_type _ItVal;
+ static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
+ using _CVT = _PathCVT<_ItVal>;
+ if (__first != __last) {
+ __append_sep_if_needed(*__first);
+ _CVT::__append_range(__pn_, __first, __last);
+ }
+ return *this;
+ }
+
+ // concatenation
+ _LIBCPP_INLINE_VISIBILITY
+ path& operator+=(const path& __x) {
+ __pn_ += __x.__pn_;
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ path& operator+=(const string_type& __x) {
+ __pn_ += __x;
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ path& operator+=(const value_type* __x) {
+ __pn_ += __x;
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ path& operator+=(value_type __x) {
+ __pn_ += __x;
+ return *this;
+ }
+
+
+ template <class _ECharT>
+ typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
+ operator+=(_ECharT __x)
+ {
+ basic_string<_ECharT> __tmp;
+ __tmp += __x;
+ _PathCVT<_ECharT>::__append_source(__pn_, __tmp);
+ return *this;
+ }
+
+ template <class _Source>
+ _EnableIfPathable<_Source>
+ operator+=(const _Source& __x) {
+ return this->concat(__x);
+ }
+
+ template <class _Source>
+ _EnableIfPathable<_Source>
+ concat(const _Source& __x) {
+ _SourceCVT<_Source>::__append_source(__pn_, __x);
+ return *this;
+ }
+
+ template <class _InputIt>
+ path& concat(_InputIt __first, _InputIt __last) {
+ typedef typename iterator_traits<_InputIt>::value_type _ItVal;
+ _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
+ return *this;
+ }
+
+ // modifiers
+ _LIBCPP_INLINE_VISIBILITY
+ void clear() _NOEXCEPT {
+ __pn_.clear();
+ }
+
+ path& make_preferred() { return *this; }
+ path& remove_filename() { return *this = parent_path(); }
+
+ path& replace_filename(const path& __replacement) {
+ remove_filename();
+ return (*this /= __replacement);
+ }
+
+ path& replace_extension(const path& __replacement = path());
+
+ _LIBCPP_INLINE_VISIBILITY
+ void swap(path& __rhs) _NOEXCEPT {
+ __pn_.swap(__rhs.__pn_);
+ }
+
+ // native format observers
+ _LIBCPP_INLINE_VISIBILITY
+ const string_type& native() const _NOEXCEPT {
+ return __pn_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); }
+
+ _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
+
+ template <class _ECharT, class _Traits = char_traits<_ECharT>,
+ class _Allocator = allocator<_ECharT> >
+ basic_string<_ECharT, _Traits, _Allocator>
+ string(const _Allocator& __a = _Allocator()) const {
+ using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>;
+ using _Str = basic_string<_ECharT, _Traits, _Allocator>;
+ _Str __s(__a);
+ __s.reserve(__pn_.size());
+ _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
+ return __s;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
+ _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { return string<wchar_t>(); }
+ _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
+ _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); }
+ _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); }
+
+ // generic format observers
+ template <class _ECharT, class _Traits = char_traits<_ECharT>,
+ class _Allocator = allocator<_ECharT>
+ >
+ basic_string<_ECharT, _Traits, _Allocator>
+ generic_string(const _Allocator& __a = _Allocator()) const {
+ return string<_ECharT, _Traits, _Allocator>(__a);
+ }
+
+ std::string generic_string() const { return __pn_; }
+ std::wstring generic_wstring() const { return string<wchar_t>(); }
+ std::string generic_u8string() const { return __pn_; }
+ std::u16string generic_u16string() const { return string<char16_t>(); }
+ std::u32string generic_u32string() const { return string<char32_t>(); }
+
+private:
+ _LIBCPP_FUNC_VIS int __compare(const value_type*) const;
+ _LIBCPP_FUNC_VIS string_view __root_name() const;
+ _LIBCPP_FUNC_VIS string_view __root_directory() const;
+ _LIBCPP_FUNC_VIS string_view __relative_path() const;
+ _LIBCPP_FUNC_VIS string_view __parent_path() const;
+ _LIBCPP_FUNC_VIS string_view __filename() const;
+ _LIBCPP_FUNC_VIS string_view __stem() const;
+ _LIBCPP_FUNC_VIS string_view __extension() const;
+
+public:
+ // compare
+ _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.c_str());}
+ _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s.c_str()); }
+ _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); }
+
+ // decomposition
+ _LIBCPP_INLINE_VISIBILITY path root_name() const { return __root_name().to_string(); }
+ _LIBCPP_INLINE_VISIBILITY path root_directory() const { return __root_directory().to_string(); }
+ _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(__root_directory().to_string()); }
+ _LIBCPP_INLINE_VISIBILITY path relative_path() const { return __relative_path().to_string(); }
+ _LIBCPP_INLINE_VISIBILITY path parent_path() const { return __parent_path().to_string(); }
+ _LIBCPP_INLINE_VISIBILITY path filename() const { return __filename().to_string(); }
+ _LIBCPP_INLINE_VISIBILITY path stem() const { return __stem().to_string();}
+ _LIBCPP_INLINE_VISIBILITY path extension() const { return __extension().to_string(); }
+
+ // query
+ _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT { return __pn_.empty(); }
+
+ _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { return !__root_name().empty(); }
+ _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); }
+ _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !(__root_name().empty() && __root_directory().empty()); }
+ _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { return !__relative_path().empty(); }
+ _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { return !__parent_path().empty(); }
+ _LIBCPP_INLINE_VISIBILITY bool has_filename() const { return !__filename().empty(); }
+ _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
+ _LIBCPP_INLINE_VISIBILITY bool has_extension() const { return !__extension().empty(); }
+
+ _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); }
+ _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
+
+ // iterators
+ class _LIBCPP_TYPE_VIS iterator;
+ typedef iterator const_iterator;
+
+ _LIBCPP_FUNC_VIS iterator begin() const;
+ _LIBCPP_FUNC_VIS iterator end() const;
+
+private:
+ inline _LIBCPP_INLINE_VISIBILITY
+ path& __assign_view(string_view const& __s) noexcept { __pn_ = __s.to_string(); return *this; }
+ string_type __pn_;
+};
+
+inline _LIBCPP_ALWAYS_INLINE
+void swap(path& __lhs, path& __rhs) _NOEXCEPT {
+ __lhs.swap(__rhs);
+}
+
+_LIBCPP_FUNC_VIS
+size_t hash_value(const path& __p) _NOEXCEPT;
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT
+{ return __lhs.compare(__rhs) == 0; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT
+{ return __lhs.compare(__rhs) != 0; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT
+{ return __lhs.compare(__rhs) < 0; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT
+{ return __lhs.compare(__rhs) <= 0; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT
+{ return __lhs.compare(__rhs) > 0; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT
+{ return __lhs.compare(__rhs) >= 0; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+path operator/(const path& __lhs, const path& __rhs) {
+ return path(__lhs) /= __rhs;
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_same<_CharT, char>::value &&
+ is_same<_Traits, char_traits<char>>::value,
+ basic_ostream<_CharT, _Traits>&
+>::type
+operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
+ __os << std::__quoted(__p.native());
+ return __os;
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_INLINE_VISIBILITY
+typename enable_if<!is_same<_CharT, char>::value ||
+ !is_same<_Traits, char_traits<char>>::value,
+ basic_ostream<_CharT, _Traits>&
+>::type
+operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
+ __os << std::__quoted(__p.string<_CharT, _Traits>());
+ return __os;
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
+{
+ basic_string<_CharT, _Traits> __tmp;
+ __is >> __quoted(__tmp);
+ __p = __tmp;
+ return __is;
+}
+
+template <class _Source>
+_LIBCPP_INLINE_VISIBILITY
+typename enable_if<__is_pathable<_Source>::value, path>::type
+u8path(const _Source& __s){
+ static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value,
+ "u8path(Source const&) requires Source have a character type of type 'char'");
+ return path(__s);
+}
+
+template <class _InputIt>
+_LIBCPP_INLINE_VISIBILITY
+typename enable_if<__is_pathable<_InputIt>::value, path>::type
+u8path(_InputIt __f, _InputIt __l) {
+ static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
+ "u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
+ return path(__f, __l);
+}
+
+class _LIBCPP_TYPE_VIS path::iterator
+{
+public:
+ typedef bidirectional_iterator_tag iterator_category;
+ typedef path value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef const path* pointer;
+ typedef const path& reference;
+public:
+ _LIBCPP_INLINE_VISIBILITY
+ iterator() : __elem_(), __path_ptr_(nullptr), __pos_(0) {}
+
+ iterator(const iterator&) = default;
+ ~iterator() = default;
+
+ iterator& operator=(const iterator&) = default;
+
+ _LIBCPP_INLINE_VISIBILITY
+ reference operator*() const {
+ return __elem_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ pointer operator->() const {
+ return &__elem_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ iterator& operator++() {
+ return __increment();
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ iterator operator++(int) {
+ iterator __it(*this);
+ this->operator++();
+ return __it;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ iterator& operator--() {
+ return __decrement();
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ iterator operator--(int) {
+ iterator __it(*this);
+ this->operator--();
+ return __it;
+ }
+
+private:
+ friend class path;
+ friend bool operator==(const iterator&, const iterator&);
+
+ _LIBCPP_FUNC_VIS iterator& __increment();
+ _LIBCPP_FUNC_VIS iterator& __decrement();
+
+ path __elem_;
+ const path* __path_ptr_;
+ size_t __pos_;
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
+ return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
+ __lhs.__pos_ == __rhs.__pos_;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
+ return !(__lhs == __rhs);
+}
+
+class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error
+{
+public:
+ _LIBCPP_INLINE_VISIBILITY
+ filesystem_error(const string& __what, error_code __ec)
+ : system_error(__ec, __what),
+ __paths_(make_shared<_Storage>(path(), path()))
+ {}
+
+ _LIBCPP_INLINE_VISIBILITY
+ filesystem_error(const string& __what, const path& __p1, error_code __ec)
+ : system_error(__ec, __what),
+ __paths_(make_shared<_Storage>(__p1, path()))
+ {}
+
+ _LIBCPP_INLINE_VISIBILITY
+ filesystem_error(const string& __what, const path& __p1, const path& __p2,
+ error_code __ec)
+ : system_error(__ec, __what),
+ __paths_(make_shared<_Storage>(__p1, __p2))
+ {}
+
+ _LIBCPP_INLINE_VISIBILITY
+ const path& path1() const _NOEXCEPT {
+ return __paths_->first;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ const path& path2() const _NOEXCEPT {
+ return __paths_->second;
+ }
+
+ _LIBCPP_FUNC_VIS
+ ~filesystem_error() override; // key function
+
+ // TODO(ericwf): Create a custom error message.
+ //const char* what() const _NOEXCEPT;
+
+private:
+ typedef pair<path, path> _Storage;
+ shared_ptr<_Storage> __paths_;
+};
+
+// operational functions
+
+_LIBCPP_FUNC_VIS
+path __canonical(const path&, const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __copy(const path& __from, const path& __to, copy_options __opt,
+ error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+bool __copy_file(const path& __from, const path& __to, copy_options __opt,
+ error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
+ error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+bool __create_directories(const path& p, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+bool __create_directory(const path& p, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+bool __create_directory(const path& p, const path & attributes,
+ error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __create_directory_symlink(const path& __to, const path& __new_symlink,
+ error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __create_hard_link(const path& __to, const path& __new_hard_link,
+ error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __create_symlink(const path& __to, const path& __new_symlink,
+ error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+path __current_path(error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __current_path(const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+bool __equivalent(const path&, const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+uintmax_t __file_size(const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+bool __fs_is_empty(const path& p, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+file_time_type __last_write_time(const path& p, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __last_write_time(const path& p, file_time_type new_time,
+ error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __permissions(const path& p, perms prms, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+path __read_symlink(const path& p, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+bool __remove(const path& p, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+uintmax_t __remove_all(const path& p, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __rename(const path& from, const path& to, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr);
+_LIBCPP_FUNC_VIS
+space_info __space(const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+file_status __status(const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+file_status __symlink_status(const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+path __system_complete(const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+path __temp_directory_path(error_code *__ec=nullptr);
+
+inline _LIBCPP_INLINE_VISIBILITY
+path current_path() {
+ return __current_path();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path current_path(error_code& __ec) {
+ return __current_path(&__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void current_path(const path& __p) {
+ __current_path(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
+ __current_path(__p, &__ec);
+}
+
+_LIBCPP_FUNC_VIS
+path absolute(const path&, const path& __p2 = current_path());
+
+inline _LIBCPP_INLINE_VISIBILITY
+path canonical(const path& __p, const path& __base = current_path()) {
+ return __canonical(__p, __base);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path canonical(const path& __p, error_code& __ec) {
+ path __base = __current_path(&__ec);
+ if (__ec) return {};
+ return __canonical(__p, __base, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path canonical(const path& __p, const path& __base, error_code& __ec) {
+ return __canonical(__p, __base, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void copy(const path& __from, const path& __to) {
+ __copy(__from, __to, copy_options::none);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void copy(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
+ __copy(__from, __to, copy_options::none, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void copy(const path& __from, const path& __to, copy_options __opt) {
+ __copy(__from, __to, __opt);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void copy(const path& __from, const path& __to,
+ copy_options __opt, error_code& __ec) _NOEXCEPT {
+ __copy(__from, __to, __opt, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool copy_file(const path& __from, const path& __to) {
+ return __copy_file(__from, __to, copy_options::none);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool copy_file(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
+ return __copy_file(__from, __to, copy_options::none, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool copy_file(const path& __from, const path& __to, copy_options __opt) {
+ return __copy_file(__from, __to, __opt);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool copy_file(const path& __from, const path& __to,
+ copy_options __opt, error_code& __ec) _NOEXCEPT {
+ return __copy_file(__from, __to, __opt, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void copy_symlink(const path& __existing, const path& __new) {
+ __copy_symlink(__existing, __new);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT {
+ __copy_symlink(__ext, __new, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool create_directories(const path& __p) {
+ return __create_directories(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool create_directories(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __create_directories(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool create_directory(const path& __p) {
+ return __create_directory(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __create_directory(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool create_directory(const path& __p, const path& __attrs) {
+ return __create_directory(__p, __attrs);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT {
+ return __create_directory(__p, __attrs, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void create_directory_symlink(const path& __to, const path& __new) {
+ __create_directory_symlink(__to, __new);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void create_directory_symlink(const path& __to, const path& __new,
+ error_code& __ec) _NOEXCEPT {
+ __create_directory_symlink(__to, __new, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void create_hard_link(const path& __to, const path& __new) {
+ __create_hard_link(__to, __new);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
+ __create_hard_link(__to, __new, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void create_symlink(const path& __to, const path& __new) {
+ __create_symlink(__to, __new);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
+ return __create_symlink(__to, __new, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool status_known(file_status __s) _NOEXCEPT {
+ return __s.type() != file_type::none;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool exists(file_status __s) _NOEXCEPT {
+ return status_known(__s) && __s.type() != file_type::not_found;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool exists(const path& __p) {
+ return exists(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool exists(const path& __p, error_code& __ec) _NOEXCEPT {
+ return exists(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool equivalent(const path& __p1, const path& __p2) {
+ return __equivalent(__p1, __p2);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT {
+ return __equivalent(__p1, __p2, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+uintmax_t file_size(const path& __p) {
+ return __file_size(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __file_size(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+uintmax_t hard_link_count(const path& __p) {
+ return __hard_link_count(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __hard_link_count(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_block_file(file_status __s) _NOEXCEPT {
+ return __s.type() == file_type::block;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_block_file(const path& __p) {
+ return is_block_file(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT {
+ return is_block_file(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_character_file(file_status __s) _NOEXCEPT {
+ return __s.type() == file_type::character;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_character_file(const path& __p) {
+ return is_character_file(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT {
+ return is_character_file(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_directory(file_status __s) _NOEXCEPT {
+ return __s.type() == file_type::directory;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_directory(const path& __p) {
+ return is_directory(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT {
+ return is_directory(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_empty(const path& __p) {
+ return __fs_is_empty(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_empty(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __fs_is_empty(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_fifo(file_status __s) _NOEXCEPT {
+ return __s.type() == file_type::fifo;
+}
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_fifo(const path& __p) {
+ return is_fifo(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT {
+ return is_fifo(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_regular_file(file_status __s) _NOEXCEPT {
+ return __s.type() == file_type::regular;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_regular_file(const path& __p) {
+ return is_regular_file(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT {
+ return is_regular_file(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_socket(file_status __s) _NOEXCEPT {
+ return __s.type() == file_type::socket;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_socket(const path& __p) {
+ return is_socket(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT {
+ return is_socket(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_symlink(file_status __s) _NOEXCEPT {
+ return __s.type() == file_type::symlink;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_symlink(const path& __p) {
+ return is_symlink(__symlink_status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT {
+ return is_symlink(__symlink_status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_other(file_status __s) _NOEXCEPT {
+ return exists(__s)
+ && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_other(const path& __p) {
+ return is_other(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool is_other(const path& __p, error_code& __ec) _NOEXCEPT {
+ return is_other(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+file_time_type last_write_time(const path& __p) {
+ return __last_write_time(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __last_write_time(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void last_write_time(const path& __p, file_time_type __t) {
+ __last_write_time(__p, __t);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT {
+ __last_write_time(__p, __t, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void permissions(const path& __p, perms __prms) {
+ __permissions(__p, __prms);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void permissions(const path& __p, perms __prms, error_code& __ec) {
+ __permissions(__p, __prms, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path read_symlink(const path& __p) {
+ return __read_symlink(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path read_symlink(const path& __p, error_code& __ec) {
+ return __read_symlink(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool remove(const path& __p) {
+ return __remove(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool remove(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __remove(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+uintmax_t remove_all(const path& __p) {
+ return __remove_all(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+uintmax_t remove_all(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __remove_all(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void rename(const path& __from, const path& __to) {
+ return __rename(__from, __to);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
+ return __rename(__from, __to, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void resize_file(const path& __p, uintmax_t __ns) {
+ return __resize_file(__p, __ns);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT {
+ return __resize_file(__p, __ns, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+space_info space(const path& __p) {
+ return __space(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+space_info space(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __space(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+file_status status(const path& __p) {
+ return __status(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+file_status status(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __status(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+file_status symlink_status(const path& __p) {
+ return __symlink_status(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
+ return __symlink_status(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path system_complete(const path& __p) {
+ return __system_complete(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path system_complete(const path& __p, error_code& __ec) {
+ return __system_complete(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path temp_directory_path() {
+ return __temp_directory_path();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path temp_directory_path(error_code& __ec) {
+ return __temp_directory_path(&__ec);
+}
+
+
+class directory_entry
+{
+ typedef _VSTD_FS::path _Path;
+
+public:
+ // constructors and destructors
+ directory_entry() _NOEXCEPT = default;
+ directory_entry(directory_entry const&) = default;
+ directory_entry(directory_entry&&) _NOEXCEPT = default;
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit directory_entry(_Path const& __p) : __p_(__p) {}
+
+ ~directory_entry() {}
+
+ directory_entry& operator=(directory_entry const&) = default;
+ directory_entry& operator=(directory_entry&&) _NOEXCEPT = default;
+
+ _LIBCPP_INLINE_VISIBILITY
+ void assign(_Path const& __p) {
+ __p_ = __p;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ void replace_filename(_Path const& __p) {
+ __p_ = __p_.parent_path() / __p;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ _Path const& path() const _NOEXCEPT {
+ return __p_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ operator const _Path&() const _NOEXCEPT {
+ return __p_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ file_status status() const {
+ return _VSTD_FS::status(__p_);
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ file_status status(error_code& __ec) const _NOEXCEPT {
+ return _VSTD_FS::status(__p_, __ec);
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ file_status symlink_status() const {
+ return _VSTD_FS::symlink_status(__p_);
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ file_status symlink_status(error_code& __ec) const _NOEXCEPT {
+ return _VSTD_FS::symlink_status(__p_, __ec);
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool operator< (directory_entry const& __rhs) const _NOEXCEPT {
+ return __p_ < __rhs.__p_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool operator==(directory_entry const& __rhs) const _NOEXCEPT {
+ return __p_ == __rhs.__p_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool operator!=(directory_entry const& __rhs) const _NOEXCEPT {
+ return __p_ != __rhs.__p_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool operator<=(directory_entry const& __rhs) const _NOEXCEPT {
+ return __p_ <= __rhs.__p_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool operator> (directory_entry const& __rhs) const _NOEXCEPT {
+ return __p_ > __rhs.__p_;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool operator>=(directory_entry const& __rhs) const _NOEXCEPT {
+ return __p_ >= __rhs.__p_;
+ }
+private:
+ _Path __p_;
+};
+
+
+class directory_iterator;
+class recursive_directory_iterator;
+class __dir_stream;
+
+class __dir_element_proxy {
+public:
+
+ inline _LIBCPP_INLINE_VISIBILITY
+ directory_entry operator*() { return _VSTD::move(__elem_); }
+
+private:
+ friend class directory_iterator;
+ friend class recursive_directory_iterator;
+ explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
+ __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {}
+ directory_entry __elem_;
+};
+
+class directory_iterator
+{
+public:
+ typedef directory_entry value_type;
+ typedef ptrdiff_t difference_type;
+ typedef value_type const* pointer;
+ typedef value_type const& reference;
+ typedef input_iterator_tag iterator_category;
+
+public:
+ //ctor & dtor
+ directory_iterator() _NOEXCEPT
+ { }
+
+ explicit directory_iterator(const path& __p)
+ : directory_iterator(__p, nullptr)
+ { }
+
+ directory_iterator(const path& __p, directory_options __opts)
+ : directory_iterator(__p, nullptr, __opts)
+ { }
+
+ directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT
+ : directory_iterator(__p, &__ec)
+ { }
+
+ directory_iterator(const path& __p, directory_options __opts,
+ error_code& __ec) _NOEXCEPT
+ : directory_iterator(__p, &__ec, __opts)
+ { }
+
+ directory_iterator(const directory_iterator&) = default;
+ directory_iterator(directory_iterator&&) = default;
+ directory_iterator& operator=(const directory_iterator&) = default;
+
+ directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT {
+ // non-default implementation provided to support self-move assign.
+ if (this != &__o) {
+ __imp_ = _VSTD::move(__o.__imp_);
+ }
+ return *this;
+ }
+
+ ~directory_iterator() = default;
+
+ const directory_entry& operator*() const {
+ _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
+ return __deref();
+ }
+
+ const directory_entry* operator->() const
+ { return &**this; }
+
+ directory_iterator& operator++()
+ { return __increment(); }
+
+ __dir_element_proxy operator++(int) {
+ __dir_element_proxy __p(**this);
+ __increment();
+ return __p;
+ }
+
+ directory_iterator& increment(error_code& __ec) _NOEXCEPT
+ { return __increment(&__ec); }
+
+private:
+ friend bool operator==(const directory_iterator& __lhs,
+ const directory_iterator& __rhs) _NOEXCEPT;
+
+ // construct the dir_stream
+ _LIBCPP_FUNC_VIS
+ directory_iterator(const path&, error_code *, directory_options = directory_options::none);
+ _LIBCPP_FUNC_VIS
+ directory_iterator& __increment(error_code * __ec = nullptr);
+ _LIBCPP_FUNC_VIS
+ const directory_entry& __deref() const;
+
+private:
+ shared_ptr<__dir_stream> __imp_;
+};
+
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator==(const directory_iterator& __lhs,
+ const directory_iterator& __rhs) _NOEXCEPT {
+ return __lhs.__imp_ == __rhs.__imp_;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(const directory_iterator& __lhs,
+ const directory_iterator& __rhs) _NOEXCEPT {
+ return !(__lhs == __rhs);
+}
+
+// enable directory_iterator range-based for statements
+inline _LIBCPP_INLINE_VISIBILITY
+directory_iterator begin(directory_iterator __iter) _NOEXCEPT {
+ return __iter;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+directory_iterator end(const directory_iterator&) _NOEXCEPT {
+ return directory_iterator();
+}
+
+class recursive_directory_iterator {
+public:
+ using value_type = directory_entry;
+ using difference_type = std::ptrdiff_t;
+ using pointer = directory_entry const *;
+ using reference = directory_entry const &;
+ using iterator_category = std::input_iterator_tag;
+
+public:
+ // constructors and destructor
+ _LIBCPP_INLINE_VISIBILITY
+ recursive_directory_iterator() _NOEXCEPT
+ : __rec_(false)
+ {}
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit recursive_directory_iterator(const path& __p,
+ directory_options __xoptions = directory_options::none)
+ : recursive_directory_iterator(__p, __xoptions, nullptr)
+ { }
+
+ _LIBCPP_INLINE_VISIBILITY
+ recursive_directory_iterator(const path& __p,
+ directory_options __xoptions, error_code& __ec) _NOEXCEPT
+ : recursive_directory_iterator(__p, __xoptions, &__ec)
+ { }
+
+ _LIBCPP_INLINE_VISIBILITY
+ recursive_directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT
+ : recursive_directory_iterator(__p, directory_options::none, &__ec)
+ { }
+
+ recursive_directory_iterator(const recursive_directory_iterator&) = default;
+ recursive_directory_iterator(recursive_directory_iterator&&) = default;
+
+ recursive_directory_iterator &
+ operator=(const recursive_directory_iterator&) = default;
+
+ _LIBCPP_INLINE_VISIBILITY
+ recursive_directory_iterator &
+ operator=(recursive_directory_iterator&& __o) noexcept {
+ // non-default implementation provided to support self-move assign.
+ if (this != &__o) {
+ __imp_ = _VSTD::move(__o.__imp_);
+ __rec_ = __o.__rec_;
+ }
+ return *this;
+ }
+
+ ~recursive_directory_iterator() = default;
+
+ _LIBCPP_INLINE_VISIBILITY
+ const directory_entry& operator*() const
+ { return __deref(); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ const directory_entry* operator->() const
+ { return &__deref(); }
+
+ recursive_directory_iterator& operator++()
+ { return __increment(); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __dir_element_proxy operator++(int) {
+ __dir_element_proxy __p(**this);
+ __increment();
+ return __p;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ recursive_directory_iterator& increment(error_code& __ec) _NOEXCEPT
+ { return __increment(&__ec); }
+
+ _LIBCPP_FUNC_VIS directory_options options() const;
+ _LIBCPP_FUNC_VIS int depth() const;
+
+ _LIBCPP_INLINE_VISIBILITY
+ void pop() { __pop(); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ void pop(error_code& __ec)
+ { __pop(&__ec); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool recursion_pending() const
+ { return __rec_; }
+
+ _LIBCPP_INLINE_VISIBILITY
+ void disable_recursion_pending()
+ { __rec_ = false; }
+
+private:
+ recursive_directory_iterator(const path& __p, directory_options __opt,
+ error_code *__ec);
+
+ _LIBCPP_FUNC_VIS
+ const directory_entry& __deref() const;
+
+ _LIBCPP_FUNC_VIS
+ bool __try_recursion(error_code* __ec);
+
+ _LIBCPP_FUNC_VIS
+ void __advance(error_code* __ec=nullptr);
+
+ _LIBCPP_FUNC_VIS
+ recursive_directory_iterator& __increment(error_code *__ec=nullptr);
+
+ _LIBCPP_FUNC_VIS
+ void __pop(error_code* __ec=nullptr);
+
+ friend bool operator==(const recursive_directory_iterator&,
+ const recursive_directory_iterator&) _NOEXCEPT;
+
+ struct __shared_imp;
+ shared_ptr<__shared_imp> __imp_;
+ bool __rec_;
+}; // class recursive_directory_iterator
+
+
+_LIBCPP_INLINE_VISIBILITY
+inline bool operator==(const recursive_directory_iterator& __lhs,
+ const recursive_directory_iterator& __rhs) _NOEXCEPT
+{
+ return __lhs.__imp_ == __rhs.__imp_;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline bool operator!=(const recursive_directory_iterator& __lhs,
+ const recursive_directory_iterator& __rhs) _NOEXCEPT
+{
+ return !(__lhs == __rhs);
+}
+// enable recursive_directory_iterator range-based for statements
+inline _LIBCPP_INLINE_VISIBILITY
+recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT {
+ return __iter;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT {
+ return recursive_directory_iterator();
+}
+
+_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
+
+#endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM
Modified: libcxx/trunk/include/iomanip
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/iomanip?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/include/iomanip (original)
+++ libcxx/trunk/include/iomanip Fri Jun 17 14:46:40 2016
@@ -512,8 +512,6 @@ put_time(const tm* __tm, const _CharT* _
return __iom_t10<_CharT>(__tm, __fmt);
}
-#if _LIBCPP_STD_VER > 11
-
template <class _CharT, class _Traits, class _ForwardIterator>
std::basic_ostream<_CharT, _Traits> &
__quoted_output ( basic_ostream<_CharT, _Traits> &__os,
@@ -631,22 +629,43 @@ quoted ( const _CharT *__s, _CharT __del
return __quoted_output_proxy<_CharT, const _CharT *> ( __s, __end, __delim, __escape );
}
+
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_INLINE_VISIBILITY
__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>
-quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+__quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
{
- return __quoted_output_proxy<_CharT,
- typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>
+ return __quoted_output_proxy<_CharT,
+ typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>
( __s.cbegin(), __s.cend (), __delim, __escape );
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_INLINE_VISIBILITY
__quoted_proxy<_CharT, _Traits, _Allocator>
-quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+__quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
{
return __quoted_proxy<_CharT, _Traits, _Allocator>( __s, __delim, __escape );
}
+
+
+#if _LIBCPP_STD_VER > 11
+
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_INLINE_VISIBILITY
+__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>
+quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+{
+ return __quoted(__s, __delim, __escape);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_INLINE_VISIBILITY
+__quoted_proxy<_CharT, _Traits, _Allocator>
+quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+{
+ return __quoted(__s, __delim, __escape);
+}
#endif
_LIBCPP_END_NAMESPACE_STD
Modified: libcxx/trunk/lib/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/CMakeLists.txt?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/lib/CMakeLists.txt (original)
+++ libcxx/trunk/lib/CMakeLists.txt Fri Jun 17 14:46:40 2016
@@ -154,7 +154,10 @@ set_target_properties(cxx
if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
file(GLOB LIBCXX_EXPERIMENTAL_SOURCES ../src/experimental/*.cpp)
- add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES})
+ if (LIBCXX_ENABLE_FILESYSTEM)
+ file(GLOB LIBCXX_FILESYSTEM_SOURCES ../src/experimental/filesystem/*.cpp)
+ endif()
+ add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES} ${LIBCXX_FILESYSTEM_SOURCES})
target_link_libraries(cxx_experimental cxx)
set(experimental_flags "${LIBCXX_COMPILE_FLAGS}")
Added: libcxx/trunk/src/experimental/filesystem/directory_iterator.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/experimental/filesystem/directory_iterator.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/src/experimental/filesystem/directory_iterator.cpp (added)
+++ libcxx/trunk/src/experimental/filesystem/directory_iterator.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,256 @@
+#include "experimental/filesystem"
+#include <dirent.h>
+#include <errno.h>
+
+_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
+
+namespace { namespace detail {
+
+inline error_code capture_errno() {
+ _LIBCPP_ASSERT(errno, "Expected errno to be non-zero");
+ return error_code{errno, std::generic_category()};
+}
+
+template <class ...Args>
+inline bool capture_error_or_throw(std::error_code* user_ec,
+ const char* msg, Args&&... args)
+{
+ std::error_code my_ec = capture_errno();
+ if (user_ec) {
+ *user_ec = my_ec;
+ return true;
+ }
+ __libcpp_throw(filesystem_error(msg, std::forward<Args>(args)..., my_ec));
+ return false;
+}
+
+template <class ...Args>
+inline bool set_or_throw(std::error_code& my_ec,
+ std::error_code* user_ec,
+ const char* msg, Args&&... args)
+{
+ if (user_ec) {
+ *user_ec = my_ec;
+ return true;
+ }
+ __libcpp_throw(filesystem_error(msg, std::forward<Args>(args)..., my_ec));
+ return false;
+}
+
+typedef path::string_type string_type;
+
+
+inline string_type posix_readdir(DIR *dir_stream, error_code& ec) {
+ struct dirent* dir_entry_ptr = nullptr;
+ errno = 0; // zero errno in order to detect errors
+ if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) {
+ ec = capture_errno();
+ return {};
+ } else {
+ ec.clear();
+ return dir_entry_ptr->d_name;
+ }
+}
+
+}} // namespace detail
+
+using detail::set_or_throw;
+
+class __dir_stream {
+public:
+ __dir_stream() = delete;
+ __dir_stream& operator=(const __dir_stream&) = delete;
+
+ __dir_stream(__dir_stream&& other) noexcept
+ : __stream_(other.__stream_), __root_(std::move(other.__root_)),
+ __entry_(std::move(other.__entry_))
+ {
+ other.__stream_ = nullptr;
+ }
+
+
+ __dir_stream(const path& root, directory_options opts, error_code& ec)
+ : __stream_(nullptr),
+ __root_(root)
+ {
+ if ((__stream_ = ::opendir(root.c_str())) == nullptr) {
+ ec = detail::capture_errno();
+ const bool allow_eacess =
+ bool(opts & directory_options::skip_permission_denied);
+ if (allow_eacess && ec.value() == EACCES)
+ ec.clear();
+ return;
+ }
+ advance(ec);
+ }
+
+ ~__dir_stream() noexcept
+ { if (__stream_) close(); }
+
+ bool good() const noexcept { return __stream_ != nullptr; }
+
+ bool advance(error_code &ec) {
+ while (true) {
+ auto str = detail::posix_readdir(__stream_, ec);
+ if (str == "." || str == "..") {
+ continue;
+ } else if (ec || str.empty()) {
+ close();
+ return false;
+ } else {
+ __entry_.assign(__root_ / str);
+ return true;
+ }
+ }
+ }
+private:
+ std::error_code close() noexcept {
+ std::error_code m_ec;
+ if (::closedir(__stream_) == -1)
+ m_ec = detail::capture_errno();
+ __stream_ = nullptr;
+ return m_ec;
+ }
+
+ DIR * __stream_{nullptr};
+public:
+ path __root_;
+ directory_entry __entry_;
+};
+
+// directory_iterator
+
+directory_iterator::directory_iterator(const path& p, error_code *ec,
+ directory_options opts)
+{
+ std::error_code m_ec;
+ __imp_ = make_shared<__dir_stream>(p, opts, m_ec);
+ if (ec) *ec = m_ec;
+ if (!__imp_->good()) {
+ __imp_.reset();
+ if (m_ec)
+ set_or_throw(m_ec, ec,
+ "directory_iterator::directory_iterator(...)", p);
+ }
+}
+
+directory_iterator& directory_iterator::__increment(error_code *ec)
+{
+ _LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator");
+ std::error_code m_ec;
+ if (!__imp_->advance(m_ec)) {
+ __imp_.reset();
+ if (m_ec)
+ set_or_throw(m_ec, ec, "directory_iterator::operator++()");
+ } else {
+ if (ec) ec->clear();
+ }
+ return *this;
+
+}
+
+directory_entry const& directory_iterator::__deref() const {
+ _LIBCPP_ASSERT(__imp_, "Attempting to dereference an invalid iterator");
+ return __imp_->__entry_;
+}
+
+// recursive_directory_iterator
+
+struct recursive_directory_iterator::__shared_imp {
+ stack<__dir_stream> __stack_;
+ directory_options __options_;
+};
+
+recursive_directory_iterator::recursive_directory_iterator(const path& p,
+ directory_options opt, error_code *ec)
+ : __imp_(nullptr), __rec_(true)
+{
+ std::error_code m_ec;
+ __dir_stream new_s(p, opt, m_ec);
+ if (m_ec) set_or_throw(m_ec, ec, "recursive_directory_iterator", p);
+ if (m_ec || !new_s.good()) return;
+
+ __imp_ = _VSTD::make_shared<__shared_imp>();
+ __imp_->__options_ = opt;
+ __imp_->__stack_.push(_VSTD::move(new_s));
+}
+
+void recursive_directory_iterator::__pop(error_code* ec)
+{
+ _LIBCPP_ASSERT(__imp_, "Popping the end iterator");
+ __imp_->__stack_.pop();
+ if (__imp_->__stack_.size() == 0) {
+ __imp_.reset();
+ if (ec) ec->clear();
+ } else {
+ __advance(ec);
+ }
+}
+
+directory_options recursive_directory_iterator::options() const {
+ return __imp_->__options_;
+}
+
+int recursive_directory_iterator::depth() const {
+ return __imp_->__stack_.size() - 1;
+}
+
+const directory_entry& recursive_directory_iterator::__deref() const {
+ return __imp_->__stack_.top().__entry_;
+}
+
+recursive_directory_iterator&
+recursive_directory_iterator::__increment(error_code *ec)
+{
+ if (recursion_pending()) {
+ if (__try_recursion(ec) || (ec && *ec))
+ return *this;
+ }
+ __rec_ = true;
+ __advance(ec);
+ return *this;
+}
+
+void recursive_directory_iterator::__advance(error_code* ec) {
+ const directory_iterator end_it;
+ auto& stack = __imp_->__stack_;
+ std::error_code m_ec;
+ while (stack.size() > 0) {
+ if (stack.top().advance(m_ec)) {
+ if (ec) ec->clear();
+ return;
+ }
+ if (m_ec) break;
+ stack.pop();
+ }
+ __imp_.reset();
+ if (m_ec)
+ set_or_throw(m_ec, ec, "recursive_directory_iterator::operator++()");
+}
+
+bool recursive_directory_iterator::__try_recursion(error_code *ec) {
+
+ bool rec_sym =
+ bool(options() & directory_options::follow_directory_symlink);
+ auto& curr_it = __imp_->__stack_.top();
+
+ if (is_directory(curr_it.__entry_.status()) &&
+ (!is_symlink(curr_it.__entry_.symlink_status()) || rec_sym))
+ {
+ std::error_code m_ec;
+ __dir_stream new_it(curr_it.__entry_.path(), __imp_->__options_, m_ec);
+ if (new_it.good()) {
+ __imp_->__stack_.push(_VSTD::move(new_it));
+ return true;
+ }
+ if (m_ec) {
+ __imp_.reset();
+ set_or_throw(m_ec, ec,
+ "recursive_directory_iterator::operator++()");
+ }
+ }
+ return false;
+}
+
+
+_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
Added: libcxx/trunk/src/experimental/filesystem/operations.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/experimental/filesystem/operations.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/src/experimental/filesystem/operations.cpp (added)
+++ libcxx/trunk/src/experimental/filesystem/operations.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,754 @@
+//===--------------------- filesystem/ops.cpp -----------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "experimental/filesystem"
+#include "iterator"
+#include "fstream"
+#include "type_traits"
+#include "random" /* for unique_path */
+#include "cstdlib"
+#include "climits"
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <fcntl.h> /* values for fchmodat */
+#if defined(__APPLE__)
+#include <sys/time.h> // for ::utimes as used in __last_write_time
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
+
+filesystem_error::~filesystem_error() {}
+
+
+// POSIX HELPERS
+
+namespace detail { namespace {
+
+using value_type = path::value_type;
+using string_type = path::string_type;
+
+
+
+inline std::error_code capture_errno() {
+ _LIBCPP_ASSERT(errno, "Expected errno to be non-zero");
+ std::error_code m_ec(errno, std::generic_category());
+ return m_ec;
+}
+
+void set_or_throw(std::error_code const& m_ec, std::error_code* ec,
+ const char* msg, path const& p = {}, path const& p2 = {})
+{
+ if (ec) {
+ *ec = m_ec;
+ } else {
+ string msg_s("std::experimental::filesystem::");
+ msg_s += msg;
+ __libcpp_throw(filesystem_error(msg_s, p, p2, m_ec));
+ }
+}
+
+void set_or_throw(std::error_code* ec, const char* msg,
+ path const& p = {}, path const& p2 = {})
+{
+ return set_or_throw(capture_errno(), ec, msg, p, p2);
+}
+
+perms posix_get_perms(const struct ::stat & st) noexcept {
+ return static_cast<perms>(st.st_mode) & perms::mask;
+}
+
+::mode_t posix_convert_perms(perms prms) {
+ return static_cast< ::mode_t>(prms & perms::mask);
+}
+
+file_status create_file_status(std::error_code& m_ec, path const& p,
+ struct ::stat& path_stat,
+ std::error_code* ec)
+{
+ if (ec) *ec = m_ec;
+ if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) {
+ return file_status(file_type::not_found);
+ }
+ else if (m_ec) {
+ set_or_throw(m_ec, ec, "posix_stat", p);
+ return file_status(file_type::none);
+ }
+ // else
+
+ file_status fs_tmp;
+ auto const mode = path_stat.st_mode;
+ if (S_ISLNK(mode)) fs_tmp.type(file_type::symlink);
+ else if (S_ISREG(mode)) fs_tmp.type(file_type::regular);
+ else if (S_ISDIR(mode)) fs_tmp.type(file_type::directory);
+ else if (S_ISBLK(mode)) fs_tmp.type(file_type::block);
+ else if (S_ISCHR(mode)) fs_tmp.type(file_type::character);
+ else if (S_ISFIFO(mode)) fs_tmp.type(file_type::fifo);
+ else if (S_ISSOCK(mode)) fs_tmp.type(file_type::socket);
+ else fs_tmp.type(file_type::unknown);
+
+ fs_tmp.permissions(detail::posix_get_perms(path_stat));
+ return fs_tmp;
+}
+
+file_status posix_stat(path const & p, struct ::stat& path_stat,
+ std::error_code* ec)
+{
+ std::error_code m_ec;
+ if (::stat(p.c_str(), &path_stat) == -1)
+ m_ec = detail::capture_errno();
+ return create_file_status(m_ec, p, path_stat, ec);
+}
+
+file_status posix_stat(path const & p, std::error_code* ec) {
+ struct ::stat path_stat;
+ return posix_stat(p, path_stat, ec);
+}
+
+file_status posix_lstat(path const & p, struct ::stat & path_stat,
+ std::error_code* ec)
+{
+ std::error_code m_ec;
+ if (::lstat(p.c_str(), &path_stat) == -1)
+ m_ec = detail::capture_errno();
+ return create_file_status(m_ec, p, path_stat, ec);
+}
+
+file_status posix_lstat(path const & p, std::error_code* ec) {
+ struct ::stat path_stat;
+ return posix_lstat(p, path_stat, ec);
+}
+
+bool stat_equivalent(struct ::stat& st1, struct ::stat& st2) {
+ return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
+}
+
+// DETAIL::MISC
+
+
+bool copy_file_impl(const path& from, const path& to, perms from_perms,
+ std::error_code *ec)
+{
+ std::ifstream in(from.c_str(), std::ios::binary);
+ std::ofstream out(to.c_str(), std::ios::binary);
+
+ if (in.good() && out.good()) {
+ using InIt = std::istreambuf_iterator<char>;
+ using OutIt = std::ostreambuf_iterator<char>;
+ InIt bin(in);
+ InIt ein;
+ OutIt bout(out);
+ std::copy(bin, ein, bout);
+ }
+ if (out.fail() || in.fail()) {
+ set_or_throw(make_error_code(errc::operation_not_permitted),
+ ec, "copy_file", from, to);
+ return false;
+ }
+ __permissions(to, from_perms, ec);
+ // TODO what if permissions fails?
+ return true;
+}
+
+}} // end namespace detail
+
+using detail::set_or_throw;
+
+path __canonical(path const & orig_p, const path& base, std::error_code *ec)
+{
+ path p = absolute(orig_p, base);
+ char buff[PATH_MAX + 1];
+ char *ret;
+ if ((ret = ::realpath(p.c_str(), buff)) == nullptr) {
+ set_or_throw(ec, "canonical", orig_p, base);
+ return {};
+ }
+ if (ec) ec->clear();
+ return {ret};
+}
+
+void __copy(const path& from, const path& to, copy_options options,
+ std::error_code *ec)
+{
+ const bool sym_status = bool(options &
+ (copy_options::create_symlinks | copy_options::skip_symlinks));
+
+ const bool sym_status2 = bool(options &
+ copy_options::copy_symlinks);
+
+ std::error_code m_ec;
+ struct ::stat f_st = {};
+ const file_status f = sym_status || sym_status2
+ ? detail::posix_lstat(from, f_st, &m_ec)
+ : detail::posix_stat(from, f_st, &m_ec);
+ if (m_ec)
+ return set_or_throw(m_ec, ec, "copy", from, to);
+
+ struct ::stat t_st = {};
+ const file_status t = sym_status ? detail::posix_lstat(to, t_st, &m_ec)
+ : detail::posix_stat(to, t_st, &m_ec);
+
+ if (not status_known(t))
+ return set_or_throw(m_ec, ec, "copy", from, to);
+
+ if (!exists(f) || is_other(f) || is_other(t)
+ || (is_directory(f) && is_regular_file(t))
+ || detail::stat_equivalent(f_st, t_st))
+ {
+ return set_or_throw(make_error_code(errc::function_not_supported),
+ ec, "copy", from, to);
+ }
+
+ if (ec) ec->clear();
+
+ if (is_symlink(f)) {
+ if (bool(copy_options::skip_symlinks & options)) {
+ // do nothing
+ } else if (not exists(t)) {
+ __copy_symlink(from, to, ec);
+ } else {
+ set_or_throw(make_error_code(errc::file_exists),
+ ec, "copy", from, to);
+ }
+ return;
+ }
+ else if (is_regular_file(f)) {
+ if (bool(copy_options::directories_only & options)) {
+ // do nothing
+ }
+ else if (bool(copy_options::create_symlinks & options)) {
+ __create_symlink(from, to, ec);
+ }
+ else if (bool(copy_options::create_hard_links & options)) {
+ __create_hard_link(from, to, ec);
+ }
+ else if (is_directory(t)) {
+ __copy_file(from, to / from.filename(), options, ec);
+ } else {
+ __copy_file(from, to, options, ec);
+ }
+ return;
+ }
+ else if (is_directory(f)) {
+ if (not bool(copy_options::recursive & options) &&
+ bool(copy_options::__in_recursive_copy & options))
+ {
+ return;
+ }
+
+ if (!exists(t)) {
+ // create directory to with attributes from 'from'.
+ __create_directory(to, from, ec);
+ if (ec && *ec) { return; }
+ }
+ directory_iterator it = ec ? directory_iterator(from, *ec)
+ : directory_iterator(from);
+ if (ec && *ec) { return; }
+ std::error_code m_ec;
+ for (; it != directory_iterator(); it.increment(m_ec)) {
+ if (m_ec) return set_or_throw(m_ec, ec, "copy", from, to);
+ __copy(it->path(), to / it->path().filename(),
+ options | copy_options::__in_recursive_copy, ec);
+ if (ec && *ec) { return; }
+ }
+ }
+}
+
+
+bool __copy_file(const path& from, const path& to, copy_options options,
+ std::error_code *ec)
+{
+ if (ec) ec->clear();
+
+ std::error_code m_ec;
+ auto from_st = detail::posix_stat(from, &m_ec);
+ if (not is_regular_file(from_st)) {
+ if (not m_ec)
+ m_ec = make_error_code(errc::not_supported);
+ set_or_throw(m_ec, ec, "copy_file", from, to);
+ return false;
+ }
+
+ auto to_st = detail::posix_stat(to, &m_ec);
+ if (!status_known(to_st)) {
+ set_or_throw(m_ec, ec, "copy_file", from, to);
+ return false;
+ }
+
+ const bool to_exists = exists(to_st);
+ if (to_exists && bool(copy_options::skip_existing & options)) {
+ return false;
+ }
+ else if (to_exists && bool(copy_options::update_existing & options)) {
+ auto from_time = __last_write_time(from, ec);
+ if (ec && *ec) { return false; }
+ auto to_time = __last_write_time(to, ec);
+ if (ec && *ec) { return false; }
+ if (from_time <= to_time) {
+ return false;
+ }
+ return detail::copy_file_impl(from, to, from_st.permissions(), ec);
+ }
+ else if (!to_exists || bool(copy_options::overwrite_existing & options)) {
+ return detail::copy_file_impl(from, to, from_st.permissions(), ec);
+ }
+ else {
+ set_or_throw(make_error_code(errc::file_exists), ec, "copy", from, to);
+ return false;
+ }
+}
+
+void __copy_symlink(const path& existing_symlink, const path& new_symlink,
+ std::error_code *ec)
+{
+ const path real_path(__read_symlink(existing_symlink, ec));
+ if (ec && *ec) { return; }
+ // NOTE: proposal says you should detect if you should call
+ // create_symlink or create_directory_symlink. I don't think this
+ // is needed with POSIX
+ __create_symlink(real_path, new_symlink, ec);
+}
+
+
+bool __create_directories(const path& p, std::error_code *ec)
+{
+ std::error_code m_ec;
+ auto const st = detail::posix_stat(p, &m_ec);
+ if (!status_known(st)) {
+ set_or_throw(m_ec, ec, "create_directories", p);
+ return false;
+ }
+ else if (is_directory(st)) {
+ if (ec) ec->clear();
+ return false;
+ }
+ else if (exists(st)) {
+ set_or_throw(make_error_code(errc::file_exists),
+ ec, "create_directories", p);
+ return false;
+ }
+
+ const path parent = p.parent_path();
+ if (!parent.empty()) {
+ const file_status parent_st = status(parent, m_ec);
+ if (not status_known(parent_st)) {
+ set_or_throw(m_ec, ec, "create_directories", p);
+ return false;
+ }
+ if (not exists(parent_st)) {
+ __create_directories(parent, ec);
+ if (ec && *ec) { return false; }
+ }
+ }
+ return __create_directory(p, ec);
+}
+
+bool __create_directory(const path& p, std::error_code *ec)
+{
+ if (ec) ec->clear();
+ if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
+ return true;
+ if (errno != EEXIST || !is_directory(p))
+ set_or_throw(ec, "create_directory", p);
+ return false;
+}
+
+bool __create_directory(path const & p, path const & attributes,
+ std::error_code *ec)
+{
+ struct ::stat attr_stat;
+ std::error_code mec;
+ auto st = detail::posix_stat(attributes, attr_stat, &mec);
+ if (!status_known(st)) {
+ set_or_throw(mec, ec, "create_directory", p, attributes);
+ return false;
+ }
+ if (ec) ec->clear();
+ if (::mkdir(p.c_str(), attr_stat.st_mode) == 0)
+ return true;
+ if (errno != EEXIST || !is_directory(p))
+ set_or_throw(ec, "create_directory", p, attributes);
+ return false;
+}
+
+void __create_directory_symlink(path const & from, path const & to,
+ std::error_code *ec){
+ if (::symlink(from.c_str(), to.c_str()) != 0)
+ set_or_throw(ec, "create_directory_symlink", from, to);
+ else if (ec)
+ ec->clear();
+}
+
+void __create_hard_link(const path& from, const path& to, std::error_code *ec){
+ if (::link(from.c_str(), to.c_str()) == -1)
+ set_or_throw(ec, "create_hard_link", from, to);
+ else if (ec)
+ ec->clear();
+}
+
+void __create_symlink(path const & from, path const & to, std::error_code *ec) {
+
+ if (::symlink(from.c_str(), to.c_str()) == -1)
+ set_or_throw(ec, "create_symlink", from, to);
+ else if (ec)
+ ec->clear();
+}
+
+path __current_path(std::error_code *ec) {
+ auto size = ::pathconf(".", _PC_PATH_MAX);
+ _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size");
+
+ auto buff = std::unique_ptr<char[]>(new char[size + 1]);
+ char* ret;
+ if ((ret = ::getcwd(buff.get(), static_cast<size_t>(size))) == nullptr) {
+ set_or_throw(ec, "current_path");
+ return {};
+ }
+ if (ec) ec->clear();
+ return {buff.get()};
+}
+
+void __current_path(const path& p, std::error_code *ec) {
+ if (::chdir(p.c_str()) == -1)
+ set_or_throw(ec, "current_path", p);
+ else if (ec)
+ ec->clear();
+}
+
+bool __equivalent(const path& p1, const path& p2, std::error_code *ec)
+{
+ std::error_code ec1, ec2;
+ struct ::stat st1 = {};
+ struct ::stat st2 = {};
+ auto s1 = detail::posix_stat(p1.native(), st1, &ec1);
+ auto s2 = detail::posix_stat(p2.native(), st2, &ec2);
+
+ if ((!exists(s1) && !exists(s2)) || (is_other(s1) && is_other(s2))) {
+ set_or_throw(make_error_code(errc::not_supported), ec,
+ "equivalent", p1, p2);
+ return false;
+ }
+ if (ec) ec->clear();
+ return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
+}
+
+
+std::uintmax_t __file_size(const path& p, std::error_code *ec)
+{
+ std::error_code m_ec;
+ struct ::stat st;
+ file_status fst = detail::posix_stat(p, st, &m_ec);
+ if (!exists(fst) || !is_regular_file(fst)) {
+ if (!m_ec)
+ m_ec = make_error_code(errc::not_supported);
+ set_or_throw(m_ec, ec, "file_size", p);
+ return static_cast<uintmax_t>(-1);
+ }
+ // is_regular_file(p) == true
+ if (ec) ec->clear();
+ return static_cast<std::uintmax_t>(st.st_size);
+}
+
+std::uintmax_t __hard_link_count(const path& p, std::error_code *ec)
+{
+ std::error_code m_ec;
+ struct ::stat st;
+ detail::posix_stat(p, st, &m_ec);
+ if (m_ec) {
+ set_or_throw(m_ec, ec, "hard_link_count", p);
+ return static_cast<std::uintmax_t>(-1);
+ }
+ if (ec) ec->clear();
+ return static_cast<std::uintmax_t>(st.st_nlink);
+}
+
+
+bool __fs_is_empty(const path& p, std::error_code *ec)
+{
+ if (ec) ec->clear();
+ std::error_code m_ec;
+ struct ::stat pst;
+ auto st = detail::posix_stat(p, pst, &m_ec);
+ if (is_directory(st))
+ return directory_iterator(p) == directory_iterator{};
+ else if (is_regular_file(st))
+ return static_cast<std::uintmax_t>(pst.st_size) == 0;
+ // else
+ set_or_throw(m_ec, ec, "is_empty", p);
+ return false;
+}
+
+
+file_time_type __last_write_time(const path& p, std::error_code *ec)
+{
+ using Clock = file_time_type::clock;
+ std::error_code m_ec;
+ struct ::stat st;
+ detail::posix_stat(p, st, &m_ec);
+ if (m_ec) {
+ set_or_throw(m_ec, ec, "last_write_time", p);
+ return file_time_type::min();
+ }
+ if (ec) ec->clear();
+ return Clock::from_time_t(static_cast<std::time_t>(st.st_mtime));
+}
+
+
+void __last_write_time(const path& p, file_time_type new_time,
+ std::error_code *ec)
+{
+ using namespace std::chrono;
+ std::error_code m_ec;
+
+#if defined(__APPLE__)
+ // FIXME: Use utimensat when it becomes available on OS X.
+ // This implementation has a race condition between determining the
+ // last access time and attempting to set it to the same value using
+ // ::utimes
+ using Clock = file_time_type::clock;
+ struct ::stat st;
+ file_status fst = detail::posix_stat(p, st, &m_ec);
+ if (m_ec && !status_known(fst)) {
+ set_or_throw(m_ec, ec, "last_write_time", p);
+ return;
+ }
+ auto write_dur = new_time.time_since_epoch();
+ auto write_sec = duration_cast<seconds>(write_dur);
+ auto access_dur = Clock::from_time_t(st.st_atime).time_since_epoch();
+ auto access_sec = duration_cast<seconds>(access_dur);
+ struct ::timeval tbuf[2];
+ tbuf[0].tv_sec = access_sec.count();
+ tbuf[0].tv_usec = duration_cast<microseconds>(access_dur - access_sec).count();
+ tbuf[1].tv_sec = write_sec.count();
+ tbuf[1].tv_usec = duration_cast<microseconds>(write_dur - write_sec).count();
+ if (::utimes(p.c_str(), tbuf) == -1) {
+ m_ec = detail::capture_errno();
+ }
+#else
+ auto dur_since_epoch = new_time.time_since_epoch();
+ auto sec_since_epoch = duration_cast<seconds>(dur_since_epoch);
+ auto ns_since_epoch = duration_cast<nanoseconds>(dur_since_epoch - sec_since_epoch);
+ struct ::timespec tbuf[2];
+ tbuf[0].tv_sec = 0;
+ tbuf[0].tv_nsec = UTIME_OMIT;
+ tbuf[1].tv_sec = sec_since_epoch.count();
+ tbuf[1].tv_nsec = ns_since_epoch.count();
+ if (::utimensat(AT_FDCWD, p.c_str(), tbuf, 0) == -1) {
+ m_ec = detail::capture_errno();
+ }
+#endif
+ if (m_ec)
+ set_or_throw(m_ec, ec, "last_write_time", p);
+ else if (ec)
+ ec->clear();
+}
+
+
+void __permissions(const path& p, perms prms, std::error_code *ec)
+{
+
+ const bool resolve_symlinks = bool(perms::resolve_symlinks & prms);
+ const bool add_perms = bool(perms::add_perms & prms);
+ const bool remove_perms = bool(perms::remove_perms & prms);
+
+ _LIBCPP_ASSERT(!(add_perms && remove_perms),
+ "Both add_perms and remove_perms are set");
+
+ std::error_code m_ec;
+ file_status st = detail::posix_lstat(p, &m_ec);
+ if (m_ec) return set_or_throw(m_ec, ec, "permissions", p);
+
+ const bool set_sym_perms = is_symlink(st) && !resolve_symlinks;
+
+ if ((resolve_symlinks && is_symlink(st)) && (add_perms || remove_perms)) {
+ st = detail::posix_stat(p, &m_ec);
+ if (m_ec) return set_or_throw(m_ec, ec, "permissions", p);
+ }
+
+ prms = prms & perms::mask;
+ if (add_perms)
+ prms |= st.permissions();
+ else if (remove_perms)
+ prms = st.permissions() & ~prms;
+ auto real_perms = detail::posix_convert_perms(prms);
+
+# if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD)
+ const int flags = set_sym_perms ? AT_SYMLINK_NOFOLLOW : 0;
+ if (::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) {
+# else
+ if (set_sym_perms)
+ return set_or_throw(make_error_code(errc::operation_not_supported),
+ ec, "permissions", p);
+ if (::chmod(p.c_str(), real_perms) == -1) {
+# endif
+ return set_or_throw(ec, "permissions", p);
+ }
+ if (ec) ec->clear();
+}
+
+
+path __read_symlink(const path& p, std::error_code *ec) {
+ char buff[PATH_MAX + 1];
+ std::error_code m_ec;
+ ::ssize_t ret;
+ if ((ret = ::readlink(p.c_str(), buff, PATH_MAX)) == -1) {
+ set_or_throw(ec, "read_symlink", p);
+ return {};
+ }
+ _LIBCPP_ASSERT(ret <= PATH_MAX, "TODO");
+ _LIBCPP_ASSERT(ret > 0, "TODO");
+ if (ec) ec->clear();
+ buff[ret] = 0;
+ return {buff};
+}
+
+
+bool __remove(const path& p, std::error_code *ec) {
+ if (ec) ec->clear();
+ if (::remove(p.c_str()) == -1) {
+ set_or_throw(ec, "remove", p);
+ return false;
+ }
+ return true;
+}
+
+namespace {
+
+std::uintmax_t remove_all_impl(path const & p, std::error_code& ec)
+{
+ const auto npos = static_cast<std::uintmax_t>(-1);
+ const file_status st = __symlink_status(p, &ec);
+ if (ec) return npos;
+ std::uintmax_t count = 1;
+ if (is_directory(st)) {
+ for (directory_iterator it(p, ec); !ec && it != directory_iterator();
+ it.increment(ec)) {
+ auto other_count = remove_all_impl(it->path(), ec);
+ if (ec) return npos;
+ count += other_count;
+ }
+ if (ec) return npos;
+ }
+ if (!__remove(p, &ec)) return npos;
+ return count;
+}
+
+} // end namespace
+
+std::uintmax_t __remove_all(const path& p, std::error_code *ec) {
+ std::error_code mec;
+ auto count = remove_all_impl(p, mec);
+ if (mec) {
+ set_or_throw(mec, ec, "remove_all", p);
+ return static_cast<std::uintmax_t>(-1);
+ }
+ if (ec) ec->clear();
+ return count;
+}
+
+void __rename(const path& from, const path& to, std::error_code *ec) {
+ if (::rename(from.c_str(), to.c_str()) == -1)
+ set_or_throw(ec, "rename", from, to);
+ else if (ec)
+ ec->clear();
+}
+
+void __resize_file(const path& p, std::uintmax_t size, std::error_code *ec) {
+ if (::truncate(p.c_str(), static_cast<long>(size)) == -1)
+ set_or_throw(ec, "resize_file", p);
+ else if (ec)
+ ec->clear();
+}
+
+space_info __space(const path& p, std::error_code *ec) {
+ space_info si;
+ struct statvfs m_svfs;
+ if (::statvfs(p.c_str(), &m_svfs) == -1) {
+ set_or_throw(ec, "space", p);
+ si.capacity = si.free = si.available =
+ static_cast<std::uintmax_t>(-1);
+ return si;
+ }
+ if (ec) ec->clear();
+ // Multiply with overflow checking.
+ auto do_mult = [&](std::uintmax_t& out, fsblkcnt_t other) {
+ out = other * m_svfs.f_frsize;
+ if (out / other != m_svfs.f_frsize || other == 0)
+ out = static_cast<std::uintmax_t>(-1);
+ };
+ do_mult(si.capacity, m_svfs.f_blocks);
+ do_mult(si.free, m_svfs.f_bfree);
+ do_mult(si.available, m_svfs.f_bavail);
+ return si;
+}
+
+file_status __status(const path& p, std::error_code *ec) {
+ return detail::posix_stat(p, ec);
+}
+
+file_status __symlink_status(const path& p, std::error_code *ec) {
+ return detail::posix_lstat(p, ec);
+}
+
+path __system_complete(const path& p, std::error_code *ec) {
+ if (ec) ec->clear();
+ return absolute(p, current_path());
+}
+
+path __temp_directory_path(std::error_code *ec) {
+ const char* env_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
+ const char* ret = nullptr;
+ for (auto & ep : env_paths) {
+ if ((ret = std::getenv(ep)))
+ break;
+ }
+ path p(ret ? ret : "/tmp");
+ std::error_code m_ec;
+ if (is_directory(p, m_ec)) {
+ if (ec) ec->clear();
+ return p;
+ }
+ if (!m_ec || m_ec == make_error_code(errc::no_such_file_or_directory))
+ m_ec = make_error_code(errc::not_a_directory);
+ set_or_throw(m_ec, ec, "temp_directory_path");
+ return {};
+}
+
+// An absolute path is composed according to the table in [fs.op.absolute].
+path absolute(const path& p, const path& base) {
+ auto root_name = p.root_name();
+ auto root_dir = p.root_directory();
+
+ if (!root_name.empty() && !root_dir.empty())
+ return p;
+
+ auto abs_base = base.is_absolute() ? base : absolute(base);
+
+ /* !has_root_name && !has_root_dir */
+ if (root_name.empty() && root_dir.empty())
+ {
+ return abs_base / p;
+ }
+ else if (!root_name.empty()) /* has_root_name && !has_root_dir */
+ {
+ return root_name / abs_base.root_directory()
+ /
+ abs_base.relative_path() / p.relative_path();
+ }
+ else /* !has_root_name && has_root_dir */
+ {
+ if (abs_base.has_root_name())
+ return abs_base.root_name() / p;
+ // else p is absolute, return outside of block
+ }
+ return p;
+}
+
+_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
Added: libcxx/trunk/src/experimental/filesystem/path.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/experimental/filesystem/path.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/src/experimental/filesystem/path.cpp (added)
+++ libcxx/trunk/src/experimental/filesystem/path.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,392 @@
+//===--------------------- filesystem/path.cpp ----------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+#include "experimental/filesystem"
+#include "experimental/string_view"
+#include "utility"
+
+_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
+
+_LIBCPP_CONSTEXPR path::value_type path::preferred_separator;
+
+
+namespace { namespace parser
+{
+
+using string_type = string_view;
+using value_type = path::value_type;
+
+using string_view_pair = pair<string_view, string_view>;
+
+// status reporting
+constexpr size_t npos = static_cast<size_t>(-1);
+
+inline bool good(size_t pos) { return pos != npos; }
+
+// lexical elements
+constexpr value_type preferred_separator = path::preferred_separator;
+constexpr value_type const * preferred_separator_str = "/";
+constexpr value_type const * dot = ".";
+
+// forward //
+bool is_separator(string_type const &, size_t);
+bool is_root_name(const string_type&, size_t);
+bool is_root_directory(string_type const &, size_t);
+bool is_trailing_separator(string_type const &, size_t);
+
+size_t start_of(string_type const &, size_t);
+size_t end_of(string_type const &, size_t);
+
+size_t root_name_start(const string_type& s);
+size_t root_name_end(const string_type&);
+
+size_t root_directory_start(string_type const &);
+size_t root_directory_end(string_type const &);
+
+string_view_pair separate_filename(string_type const &);
+string_view extract_raw(string_type const &, size_t);
+string_view extract_preferred(string_type const &, size_t);
+
+inline bool is_separator(const string_type& s, size_t pos) {
+ return (pos < s.size() && s[pos] == preferred_separator);
+}
+
+inline bool is_root_name(const string_type& s, size_t pos) {
+ return good(pos) && pos == 0 ? root_name_start(s) == pos : false;
+}
+
+inline bool is_root_directory(const string_type& s, size_t pos) {
+ return good(pos) ? root_directory_start(s) == pos : false;
+}
+
+inline bool is_trailing_separator(const string_type& s, size_t pos) {
+ return (pos < s.size() && is_separator(s, pos) &&
+ end_of(s, pos) == s.size()-1 &&
+ !is_root_directory(s, pos) && !is_root_name(s, pos));
+}
+
+size_t start_of(const string_type& s, size_t pos) {
+ if (pos >= s.size()) return npos;
+ bool in_sep = (s[pos] == preferred_separator);
+ while (pos - 1 < s.size() &&
+ (s[pos-1] == preferred_separator) == in_sep)
+ { --pos; }
+ if (pos == 2 && !in_sep && s[0] == preferred_separator &&
+ s[1] == preferred_separator)
+ { return 0; }
+ return pos;
+}
+
+size_t end_of(const string_type& s, size_t pos) {
+ if (pos >= s.size()) return npos;
+ // special case for root name
+ if (pos == 0 && is_root_name(s, pos)) return root_name_end(s);
+ bool in_sep = (s[pos] == preferred_separator);
+ while (pos + 1 < s.size() && (s[pos+1] == preferred_separator) == in_sep)
+ { ++pos; }
+ return pos;
+}
+
+inline size_t root_name_start(const string_type& s) {
+ return good(root_name_end(s)) ? 0 : npos;
+}
+
+size_t root_name_end(const string_type& s) {
+ if (s.size() < 2 || s[0] != preferred_separator
+ || s[1] != preferred_separator) {
+ return npos;
+ }
+ if (s.size() == 2) {
+ return 1;
+ }
+ size_t index = 2; // current position
+ if (s[index] == preferred_separator) {
+ return npos;
+ }
+ while (index + 1 < s.size() && s[index+1] != preferred_separator) {
+ ++index;
+ }
+ return index;
+}
+
+size_t root_directory_start(const string_type& s) {
+ size_t e = root_name_end(s);
+ if (!good(e))
+ return is_separator(s, 0) ? 0 : npos;
+ return is_separator(s, e + 1) ? e + 1 : npos;
+}
+
+size_t root_directory_end(const string_type& s) {
+ size_t st = root_directory_start(s);
+ if (!good(st)) return npos;
+ size_t index = st;
+ while (index + 1 < s.size() && s[index + 1] == preferred_separator)
+ { ++index; }
+ return index;
+}
+
+string_view_pair separate_filename(string_type const & s) {
+ if (s == "." || s == ".." || s.empty()) return string_view_pair{s, ""};
+ auto pos = s.find_last_of('.');
+ if (pos == string_type::npos) return string_view_pair{s, string_view{}};
+ return string_view_pair{s.substr(0, pos), s.substr(pos)};
+}
+
+inline string_view extract_raw(const string_type& s, size_t pos) {
+ size_t end_i = end_of(s, pos);
+ if (!good(end_i)) return string_view{};
+ return string_view(s).substr(pos, end_i - pos + 1);
+}
+
+string_view extract_preferred(const string_type& s, size_t pos) {
+ string_view raw = extract_raw(s, pos);
+ if (raw.empty())
+ return raw;
+ if (is_trailing_separator(s, pos))
+ return string_view{dot};
+ if (is_separator(s, pos) && !is_root_name(s, pos))
+ return string_view(preferred_separator_str);
+ return raw;
+}
+
+}} // namespace parser
+
+
+////////////////////////////////////////////////////////////////////////////////
+// path_view_iterator
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+struct path_view_iterator {
+ const string_view __s_;
+ size_t __pos_;
+
+ explicit path_view_iterator(string_view const& __s) : __s_(__s), __pos_(__s_.empty() ? parser::npos : 0) {}
+ explicit path_view_iterator(string_view const& __s, size_t __p) : __s_(__s), __pos_(__p) {}
+
+ string_view operator*() const {
+ return parser::extract_preferred(__s_, __pos_);
+ }
+
+ path_view_iterator& operator++() {
+ increment();
+ return *this;
+ }
+
+ path_view_iterator& operator--() {
+ decrement();
+ return *this;
+ }
+
+ void increment() {
+ if (__pos_ == parser::npos) return;
+ while (! set_position(parser::end_of(__s_, __pos_)+1))
+ ;
+ return;
+ }
+
+ void decrement() {
+ if (__pos_ == 0) {
+ set_position(0);
+ }
+ else if (__pos_ == parser::npos) {
+ auto const str_size = __s_.size();
+ set_position(parser::start_of(
+ __s_, str_size != 0 ? str_size - 1 : str_size));
+ } else {
+ while (!set_position(parser::start_of(__s_, __pos_-1)))
+ ;
+ }
+ }
+
+ bool set_position(size_t pos) {
+ if (pos >= __s_.size()) {
+ __pos_ = parser::npos;
+ } else {
+ __pos_ = pos;
+ }
+ return valid_iterator_position();
+ }
+
+ bool valid_iterator_position() const {
+ if (__pos_ == parser::npos) return true; // end position is valid
+ return (!parser::is_separator (__s_, __pos_) ||
+ parser::is_root_directory (__s_, __pos_) ||
+ parser::is_trailing_separator(__s_, __pos_) ||
+ parser::is_root_name (__s_, __pos_));
+ }
+
+ bool is_end() const { return __pos_ == parser::npos; }
+
+ inline bool operator==(path_view_iterator const& __p) {
+ return __pos_ == __p.__pos_;
+ }
+};
+
+path_view_iterator pbegin(path const& p) {
+ return path_view_iterator(p.native());
+}
+
+path_view_iterator pend(path const& p) {
+ path_view_iterator __p(p.native());
+ __p.__pos_ = parser::npos;
+ return __p;
+}
+
+} // end namespace
+///////////////////////////////////////////////////////////////////////////////
+// path definitions
+///////////////////////////////////////////////////////////////////////////////
+
+path & path::replace_extension(path const & replacement)
+{
+ path p = extension();
+ if (not p.empty()) {
+ __pn_.erase(__pn_.size() - p.native().size());
+ }
+ if (!replacement.empty()) {
+ if (replacement.native()[0] != '.') {
+ __pn_ += ".";
+ }
+ __pn_.append(replacement.__pn_);
+ }
+ return *this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// path.decompose
+
+string_view path::__root_name() const
+{
+ return parser::is_root_name(__pn_, 0)
+ ? parser::extract_preferred(__pn_, 0)
+ : string_view{};
+}
+
+string_view path::__root_directory() const
+{
+ auto start_i = parser::root_directory_start(__pn_);
+ if(!parser::good(start_i)) {
+ return {};
+ }
+ return parser::extract_preferred(__pn_, start_i);
+}
+
+string_view path::__relative_path() const
+{
+ if (empty()) {
+ return {__pn_};
+ }
+ auto end_i = parser::root_directory_end(__pn_);
+ if (not parser::good(end_i)) {
+ end_i = parser::root_name_end(__pn_);
+ }
+ if (not parser::good(end_i)) {
+ return {__pn_};
+ }
+ return string_view(__pn_).substr(end_i+1);
+}
+
+string_view path::__parent_path() const
+{
+ if (empty() || pbegin(*this) == --pend(*this)) {
+ return {};
+ }
+ auto end_it = --(--pend(*this));
+ auto end_i = parser::end_of(__pn_, end_it.__pos_);
+ return string_view(__pn_).substr(0, end_i+1);
+}
+
+string_view path::__filename() const
+{
+ return empty() ? string_view{} : *--pend(*this);
+}
+
+string_view path::__stem() const
+{
+ return parser::separate_filename(__filename()).first;
+}
+
+string_view path::__extension() const
+{
+ return parser::separate_filename(__filename()).second;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.comparisons
+int path::__compare(const value_type* __s) const {
+ path_view_iterator thisIter(this->native());
+ path_view_iterator sIter(__s);
+ while (!thisIter.is_end() && !sIter.is_end()) {
+ int res = (*thisIter).compare(*sIter);
+ if (res != 0) return res;
+ ++thisIter; ++sIter;
+ }
+ if (thisIter.is_end() && sIter.is_end())
+ return 0;
+ if (thisIter.is_end())
+ return -1;
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.nonmembers
+size_t hash_value(const path& __p) _NOEXCEPT {
+ path_view_iterator thisIter(__p.native());
+ struct HashPairT {
+ size_t first;
+ size_t second;
+ };
+ HashPairT hp = {0, 0};
+ std::hash<string_view> hasher;
+ std::__scalar_hash<decltype(hp)> pair_hasher;
+ while (!thisIter.is_end()) {
+ hp.second = hasher(*thisIter);
+ hp.first = pair_hasher(hp);
+ ++thisIter;
+ }
+ return hp.first;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.itr
+path::iterator path::begin() const
+{
+ path_view_iterator pit = pbegin(*this);
+ iterator it;
+ it.__path_ptr_ = this;
+ it.__pos_ = pit.__pos_;
+ it.__elem_.__assign_view(*pit);
+ return it;
+}
+
+path::iterator path::end() const
+{
+ iterator it{};
+ it.__path_ptr_ = this;
+ it.__pos_ = parser::npos;
+ return it;
+}
+
+path::iterator& path::iterator::__increment() {
+ path_view_iterator it(__path_ptr_->native(), __pos_);
+ it.increment();
+ __pos_ = it.__pos_;
+ __elem_.__assign_view(*it);
+ return *this;
+}
+
+path::iterator& path::iterator::__decrement() {
+ path_view_iterator it(__path_ptr_->native(), __pos_);
+ it.decrement();
+ __pos_ = it.__pos_;
+ __elem_.__assign_view(*it);
+ return *this;
+}
+
+_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
Modified: libcxx/trunk/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/CMakeLists.txt?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/test/CMakeLists.txt (original)
+++ libcxx/trunk/test/CMakeLists.txt Fri Jun 17 14:46:40 2016
@@ -11,6 +11,7 @@ set(LIBCXX_LIT_VARIANT "libcxx" CACHE ST
pythonize_bool(LIBCXX_ENABLE_EXCEPTIONS)
pythonize_bool(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
+pythonize_bool(LIBCXX_ENABLE_FILESYSTEM)
pythonize_bool(LIBCXX_ENABLE_RTTI)
pythonize_bool(LIBCXX_ENABLE_SHARED)
pythonize_bool(LIBCXX_BUILD_32_BITS)
Added: libcxx/trunk/test/libcxx/experimental/filesystem/class.path/path.req/is_pathable.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/filesystem/class.path/path.req/is_pathable.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/filesystem/class.path/path.req/is_pathable.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/experimental/filesystem/class.path/path.req/is_pathable.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// template <class Tp> struct __is_pathable
+
+// [path.req]
+// In addition to the requirements (5), function template parameters named
+// `Source` shall be one of:
+// * basic_string<_ECharT, _Traits, _Alloc>
+// * InputIterator with a value_type of _ECharT
+// * A character array, which points to a NTCTS after array-to-pointer decay.
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "min_allocator.h"
+
+namespace fs = std::experimental::filesystem;
+
+using fs::__is_pathable;
+
+template <class Tp>
+struct Identity { typedef Tp type; };
+
+template <class Source>
+Identity<Source> CheckSourceType(Source const&);
+
+template <class Tp>
+using GetSourceType = typename decltype(CheckSourceType(std::declval<Tp>()))::type;
+
+template <class Tp, class Exp,
+ class ExpQual = typename std::remove_const<Exp>::type>
+using CheckPass = std::is_same<ExpQual, GetSourceType<Tp>>;
+
+template <class Source>
+using CheckPassSource = std::integral_constant<bool,
+ CheckPass<Source&, Source>::value &&
+ CheckPass<Source const&, Source>::value &&
+ CheckPass<Source&&, Source>::value &&
+ CheckPass<Source const&&, Source>::value
+ >;
+
+template <class CharT>
+struct MakeTestType {
+ using value_type = CharT;
+ using string_type = std::basic_string<CharT>;
+ using string_type2 = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>;
+ using cstr_type = CharT* const;
+ using const_cstr_type = const CharT*;
+ using array_type = CharT[25];
+ using const_array_type = const CharT[25];
+ using iter_type = input_iterator<CharT*>;
+ using bad_iter_type = input_iterator<signed char*>;
+
+ template <class TestT>
+ static void AssertPathable() {
+ static_assert(__is_pathable<TestT>::value, "");
+ static_assert(CheckPassSource<TestT>::value, "cannot pass as Source const&");
+ ASSERT_SAME_TYPE(CharT, typename __is_pathable<TestT>::__char_type);
+ }
+
+ template <class TestT>
+ static void AssertNotPathable() {
+ static_assert(!__is_pathable<TestT>::value, "");
+ }
+
+ static void Test() {
+ AssertPathable<string_type>();
+ AssertPathable<string_type2>();
+ AssertPathable<cstr_type>();
+ AssertPathable<const_cstr_type>();
+ AssertPathable<array_type>();
+ AssertPathable<const_array_type>();
+ AssertPathable<iter_type>();
+
+ AssertNotPathable<CharT>();
+ AssertNotPathable<bad_iter_type>();
+ AssertNotPathable<signed char*>();
+ }
+};
+
+int main() {
+ MakeTestType<char>::Test();
+ MakeTestType<wchar_t>::Test();
+ MakeTestType<char16_t>::Test();
+ MakeTestType<char32_t>::Test();
+}
Added: libcxx/trunk/test/libcxx/experimental/filesystem/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/filesystem/lit.local.cfg?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/filesystem/lit.local.cfg (added)
+++ libcxx/trunk/test/libcxx/experimental/filesystem/lit.local.cfg Fri Jun 17 14:46:40 2016
@@ -0,0 +1,3 @@
+# Disable all of the filesystem tests if the correct feature is not available.
+if 'c++filesystem' not in config.available_features:
+ config.unsupported = True
Added: libcxx/trunk/test/libcxx/experimental/filesystem/version.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/filesystem/version.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/filesystem/version.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/experimental/filesystem/version.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+#include <experimental/filesystem>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
Modified: libcxx/trunk/test/libcxx/test/config.py
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/test/config.py?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/test/config.py (original)
+++ libcxx/trunk/test/libcxx/test/config.py Fri Jun 17 14:46:40 2016
@@ -103,6 +103,7 @@ class Configuration(object):
self.configure_execute_external()
self.configure_ccache()
self.configure_compile_flags()
+ self.configure_filesystem_compile_flags()
self.configure_link_flags()
self.configure_env()
self.configure_color_diagnostics()
@@ -427,6 +428,35 @@ class Configuration(object):
self.config.available_features.add('libcpp-abi-unstable')
self.cxx.compile_flags += ['-D_LIBCPP_ABI_UNSTABLE']
+ def configure_filesystem_compile_flags(self):
+ enable_fs = self.get_lit_bool('enable_filesystem', default=False)
+ if not enable_fs:
+ return
+ enable_experimental = self.get_lit_bool('enable_experimental', default=False)
+ if not enable_experimental:
+ self.lit_config.fatal(
+ 'filesystem is enabled but libc++experimental.a is not.')
+ self.config.available_features.add('c++filesystem')
+ static_env = os.path.join(self.libcxx_src_root, 'test', 'std',
+ 'experimental', 'filesystem', 'Inputs', 'static_test_env')
+ assert os.path.isdir(static_env)
+ self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_STATIC_TEST_ROOT="%s"' % static_env]
+
+ dynamic_env = os.path.join(self.libcxx_obj_root, 'test',
+ 'filesystem', 'Output', 'dynamic_env')
+ if not os.path.isdir(dynamic_env):
+ os.makedirs(dynamic_env)
+ self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT="%s"' % dynamic_env]
+ self.env['LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT'] = ("%s" % dynamic_env)
+
+ dynamic_helper = os.path.join(self.libcxx_src_root, 'test', 'support',
+ 'filesystem_dynamic_test_helper.py')
+ assert os.path.isfile(dynamic_helper)
+
+ self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER="%s %s"'
+ % (sys.executable, dynamic_helper)]
+
+
def configure_link_flags(self):
no_default_flags = self.get_lit_bool('no_default_flags', False)
if not no_default_flags:
Modified: libcxx/trunk/test/lit.site.cfg.in
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/lit.site.cfg.in?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/test/lit.site.cfg.in (original)
+++ libcxx/trunk/test/lit.site.cfg.in Fri Jun 17 14:46:40 2016
@@ -6,6 +6,7 @@ config.libcxx_obj_root = "@LIBC
config.cxx_library_root = "@LIBCXX_LIBRARY_DIR@"
config.enable_exceptions = "@LIBCXX_ENABLE_EXCEPTIONS@"
config.enable_experimental = "@LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY@"
+config.enable_filesystem = "@LIBCXX_ENABLE_FILESYSTEM@"
config.enable_rtti = "@LIBCXX_ENABLE_RTTI@"
config.enable_shared = "@LIBCXX_ENABLE_SHARED@"
config.enable_32bit = "@LIBCXX_BUILD_32_BITS@"
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink (added)
+++ libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink Fri Jun 17 14:46:40 2016
@@ -0,0 +1 @@
+link dne
\ No newline at end of file
Propchange: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink
------------------------------------------------------------------------------
svn:special = *
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/afile3
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/afile3?rev=273034&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/file5
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/file5?rev=273034&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/file4
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/file4?rev=273034&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 (added)
+++ libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 Fri Jun 17 14:46:40 2016
@@ -0,0 +1 @@
+link dir3
\ No newline at end of file
Propchange: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3
------------------------------------------------------------------------------
svn:special = *
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file1
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file1?rev=273034&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2 (added)
+++ libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2 Fri Jun 17 14:46:40 2016
@@ -0,0 +1 @@
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
\ No newline at end of file
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/empty_file
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/empty_file?rev=273034&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file (added)
+++ libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file Fri Jun 17 14:46:40 2016
@@ -0,0 +1 @@
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
\ No newline at end of file
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir (added)
+++ libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir Fri Jun 17 14:46:40 2016
@@ -0,0 +1 @@
+link dir1
\ No newline at end of file
Propchange: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir
------------------------------------------------------------------------------
svn:special = *
Added: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file (added)
+++ libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file Fri Jun 17 14:46:40 2016
@@ -0,0 +1 @@
+link empty_file
\ No newline at end of file
Propchange: libcxx/trunk/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file
------------------------------------------------------------------------------
svn:special = *
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_entry
+
+// directory_entry() noexcept = default;
+// directory_entry(const directory_entry&) = default;
+// directory_entry(directory_entry&&) noexcept = default;
+// explicit directory_entry(const path);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+namespace fs = std::experimental::filesystem;
+
+void test_default_ctor()
+{
+ using namespace fs;
+ // Default
+ {
+ static_assert(std::is_nothrow_default_constructible<directory_entry>::value,
+ "directory_entry must have a nothrow default constructor");
+ directory_entry e;
+ assert(e.path() == path());
+ }
+}
+
+
+void test_copy_ctor()
+{
+ using namespace fs;
+ // Copy
+ {
+ static_assert(std::is_copy_constructible<directory_entry>::value,
+ "directory_entry must be copy constructible");
+ static_assert(!std::is_nothrow_copy_constructible<directory_entry>::value,
+ "directory_entry's copy constructor cannot be noexcept");
+ const path p("foo/bar/baz");
+ const directory_entry e(p);
+ assert(e.path() == p);
+ directory_entry e2(e);
+ assert(e.path() == p);
+ assert(e2.path() == p);
+ }
+
+}
+
+void test_move_ctor()
+{
+ using namespace fs;
+ // Move
+ {
+ static_assert(std::is_nothrow_move_constructible<directory_entry>::value,
+ "directory_entry must be nothrow move constructible");
+ const path p("foo/bar/baz");
+ directory_entry e(p);
+ assert(e.path() == p);
+ directory_entry e2(std::move(e));
+ assert(e2.path() == p);
+ assert(e.path() != p); // Testing moved from state.
+ }
+}
+
+void test_path_ctor() {
+ using namespace fs;
+ {
+ static_assert(std::is_constructible<directory_entry, const path&>::value,
+ "directory_entry must be constructible from path");
+ static_assert(!std::is_nothrow_constructible<directory_entry, const path&>::value,
+ "directory_entry constructor should not be noexcept");
+ static_assert(!std::is_convertible<path const&, directory_entry>::value,
+ "directory_entry constructor should be explicit");
+ }
+ {
+ const path p("foo/bar/baz");
+ const directory_entry e(p);
+ assert(p == e.path());
+ }
+}
+
+int main() {
+ test_default_ctor();
+ test_copy_ctor();
+ test_move_ctor();
+ test_path_ctor();
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_entry
+
+// directory_entry& operator=(directory_entry const&) = default;
+// directory_entry& operator=(directory_entry&&) noexcept = default;
+// void assign(path const&);
+// void replace_filename(path const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+namespace fs = std::experimental::filesystem;
+
+void test_copy_assign_operator()
+{
+ using namespace fs;
+ // Copy
+ {
+ static_assert(std::is_copy_assignable<directory_entry>::value,
+ "directory_entry must be copy assignable");
+ static_assert(!std::is_nothrow_copy_assignable<directory_entry>::value,
+ "directory_entry's copy assignment cannot be noexcept");
+ const path p("foo/bar/baz");
+ const path p2("abc");
+ const directory_entry e(p);
+ directory_entry e2;
+ assert(e.path() == p && e2.path() == path());
+ e2 = e;
+ assert(e.path() == p && e2.path() == p);
+ directory_entry e3(p2);
+ e2 = e3;
+ assert(e2.path() == p2 && e3.path() == p2);
+ }
+}
+
+
+void test_move_assign_operator()
+{
+ using namespace fs;
+ // Copy
+ {
+ static_assert(std::is_nothrow_move_assignable<directory_entry>::value,
+ "directory_entry is noexcept move assignable");
+ const path p("foo/bar/baz");
+ const path p2("abc");
+ directory_entry e(p);
+ directory_entry e2(p2);
+ assert(e.path() == p && e2.path() == p2);
+ e2 = std::move(e);
+ assert(e2.path() == p);
+ assert(e.path() != p); // testing moved from state
+ }
+}
+
+void test_path_assign_method()
+{
+ using namespace fs;
+ const path p("foo/bar/baz");
+ const path p2("abc");
+ directory_entry e(p);
+ {
+ static_assert(std::is_same<decltype(e.assign(p)), void>::value,
+ "return type should be void");
+ static_assert(noexcept(e.assign(p)) == false, "operation must not be noexcept");
+ }
+ {
+ assert(e.path() == p);
+ e.assign(p2);
+ assert(e.path() == p2 && e.path() != p);
+ e.assign(p);
+ assert(e.path() == p && e.path() != p2);
+ }
+}
+
+void test_replace_filename_method()
+{
+ using namespace fs;
+ const path p("/path/to/foo.exe");
+ const path replace("bar.out");
+ const path expect("/path/to/bar.out");
+ directory_entry e(p);
+ {
+ static_assert(noexcept(e.replace_filename(replace)) == false,
+ "operation cannot be noexcept");
+ static_assert(std::is_same<decltype(e.replace_filename(replace)), void>::value,
+ "operation must return void");
+ }
+ {
+ assert(e.path() == p);
+ e.replace_filename(replace);
+ assert(e.path() == expect);
+ }
+}
+
+int main() {
+ test_copy_assign_operator();
+ test_move_assign_operator();
+ test_path_assign_method();
+ test_replace_filename_method();
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_entry
+
+// bool operator==(directory_entry const&) const noexcept;
+// bool operator!=(directory_entry const&) const noexcept;
+// bool operator< (directory_entry const&) const noexcept;
+// bool operator<=(directory_entry const&) const noexcept;
+// bool operator> (directory_entry const&) const noexcept;
+// bool operator>=(directory_entry const&) const noexcept;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+namespace fs = std::experimental::filesystem;
+
+#define CHECK_OP(Op) \
+ static_assert(std::is_same<decltype(ce. operator Op (ce)), bool>::value, ""); \
+ static_assert(noexcept(ce.operator Op (ce)), "Operation must be noexcept" )
+
+void test_comparison_signatures() {
+ using namespace fs;
+ path const p("foo/bar/baz");
+ // Check that the operators are member functions with the correct signatures.
+ {
+ directory_entry const ce(p);
+ CHECK_OP(==);
+ CHECK_OP(!=);
+ CHECK_OP(< );
+ CHECK_OP(<=);
+ CHECK_OP(> );
+ CHECK_OP(>=);
+ }
+}
+#undef CHECK_OP
+
+// The actual semantics of the comparisons are testing via paths operators.
+void test_comparisons_simple() {
+ using namespace fs;
+ typedef std::pair<path, path> TestType;
+ TestType TestCases[] =
+ {
+ {"", ""},
+ {"", "a"},
+ {"a", "a"},
+ {"a", "b"},
+ {"foo/bar/baz", "foo/bar/baz/"}
+ };
+ auto TestFn = [](path const& LHS, const directory_entry& LHSE,
+ path const& RHS, const directory_entry& RHSE) {
+ assert((LHS == RHS) == (LHSE == RHSE));
+ assert((LHS != RHS) == (LHSE != RHSE));
+ assert((LHS < RHS) == (LHSE < RHSE));
+ assert((LHS <= RHS) == (LHSE <= RHSE));
+ assert((LHS > RHS) == (LHSE > RHSE));
+ assert((LHS >= RHS) == (LHSE >= RHSE));
+ };
+ for (auto const& TC : TestCases) {
+ const directory_entry L(TC.first);
+ const directory_entry R(TC.second);
+ TestFn(TC.first, L, TC.second, R);
+ TestFn(TC.second, R, TC.first, L);
+ }
+}
+
+int main() {
+ test_comparison_signatures();
+ test_comparisons_simple();
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_entry
+
+// const path& path() const noexcept;
+// operator const path&() const noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+namespace fs = std::experimental::filesystem;
+
+void test_path_method() {
+ using namespace fs;
+ const path p("foo/bar/baz.exe");
+ const path p2("abc");
+ {
+ directory_entry nce;
+ const directory_entry e("");
+ static_assert(std::is_same<decltype(e.path()), const path&>::value, "");
+ static_assert(std::is_same<decltype(nce.path()), const path&>::value, "");
+ static_assert(noexcept(e.path()) && noexcept(nce.path()), "");
+ }
+ {
+ directory_entry e(p);
+ path const& pref = e.path();
+ assert(pref == p);
+ assert(&pref == &e.path());
+ e.assign(p2);
+ assert(pref == p2);
+ assert(&pref == &e.path());
+ }
+}
+
+void test_path_conversion() {
+ using namespace fs;
+ const path p("foo/bar/baz.exe");
+ const path p2("abc");
+ {
+ directory_entry nce;
+ const directory_entry e("");
+ // Check conversions exist
+ static_assert(std::is_convertible<directory_entry&, path const&>::value, "");
+ static_assert(std::is_convertible<directory_entry const&, path const&>::value, "");
+ static_assert(std::is_convertible<directory_entry &&, path const&>::value, "");
+ static_assert(std::is_convertible<directory_entry const&&, path const&>::value, "");
+ // Not convertible to non-const
+ static_assert(!std::is_convertible<directory_entry&, path&>::value, "");
+ static_assert(!std::is_convertible<directory_entry const&, path&>::value, "");
+ static_assert(!std::is_convertible<directory_entry &&, path&>::value, "");
+ static_assert(!std::is_convertible<directory_entry const&&, path&>::value, "");
+ // conversions are noexcept
+ static_assert(noexcept(e.operator fs::path const&()) &&
+ noexcept(e.operator fs::path const&()), "");
+ }
+ // const
+ {
+ directory_entry const e(p);
+ path const& pref = e;
+ assert(&pref == &e.path());
+ }
+ // non-const
+ {
+ directory_entry e(p);
+ path const& pref = e;
+ assert(&pref == &e.path());
+
+ e.assign(p2);
+ assert(pref == p2);
+ assert(&pref == &e.path());
+ }
+}
+
+int main() {
+ test_path_method();
+ test_path_conversion();
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_entry
+
+// file_status status() const;
+// file_status status(error_code const&) const noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "filesystem_test_helper.hpp"
+
+int main()
+{
+ using namespace fs;
+ {
+ const directory_entry e("foo");
+ std::error_code ec;
+ static_assert(std::is_same<decltype(e.status()), file_status>::value, "");
+ static_assert(std::is_same<decltype(e.status(ec)), file_status>::value, "");
+ static_assert(noexcept(e.status()) == false, "");
+ static_assert(noexcept(e.status(ec)) == true, "");
+ }
+ auto TestFn = [](path const& p) {
+ const directory_entry e(p);
+ std::error_code pec, eec;
+ file_status ps = fs::status(p, pec);
+ file_status es = e.status(eec);
+ assert(ps.type() == es.type());
+ assert(ps.permissions() == es.permissions());
+ assert(pec == eec);
+ };
+ {
+ TestFn(StaticEnv::File);
+ TestFn(StaticEnv::Dir);
+ TestFn(StaticEnv::SymlinkToFile);
+ TestFn(StaticEnv::DNE);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_entry
+
+// file_status symlink_status() const;
+// file_status symlink_status(error_code&) const noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "filesystem_test_helper.hpp"
+
+int main() {
+ using namespace fs;
+ {
+ const directory_entry e("foo");
+ std::error_code ec;
+ static_assert(std::is_same<decltype(e.symlink_status()), file_status>::value, "");
+ static_assert(std::is_same<decltype(e.symlink_status(ec)), file_status>::value, "");
+ static_assert(noexcept(e.symlink_status()) == false, "");
+ static_assert(noexcept(e.symlink_status(ec)) == true, "");
+ }
+ auto TestFn = [](path const& p) {
+ const directory_entry e(p);
+ std::error_code pec, eec;
+ file_status ps = fs::symlink_status(p, pec);
+ file_status es = e.symlink_status(eec);
+ assert(ps.type() == es.type());
+ assert(ps.permissions() == es.permissions());
+ assert(pec == eec);
+ };
+ {
+ TestFn(StaticEnv::File);
+ TestFn(StaticEnv::Dir);
+ TestFn(StaticEnv::SymlinkToFile);
+ TestFn(StaticEnv::DNE);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+// directory_iterator(directory_iterator const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(directory_iterator_copy_construct_tests)
+
+TEST_CASE(test_constructor_signature)
+{
+ using D = directory_iterator;
+ static_assert(std::is_copy_constructible<D>::value, "");
+}
+
+TEST_CASE(test_copy_end_iterator)
+{
+ const directory_iterator endIt;
+ directory_iterator it(endIt);
+ TEST_CHECK(it == endIt);
+}
+
+TEST_CASE(test_copy_valid_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+ const directory_iterator endIt{};
+
+ const directory_iterator it(testDir);
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+
+ const directory_iterator it2(it);
+ TEST_REQUIRE(it2 == it);
+ TEST_CHECK(*it2 == entry);
+ TEST_CHECK(*it == entry);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+// directory_iterator& operator=(directory_iterator const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(directory_iterator_copy_assign_tests)
+
+TEST_CASE(test_assignment_signature)
+{
+ using D = directory_iterator;
+ static_assert(std::is_copy_assignable<D>::value, "");
+}
+
+TEST_CASE(test_copy_to_end_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+
+ const directory_iterator from(testDir);
+ TEST_REQUIRE(from != directory_iterator{});
+ const path entry = *from;
+
+ directory_iterator to{};
+ to = from;
+ TEST_REQUIRE(to == from);
+ TEST_CHECK(*to == entry);
+ TEST_CHECK(*from == entry);
+}
+
+
+TEST_CASE(test_copy_from_end_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+
+ const directory_iterator from{};
+
+ directory_iterator to(testDir);
+ TEST_REQUIRE(to != directory_iterator{});
+
+ to = from;
+ TEST_REQUIRE(to == from);
+ TEST_CHECK(to == directory_iterator{});
+}
+
+TEST_CASE(test_copy_valid_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+ const directory_iterator endIt{};
+
+ directory_iterator it_obj(testDir);
+ const directory_iterator& it = it_obj;
+ TEST_REQUIRE(it != endIt);
+ ++it_obj;
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+
+ directory_iterator it2(testDir);
+ TEST_REQUIRE(it2 != it);
+ const path entry2 = *it2;
+ TEST_CHECK(entry2 != entry);
+
+ it2 = it;
+ TEST_REQUIRE(it2 == it);
+ TEST_CHECK(*it2 == entry);
+}
+
+TEST_CASE(test_returns_reference_to_self)
+{
+ const directory_iterator it;
+ directory_iterator it2;
+ directory_iterator& ref = (it2 = it);
+ TEST_CHECK(&ref == &it2);
+}
+
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,246 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+// explicit directory_iterator(const path& p);
+// directory_iterator(const path& p, directory_options options);
+// directory_iterator(const path& p, error_code& ec) noexcept;
+// directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(directory_iterator_constructor_tests)
+
+TEST_CASE(test_constructor_signatures)
+{
+ using D = directory_iterator;
+
+ // explicit directory_iterator(path const&);
+ static_assert(!std::is_convertible<path, D>::value, "");
+ static_assert(std::is_constructible<D, path>::value, "");
+ static_assert(!std::is_nothrow_constructible<D, path>::value, "");
+
+ // directory_iterator(path const&, error_code&) noexcept
+ static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, "");
+
+ // directory_iterator(path const&, directory_options);
+ static_assert(std::is_constructible<D, path, directory_options>::value, "");
+ static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, "");
+
+ // directory_iterator(path const&, directory_options, error_code&) noexcept
+ static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, "");
+}
+
+TEST_CASE(test_construction_from_bad_path)
+{
+ std::error_code ec;
+ directory_options opts = directory_options::none;
+ const directory_iterator endIt;
+
+ const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink };
+ for (path const& testPath : testPaths)
+ {
+ {
+ directory_iterator it(testPath, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(it == endIt);
+ }
+ {
+ directory_iterator it(testPath, opts, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(it == endIt);
+ }
+ {
+ TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath));
+ TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath, opts));
+ }
+ }
+}
+
+TEST_CASE(access_denied_test_case)
+{
+ using namespace std::experimental::filesystem;
+ scoped_test_env env;
+ path const testDir = env.make_env_path("dir1");
+ path const testFile = testDir / "testFile";
+ env.create_dir(testDir);
+ env.create_file(testFile, 42);
+
+ // Test that we can iterator over the directory before changing the perms
+ directory_iterator it(testDir);
+ TEST_REQUIRE(it != directory_iterator{});
+
+ // Change the permissions so we can no longer iterate
+ permissions(testDir, perms::none);
+
+ // Check that the construction fails when skip_permissions_denied is
+ // not given.
+ {
+ std::error_code ec;
+ directory_iterator it(testDir, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(it == directory_iterator{});
+ }
+ // Check that construction does not report an error when
+ // 'skip_permissions_denied' is given.
+ {
+ std::error_code ec;
+ directory_iterator it(testDir, directory_options::skip_permission_denied, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(it == directory_iterator{});
+ }
+}
+
+
+TEST_CASE(access_denied_to_file_test_case)
+{
+ using namespace std::experimental::filesystem;
+ scoped_test_env env;
+ path const testFile = env.make_env_path("file1");
+ env.create_file(testFile, 42);
+
+ // Change the permissions so we can no longer iterate
+ permissions(testFile, perms::none);
+
+ // Check that the construction fails when skip_permissions_denied is
+ // not given.
+ {
+ std::error_code ec;
+ directory_iterator it(testFile, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(it == directory_iterator{});
+ }
+ // Check that construction still fails when 'skip_permissions_denied' is given
+ // because we tried to open a file and not a directory.
+ {
+ std::error_code ec;
+ directory_iterator it(testFile, directory_options::skip_permission_denied, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(it == directory_iterator{});
+ }
+}
+
+TEST_CASE(test_open_on_empty_directory_equals_end)
+{
+ scoped_test_env env;
+ const path testDir = env.make_env_path("dir1");
+ env.create_dir(testDir);
+
+ const directory_iterator endIt;
+ {
+ std::error_code ec;
+ directory_iterator it(testDir, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(it == endIt);
+ }
+ {
+ directory_iterator it(testDir);
+ TEST_CHECK(it == endIt);
+ }
+}
+
+TEST_CASE(test_open_on_directory_succeeds)
+{
+ const path testDir = StaticEnv::Dir;
+ std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList),
+ std::end( StaticEnv::DirIterationList));
+ const directory_iterator endIt{};
+
+ {
+ std::error_code ec;
+ directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(it != endIt);
+ TEST_CHECK(dir_contents.count(*it));
+ }
+ {
+ directory_iterator it(testDir);
+ TEST_CHECK(it != endIt);
+ TEST_CHECK(dir_contents.count(*it));
+ }
+}
+
+TEST_CASE(test_open_on_file_fails)
+{
+ const path testFile = StaticEnv::File;
+ const directory_iterator endIt{};
+ {
+ std::error_code ec;
+ directory_iterator it(testFile, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(it == endIt);
+ }
+ {
+ TEST_CHECK_THROW(filesystem_error, directory_iterator(testFile));
+ }
+}
+
+TEST_CASE(test_open_on_empty_string)
+{
+ const path testPath = "";
+ const directory_iterator endIt{};
+
+ std::error_code ec;
+ directory_iterator it(testPath, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(it == endIt);
+}
+
+TEST_CASE(test_open_on_dot_dir)
+{
+ const path testPath = ".";
+
+ std::error_code ec;
+ directory_iterator it(testPath, ec);
+ TEST_CHECK(!ec);
+}
+
+TEST_CASE(test_open_on_symlink)
+{
+ const path symlinkToDir = StaticEnv::SymlinkToDir;
+ std::set<path> dir_contents;
+ for (path const& p : StaticEnv::DirIterationList) {
+ dir_contents.insert(p.filename());
+ }
+ const directory_iterator endIt{};
+
+ {
+ std::error_code ec;
+ directory_iterator it(symlinkToDir, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(it != endIt);
+ path const& entry = *it;
+ TEST_CHECK(dir_contents.count(entry.filename()));
+ }
+ {
+ std::error_code ec;
+ directory_iterator it(symlinkToDir,
+ directory_options::follow_directory_symlink, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(it != endIt);
+ path const& entry = *it;
+ TEST_CHECK(dir_contents.count(entry.filename()));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+// directory_iterator::directory_iterator() noexcept
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ {
+ static_assert(std::is_nothrow_default_constructible<fs::directory_iterator>::value, "");
+ }
+ {
+ fs::directory_iterator d1;
+ const fs::directory_iterator d2;
+ assert(d1 == d2);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+// directory_iterator& operator++();
+// directory_iterator& increment(error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+#include <iostream>
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(directory_iterator_increment_tests)
+
+TEST_CASE(test_increment_signatures)
+{
+ using D = directory_iterator;
+ directory_iterator d; ((void)d);
+ std::error_code ec; ((void)ec);
+
+ ASSERT_SAME_TYPE(decltype(++d), directory_iterator&);
+ ASSERT_NOT_NOEXCEPT(++d);
+
+ ASSERT_SAME_TYPE(decltype(d.increment(ec)), directory_iterator&);
+ ASSERT_NOEXCEPT(d.increment(ec));
+}
+
+TEST_CASE(test_prefix_increment)
+{
+ const path testDir = StaticEnv::Dir;
+ const std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList),
+ std::end( StaticEnv::DirIterationList));
+ const directory_iterator endIt{};
+
+ std::error_code ec;
+ directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+
+ std::set<path> unseen_entries = dir_contents;
+ while (!unseen_entries.empty()) {
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+ TEST_REQUIRE(unseen_entries.erase(entry) == 1);
+ directory_iterator& it_ref = ++it;
+ TEST_CHECK(&it_ref == &it);
+ }
+
+ TEST_CHECK(it == endIt);
+}
+
+TEST_CASE(test_postfix_increment)
+{
+ const path testDir = StaticEnv::Dir;
+ const std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList),
+ std::end( StaticEnv::DirIterationList));
+ const directory_iterator endIt{};
+
+ std::error_code ec;
+ directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+
+ std::set<path> unseen_entries = dir_contents;
+ while (!unseen_entries.empty()) {
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+ TEST_REQUIRE(unseen_entries.erase(entry) == 1);
+ const path entry2 = *it++;
+ TEST_CHECK(entry2 == entry);
+ }
+
+ TEST_CHECK(it == endIt);
+}
+
+
+TEST_CASE(test_increment_method)
+{
+ const path testDir = StaticEnv::Dir;
+ const std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList),
+ std::end( StaticEnv::DirIterationList));
+ const directory_iterator endIt{};
+
+ std::error_code ec;
+ directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+
+ std::set<path> unseen_entries = dir_contents;
+ while (!unseen_entries.empty()) {
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+ TEST_REQUIRE(unseen_entries.erase(entry) == 1);
+ directory_iterator& it_ref = it.increment(ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(&it_ref == &it);
+ }
+
+ TEST_CHECK(it == endIt);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp Fri Jun 17 14:46:40 2016
@@ -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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+// directory_iterator(directory_iterator&&) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(directory_iterator_move_construct_tests)
+
+TEST_CASE(test_constructor_signature)
+{
+ using D = directory_iterator;
+ static_assert(std::is_nothrow_move_constructible<D>::value, "");
+}
+
+TEST_CASE(test_move_end_iterator)
+{
+ const directory_iterator endIt;
+ directory_iterator endIt2{};
+
+ directory_iterator it(std::move(endIt2));
+ TEST_CHECK(it == endIt);
+ TEST_CHECK(endIt2 == endIt);
+}
+
+TEST_CASE(test_move_valid_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+ const directory_iterator endIt{};
+
+ directory_iterator it(testDir);
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+
+ const directory_iterator it2(std::move(it));
+ TEST_CHECK(*it2 == entry);
+
+ TEST_CHECK(it == it2 || it == endIt);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+// directory_iterator& operator=(directory_iterator const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(directory_iterator_move_assign_tests)
+
+TEST_CASE(test_assignment_signature)
+{
+ using D = directory_iterator;
+ static_assert(std::is_nothrow_move_assignable<D>::value, "");
+}
+
+TEST_CASE(test_move_to_end_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+
+ directory_iterator from(testDir);
+ TEST_REQUIRE(from != directory_iterator{});
+ const path entry = *from;
+
+ directory_iterator to{};
+ to = std::move(from);
+ TEST_REQUIRE(to != directory_iterator{});
+ TEST_CHECK(*to == entry);
+}
+
+
+TEST_CASE(test_move_from_end_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+
+ directory_iterator from{};
+
+ directory_iterator to(testDir);
+ TEST_REQUIRE(to != from);
+
+ to = std::move(from);
+ TEST_REQUIRE(to == directory_iterator{});
+ TEST_REQUIRE(from == directory_iterator{});
+}
+
+TEST_CASE(test_move_valid_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+ const directory_iterator endIt{};
+
+ directory_iterator it(testDir);
+ TEST_REQUIRE(it != endIt);
+ ++it;
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+
+ directory_iterator it2(testDir);
+ TEST_REQUIRE(it2 != it);
+ const path entry2 = *it2;
+ TEST_CHECK(entry2 != entry);
+
+ it2 = std::move(it);
+ TEST_REQUIRE(it2 != directory_iterator{});
+ TEST_CHECK(*it2 == entry);
+}
+
+TEST_CASE(test_returns_reference_to_self)
+{
+ directory_iterator it;
+ directory_iterator it2;
+ directory_iterator& ref = (it2 = it);
+ TEST_CHECK(&ref == &it2);
+}
+
+
+TEST_CASE(test_self_move)
+{
+ // Create two non-equal iterators that have exactly the same state.
+ directory_iterator it(StaticEnv::Dir);
+ directory_iterator it2(StaticEnv::Dir);
+ ++it; ++it2;
+ TEST_CHECK(it != it2);
+ TEST_CHECK(*it2 == *it);
+
+ it = std::move(it);
+ TEST_CHECK(*it2 == *it);
+}
+
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+// directory_iterator begin(directory_iterator iter) noexcept;
+// directory_iterator end(directory_iterator iter) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+#include <iostream>
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(directory_iterator_begin_end_tests)
+
+TEST_CASE(test_function_signatures)
+{
+ using D = directory_iterator;
+ directory_iterator d; ((void)d);
+
+ ASSERT_SAME_TYPE(decltype(begin(d)), directory_iterator);
+ ASSERT_NOEXCEPT(begin(std::move(d)));
+
+ ASSERT_SAME_TYPE(decltype(end(d)), directory_iterator);
+ ASSERT_NOEXCEPT(end(std::move(d)));
+}
+
+TEST_CASE(test_ranged_for_loop)
+{
+ const path testDir = StaticEnv::Dir;
+ std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList),
+ std::end( StaticEnv::DirIterationList));
+
+ std::error_code ec;
+ directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+
+ for (auto& elem : it) {
+ TEST_CHECK(dir_contents.erase(elem) == 1);
+ }
+ TEST_CHECK(dir_contents.empty());
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+// typedef ... value_type;
+// typedef ... difference_type;
+// typedef ... pointer;
+// typedef ... reference;
+// typedef ... iterator_category
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+ using D = directory_iterator;
+ ASSERT_SAME_TYPE(D::value_type, directory_entry);
+ ASSERT_SAME_TYPE(D::difference_type, std::ptrdiff_t);
+ ASSERT_SAME_TYPE(D::pointer, const directory_entry*);
+ ASSERT_SAME_TYPE(D::reference, const directory_entry&);
+ ASSERT_SAME_TYPE(D::iterator_category, std::input_iterator_tag);
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class file_status
+
+// explicit file_status() noexcept;
+// explicit file_status(file_type, perms prms = perms::unknown) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_convertible.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+ // Default ctor
+ {
+ static_assert(std::is_nothrow_default_constructible<file_status>::value,
+ "The default constructor must be noexcept");
+ static_assert(!test_convertible<file_status>(),
+ "The default constructor must be explicit");
+ const file_status f;
+ assert(f.type() == file_type::none);
+ assert(f.permissions() == perms::unknown);
+ }
+
+ // Unary ctor
+ {
+ static_assert(std::is_nothrow_constructible<file_status, file_type>::value,
+ "This constructor must be noexcept");
+ static_assert(!test_convertible<file_status, file_type>(),
+ "This constructor must be explicit");
+
+ const file_status f(file_type::not_found);
+ assert(f.type() == file_type::not_found);
+ assert(f.permissions() == perms::unknown);
+ }
+ // Binary ctor
+ {
+ static_assert(std::is_nothrow_constructible<file_status, file_type, perms>::value,
+ "This constructor must be noexcept");
+ static_assert(!test_convertible<file_status, file_type, perms>(),
+ "This constructor must b explicit");
+ const file_status f(file_type::regular, perms::owner_read);
+ assert(f.type() == file_type::regular);
+ assert(f.permissions() == perms::owner_read);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class file_status
+
+// void type(file_type) noexcept;
+// void permissions(perms) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+
+ file_status st;
+
+ // type test
+ {
+ static_assert(noexcept(st.type(file_type::regular)),
+ "operation must be noexcept");
+ static_assert(std::is_same<decltype(st.type(file_type::regular)), void>::value,
+ "operation must return void");
+ assert(st.type() != file_type::regular);
+ st.type(file_type::regular);
+ assert(st.type() == file_type::regular);
+ }
+ // permissions test
+ {
+ static_assert(noexcept(st.permissions(perms::owner_read)),
+ "operation must be noexcept");
+ static_assert(std::is_same<decltype(st.permissions(perms::owner_read)), void>::value,
+ "operation must return void");
+ assert(st.permissions() != perms::owner_read);
+ st.permissions(perms::owner_read);
+ assert(st.permissions() == perms::owner_read);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class file_status
+
+// file_type type() const noexcept;
+// perms permissions(p) const noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+
+ const file_status st(file_type::regular, perms::owner_read);
+
+ // type test
+ {
+ static_assert(noexcept(st.type()),
+ "operation must be noexcept");
+ static_assert(std::is_same<decltype(st.type()), file_type>::value,
+ "operation must return file_type");
+ assert(st.type() == file_type::regular);
+ }
+ // permissions test
+ {
+ static_assert(noexcept(st.permissions()),
+ "operation must be noexcept");
+ static_assert(std::is_same<decltype(st.permissions()), perms>::value,
+ "operation must return perms");
+ assert(st.permissions() == perms::owner_read);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class filesystem_error
+
+// filesystem_error(const string& what_arg, error_code ec);
+// filesystem_error(const string& what_arg, const path& p1, error_code ec);
+// filesystem_error(const string& what_arg, const path& p1, const path& p2, error_code ec);
+// const std::error_code& code() const;
+// const char* what() const noexcept;
+// const path& path1() const noexcept;
+// const path& path2() const noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+void test_constructors() {
+ using namespace fs;
+
+ // The string returned by "filesystem_error::what() must contain runtime_error::what()
+ const std::string what_arg = "Hello World";
+ const std::string what_contains = std::runtime_error(what_arg).what();
+ assert(what_contains.find(what_arg) != std::string::npos);
+ auto CheckWhat = [what_contains](filesystem_error const& e) {
+ std::string s = e.what();
+ assert(s.find(what_contains) != std::string::npos);
+ };
+
+ std::error_code ec = std::make_error_code(std::errc::file_exists);
+ const path p1("foo");
+ const path p2("bar");
+
+ // filesystem_error(const string& what_arg, error_code ec);
+ {
+ ASSERT_NOT_NOEXCEPT(filesystem_error(what_arg, ec));
+ filesystem_error e(what_arg, ec);
+ CheckWhat(e);
+ assert(e.code() == ec);
+ assert(e.path1().empty() && e.path2().empty());
+ }
+ // filesystem_error(const string& what_arg, const path&, error_code ec);
+ {
+ ASSERT_NOT_NOEXCEPT(filesystem_error(what_arg, p1, ec));
+ filesystem_error e(what_arg, p1, ec);
+ CheckWhat(e);
+ assert(e.code() == ec);
+ assert(e.path1() == p1);
+ assert(e.path2().empty());
+ }
+ // filesystem_error(const string& what_arg, const path&, const path&, error_code ec);
+ {
+ ASSERT_NOT_NOEXCEPT(filesystem_error(what_arg, p1, p2, ec));
+ filesystem_error e(what_arg, p1, p2, ec);
+ CheckWhat(e);
+ assert(e.code() == ec);
+ assert(e.path1() == p1);
+ assert(e.path2() == p2);
+ }
+}
+
+void test_signatures()
+{
+ using namespace fs;
+ const path p;
+ std::error_code ec;
+ const filesystem_error e("lala", ec);
+ // const path& path1() const noexcept;
+ {
+ ASSERT_SAME_TYPE(path const&, decltype(e.path1()));
+ ASSERT_NOEXCEPT(e.path1());
+ }
+ // const path& path2() const noexcept
+ {
+ ASSERT_SAME_TYPE(path const&, decltype(e.path2()));
+ ASSERT_NOEXCEPT(e.path2());
+ }
+ // const char* what() const noexcept
+ {
+ ASSERT_SAME_TYPE(const char*, decltype(e.what()));
+ ASSERT_NOEXCEPT(e.what());
+ }
+}
+
+int main() {
+ static_assert(std::is_base_of<std::system_error, fs::filesystem_error>::value, "");
+ test_constructors();
+ test_signatures();
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class Source>
+// path(const Source& source);
+// template <class InputIterator>
+// path(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <iterator>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+
+template <class It>
+std::reverse_iterator<It> mkRev(It it) {
+ return std::reverse_iterator<It>(it);
+}
+
+
+void checkIteratorConcepts() {
+ using namespace fs;
+ using It = path::iterator;
+ using Traits = std::iterator_traits<It>;
+ ASSERT_SAME_TYPE(Traits::iterator_category, std::bidirectional_iterator_tag);
+ ASSERT_SAME_TYPE(Traits::value_type, path);
+ ASSERT_SAME_TYPE(Traits::pointer, path const*);
+ ASSERT_SAME_TYPE(Traits::reference, path const&);
+ {
+ It it;
+ ASSERT_SAME_TYPE(It&, decltype(++it));
+ ASSERT_SAME_TYPE(It, decltype(it++));
+ ASSERT_SAME_TYPE(It&, decltype(--it));
+ ASSERT_SAME_TYPE(It, decltype(it--));
+ ASSERT_SAME_TYPE(Traits::reference, decltype(*it));
+ ASSERT_SAME_TYPE(Traits::pointer, decltype(it.operator->()));
+ ASSERT_SAME_TYPE(std::string const&, decltype(it->native()));
+ ASSERT_SAME_TYPE(bool, decltype(it == it));
+ ASSERT_SAME_TYPE(bool, decltype(it != it));
+ }
+ {
+ path const p;
+ ASSERT_SAME_TYPE(It, decltype(p.begin()));
+ ASSERT_SAME_TYPE(It, decltype(p.end()));
+ assert(p.begin() == p.end());
+ }
+}
+
+void checkBeginEndBasic() {
+ using namespace fs;
+ using It = path::iterator;
+ {
+ path const p;
+ ASSERT_SAME_TYPE(It, decltype(p.begin()));
+ ASSERT_SAME_TYPE(It, decltype(p.end()));
+ assert(p.begin() == p.end());
+ }
+ {
+ path const p("foo");
+ It default_constructed;
+ default_constructed = p.begin();
+ assert(default_constructed == p.begin());
+ assert(default_constructed != p.end());
+ default_constructed = p.end();
+ assert(default_constructed == p.end());
+ assert(default_constructed != p.begin());
+ }
+ {
+ path p("//root_name//first_dir////second_dir");
+ const path expect[] = {"//root_name", "/", "first_dir", "second_dir"};
+ assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect)));
+ assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()), mkRev(std::end(expect)), mkRev(std::begin(expect))));
+ }
+ {
+ path p("////foo/bar/baz///");
+ const path expect[] = {"/", "foo", "bar", "baz", "."};
+ assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect)));
+ assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()), mkRev(std::end(expect)), mkRev(std::begin(expect))));
+ }
+}
+
+int main() {
+ using namespace fs;
+ checkIteratorConcepts();
+ checkBeginEndBasic(); // See path.decompose.pass.cpp for more tests.
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,241 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path& operator/=(path const&)
+// template <class Source>
+// path& operator/=(Source const&);
+// template <class Source>
+// path& append(Source const&);
+// template <class InputIterator>
+// path& append(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct AppendOperatorTestcase {
+ MultiStringType lhs;
+ MultiStringType rhs;
+ MultiStringType expect;
+};
+
+#define S(Str) MKSTR(Str)
+const AppendOperatorTestcase Cases[] =
+ {
+ {S(""), S(""), S("")}
+ , {S("p1"), S("p2"), S("p1/p2")}
+ , {S("p1/"), S("p2"), S("p1/p2")}
+ , {S("p1"), S("/p2"), S("p1/p2")}
+ , {S("p1/"), S("/p2"), S("p1//p2")}
+ , {S("p1"), S("\\p2"), S("p1/\\p2")}
+ , {S("p1\\"), S("p2"), S("p1\\/p2")}
+ , {S("p1\\"), S("\\p2"), S("p1\\/\\p2")}
+ , {S("p1"), S(""), S("p1")}
+ , {S(""), S("p2"), S("p2")}
+ };
+
+
+const AppendOperatorTestcase LongLHSCases[] =
+ {
+ {S("p1"), S("p2"), S("p1/p2")}
+ , {S("p1/"), S("p2"), S("p1/p2")}
+ , {S("p1"), S("/p2"), S("p1/p2")}
+ };
+#undef S
+
+
+// The append operator may need to allocate a temporary buffer before a code_cvt
+// conversion. Test if this allocation occurs by:
+// 1. Create a path, `LHS`, and reserve enough space to append `RHS`.
+// This prevents `LHS` from allocating during the actual appending.
+// 2. Create a `Source` object `RHS`, which represents a "large" string.
+// (The string must not trigger the SSO)
+// 3. Append `RHS` to `LHS` and check for the expected allocation behavior.
+template <class CharT>
+void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
+{
+ using namespace fs;
+ using Ptr = CharT const*;
+ using Str = std::basic_string<CharT>;
+ using InputIter = input_iterator<Ptr>;
+
+ const Ptr L = TC.lhs;
+ Str RShort = (Ptr)TC.rhs;
+ Str EShort = (Ptr)TC.expect;
+ assert(RShort.size() >= 2);
+ CharT c = RShort.back();
+ RShort.append(100, c);
+ EShort.append(100, c);
+ const Ptr R = RShort.data();
+ const Str& E = EShort;
+ std::size_t ReserveSize = E.size() + 3;
+ // basic_string
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ Str RHS(R);
+ {
+ DisableAllocationGuard g;
+ LHS /= RHS;
+ }
+ assert(LHS == E);
+ }
+ // CharT*
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ Ptr RHS(R);
+ {
+ DisableAllocationGuard g;
+ LHS /= RHS;
+ }
+ assert(LHS == E);
+ }
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ Ptr RHS(R);
+ {
+ DisableAllocationGuard g;
+ LHS.append(RHS, StrEnd(RHS));
+ }
+ assert(LHS == E);
+ }
+ // input iterator - For non-native char types, appends needs to copy the
+ // iterator range into a contigious block of memory before it can perform the
+ // code_cvt conversions.
+ // For "char" no allocations will be performed because no conversion is
+ // required.
+ bool DisableAllocations = std::is_same<CharT, char>::value;
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ InputIter RHS(R);
+ {
+ RequireAllocationGuard g; // requires 1 or more allocations occur by default
+ if (DisableAllocations) g.requireExactly(0);
+ LHS /= RHS;
+ }
+ assert(LHS == E);
+ }
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ InputIter RHS(R);
+ InputIter REnd(StrEnd(R));
+ {
+ RequireAllocationGuard g;
+ if (DisableAllocations) g.requireExactly(0);
+ LHS.append(RHS, REnd);
+ }
+ assert(LHS == E);
+ }
+}
+
+template <class CharT>
+void doAppendSourceTest(AppendOperatorTestcase const& TC)
+{
+ using namespace fs;
+ using Ptr = CharT const*;
+ using Str = std::basic_string<CharT>;
+ using InputIter = input_iterator<Ptr>;
+ const Ptr L = TC.lhs;
+ const Ptr R = TC.rhs;
+ const Ptr E = TC.expect;
+ // basic_string
+ {
+ path LHS(L);
+ Str RHS(R);
+ path& Ref = (LHS /= RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ Str RHS(R);
+ path& Ref = LHS.append(RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ // Char*
+ {
+ path LHS(L);
+ Str RHS(R);
+ path& Ref = (LHS /= RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ Ptr RHS(R);
+ path& Ref = LHS.append(RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ Ptr RHS(R);
+ path& Ref = LHS.append(RHS, StrEnd(RHS));
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ // iterators
+ {
+ path LHS(L);
+ InputIter RHS(R);
+ path& Ref = (LHS /= RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L); InputIter RHS(R);
+ path& Ref = LHS.append(RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ InputIter RHS(R);
+ InputIter REnd(StrEnd(R));
+ path& Ref = LHS.append(RHS, REnd);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+}
+
+int main()
+{
+ using namespace fs;
+ for (auto const & TC : Cases) {
+ {
+ path LHS((const char*)TC.lhs);
+ path RHS((const char*)TC.rhs);
+ path& Ref = (LHS /= RHS);
+ assert(LHS == (const char*)TC.expect);
+ assert(&Ref == &LHS);
+ }
+ doAppendSourceTest<char> (TC);
+ doAppendSourceTest<wchar_t> (TC);
+ doAppendSourceTest<char16_t>(TC);
+ doAppendSourceTest<char32_t>(TC);
+ }
+ for (auto const & TC : LongLHSCases) {
+ doAppendSourceAllocTest<char>(TC);
+ doAppendSourceAllocTest<wchar_t>(TC);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path& operator=(path const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+ static_assert(std::is_copy_assignable<path>::value, "");
+ static_assert(!std::is_nothrow_copy_assignable<path>::value, "should not be noexcept");
+ const std::string s("foo");
+ const path p(s);
+ path p2;
+ path& pref = (p2 = p);
+ assert(p.native() == s);
+ assert(p2.native() == s);
+ assert(&pref == &p2);
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path& operator=(path&&) noexcept
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+ static_assert(std::is_nothrow_move_assignable<path>::value, "");
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ const std::string s("we really really really really really really really "
+ "really really long string so that we allocate");
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ path p(s);
+ {
+ DisableAllocationGuard g;
+ path p2;
+ path& pref = (p2 = std::move(p));
+ assert(p2.native() == s);
+ assert(p.native() != s); // Testing moved from state
+ assert(&pref == &p2);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,153 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class Source>
+// path& operator=(Source const&);
+// template <class Source>
+// path& assign(Source const&);
+// template <class InputIterator>
+// path& assign(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+#include <iostream>
+
+namespace fs = std::experimental::filesystem;
+
+template <class CharT>
+void RunTestCase(MultiStringType const& MS) {
+ using namespace fs;
+ const char* Expect = MS;
+ const CharT* TestPath = MS;
+ const CharT* TestPathEnd = StrEnd(TestPath);
+ const std::size_t Size = TestPathEnd - TestPath;
+ const std::size_t SSize = StrEnd(Expect) - Expect;
+ assert(Size == SSize);
+ //////////////////////////////////////////////////////////////////////////////
+ // basic_string<Char, Traits, Alloc>
+ {
+ const std::basic_string<CharT> S(TestPath);
+ path p; PathReserve(p, S.length() + 1);
+ {
+ // string provides a contigious iterator. No allocation needed.
+ DisableAllocationGuard g;
+ path& pref = (p = S);
+ assert(&pref == &p);
+ }
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ assert(p.string<CharT>() == S);
+ }
+ {
+ const std::basic_string<CharT> S(TestPath);
+ path p; PathReserve(p, S.length() + 1);
+ {
+ DisableAllocationGuard g;
+ path& pref = p.assign(S);
+ assert(&pref == &p);
+ }
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ assert(p.string<CharT>() == S);
+ }
+ //////////////////////////////////////////////////////////////////////////////
+ // Char* pointers
+ {
+ path p; PathReserve(p, Size + 1);
+ {
+ // char* pointers are contigious and can be used with code_cvt directly.
+ // no allocations needed.
+ DisableAllocationGuard g;
+ path& pref = (p = TestPath);
+ assert(&pref == &p);
+ }
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ {
+ path p; PathReserve(p, Size + 1);
+ {
+ DisableAllocationGuard g;
+ path& pref = p.assign(TestPath);
+ assert(&pref == &p);
+ }
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ {
+ path p; PathReserve(p, Size + 1);
+ {
+ DisableAllocationGuard g;
+ path& pref = p.assign(TestPath, TestPathEnd);
+ assert(&pref == &p);
+ }
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ //////////////////////////////////////////////////////////////////////////////
+ // Iterators
+ {
+ using It = input_iterator<const CharT*>;
+ path p; PathReserve(p, Size + 1);
+ It it(TestPath);
+ {
+ // Iterators cannot be used with code_cvt directly. This assignment
+ // may allocate if it's larger than a "short-string".
+ path& pref = (p = it);
+ assert(&pref == &p);
+ }
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ {
+ using It = input_iterator<const CharT*>;
+ path p; PathReserve(p, Size + 1);
+ It it(TestPath);
+ {
+ path& pref = p.assign(it);
+ assert(&pref == &p);
+ }
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ {
+ using It = input_iterator<const CharT*>;
+ path p; PathReserve(p, Size + 1);
+ It it(TestPath);
+ It e(TestPathEnd);
+ {
+ path& pref = p.assign(it, e);
+ assert(&pref == &p);
+ }
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+}
+
+int main() {
+ for (auto const& MS : PathList) {
+ RunTestCase<char>(MS);
+ RunTestCase<wchar_t>(MS);
+ RunTestCase<char16_t>(MS);
+ RunTestCase<char32_t>(MS);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// int compare(path const&) const noexcept;
+// int compare(string_type const&) const;
+// int compare(value_type const*) const;
+//
+// bool operator==(path const&, path const&) noexcept;
+// bool operator!=(path const&, path const&) noexcept;
+// bool operator< (path const&, path const&) noexcept;
+// bool operator<=(path const&, path const&) noexcept;
+// bool operator> (path const&, path const&) noexcept;
+// bool operator>=(path const&, path const&) noexcept;
+//
+// size_t hash_value(path const&) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct PathCompareTest {
+ const char* LHS;
+ const char* RHS;
+ int expect;
+};
+
+#define LONGA "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+#define LONGB "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
+#define LONGC "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
+#define LONGD "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
+const PathCompareTest CompareTestCases[] =
+{
+ {"", "", 0},
+ {"a", "", 1},
+ {"", "a", -1},
+ {"a/b/c", "a/b/c", 0},
+ {"b/a/c", "a/b/c", 1},
+ {"a/b/c", "b/a/c", -1},
+ {"a/b", "a/b/c", -1},
+ {"a/b/c", "a/b", 1},
+ {"a/b/", "a/b/.", 0},
+ {"a/b//////", "a/b/////.", 0},
+ {"a/.././b", "a///..//.////b", 0},
+ {"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators
+ {"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory
+ {"/foo/bar/", "/foo/bar", 1}, // trailing separator
+ {"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0},
+ { LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1}
+
+};
+#undef LONGA
+#undef LONGB
+#undef LONGC
+#undef LONGD
+
+int main()
+{
+ using namespace fs;
+ for (auto const & TC : CompareTestCases) {
+ const path p1(TC.LHS);
+ const path p2(TC.RHS);
+ const std::string R(TC.RHS);
+ const int E = TC.expect;
+ { // compare(...) functions
+ DisableAllocationGuard g; // none of these operations should allocate
+
+ // check runtime results
+ int ret1 = p1.compare(p2);
+ int ret2 = p1.compare(R);
+ int ret3 = p1.compare(TC.RHS);
+ assert(ret1 == ret2 && ret1 == ret3);
+ int normalized_ret = ret1 < 0 ? -1 : (ret1 > 0 ? 1 : 0);
+ assert(normalized_ret == E);
+
+ // check signatures
+ ASSERT_NOEXCEPT(p1.compare(p2));
+ }
+ { // comparison operators
+ DisableAllocationGuard g; // none of these operations should allocate
+
+ // Check runtime result
+ assert((p1 == p2) == (E == 0));
+ assert((p1 != p2) == (E != 0));
+ assert((p1 < p2) == (E < 0));
+ assert((p1 <= p2) == (E <= 0));
+ assert((p1 > p2) == (E > 0));
+ assert((p1 >= p2) == (E >= 0));
+
+ // Check signatures
+ ASSERT_NOEXCEPT(p1 == p2);
+ ASSERT_NOEXCEPT(p1 != p2);
+ ASSERT_NOEXCEPT(p1 < p2);
+ ASSERT_NOEXCEPT(p1 <= p2);
+ ASSERT_NOEXCEPT(p1 > p2);
+ ASSERT_NOEXCEPT(p1 >= p2);
+ }
+ { // check hash values
+ auto h1 = hash_value(p1);
+ auto h2 = hash_value(p2);
+ assert((h1 == h2) == (p1 == p2));
+ // check signature
+ ASSERT_SAME_TYPE(size_t, decltype(hash_value(p1)));
+ ASSERT_NOEXCEPT(hash_value(p1));
+ }
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,277 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path& operator+=(const path& x);
+// path& operator+=(const string_type& x); // Implemented as Source template
+// path& operator+=(const value_type* x); // Implemented as Source template
+// path& operator+=(value_type x);
+// template <class Source>
+// path& operator+=(const Source& x);
+// template <class EcharT>
+// path& operator+=(EcharT x);
+// template <class Source>
+// path& concat(const Source& x);
+// template <class InputIterator>
+// path& concat(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct ConcatOperatorTestcase {
+ MultiStringType lhs;
+ MultiStringType rhs;
+ MultiStringType expect;
+};
+
+#define LONGSTR "LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR"
+#define S(Str) MKSTR(Str)
+const ConcatOperatorTestcase Cases[] =
+ {
+ {S(""), S(""), S("")}
+ , {S("p1"), S("p2"), S("p1p2")}
+ , {S("p1/"), S("/p2"), S("p1//p2")}
+ , {S(""), S("\\foo/bar/baz"), S("\\foo/bar/baz")}
+ , {S("c:\\foo"), S(""), S("c:\\foo")}
+ , {S(LONGSTR), S("foo"), S(LONGSTR "foo")}
+ , {S("abcdefghijklmnopqrstuvwxyz/\\"), S("/\\123456789"), S("abcdefghijklmnopqrstuvwxyz/\\/\\123456789")}
+ };
+const ConcatOperatorTestcase LongLHSCases[] =
+ {
+ {S(""), S(LONGSTR), S(LONGSTR)}
+ , {S("p1/"), S(LONGSTR), S("p1/" LONGSTR)}
+ };
+const ConcatOperatorTestcase CharTestCases[] =
+ {
+ {S(""), S("P"), S("P")}
+ , {S("/fooba"), S("r"), S("/foobar")}
+ };
+#undef S
+#undef LONGSTR
+
+// The concat operator may need to allocate a temporary buffer before a code_cvt
+// conversion. Test if this allocation occurs by:
+// 1. Create a path, `LHS`, and reserve enough space to append `RHS`.
+// This prevents `LHS` from allocating during the actual appending.
+// 2. Create a `Source` object `RHS`, which represents a "large" string.
+// (The string must not trigger the SSO)
+// 3. Concat `RHS` to `LHS` and check for the expected allocation behavior.
+template <class CharT>
+void doConcatSourceAllocTest(ConcatOperatorTestcase const& TC)
+{
+ using namespace fs;
+ using Ptr = CharT const*;
+ using Str = std::basic_string<CharT>;
+ using InputIter = input_iterator<Ptr>;
+
+ const Ptr L = TC.lhs;
+ const Ptr R = TC.rhs;
+ const Ptr E = TC.expect;
+ std::size_t ReserveSize = StrLen(E) + 1;
+ // basic_string
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ Str RHS(R);
+ {
+ DisableAllocationGuard g;
+ LHS += RHS;
+ }
+ assert(LHS == E);
+ }
+ // CharT*
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ Ptr RHS(R);
+ {
+ DisableAllocationGuard g;
+ LHS += RHS;
+ }
+ assert(LHS == E);
+ }
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ Ptr RHS(R);
+ {
+ DisableAllocationGuard g;
+ LHS.concat(RHS, StrEnd(RHS));
+ }
+ assert(LHS == E);
+ }
+ // input iterator - For non-native char types, appends needs to copy the
+ // iterator range into a contigious block of memory before it can perform the
+ // code_cvt conversions.
+ // For "char" no allocations will be performed because no conversion is
+ // required.
+ bool DisableAllocations = std::is_same<CharT, char>::value;
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ InputIter RHS(R);
+ {
+ RequireAllocationGuard g; // requires 1 or more allocations occur by default
+ if (DisableAllocations) g.requireExactly(0);
+ LHS += RHS;
+ }
+ assert(LHS == E);
+ }
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ InputIter RHS(R);
+ InputIter REnd(StrEnd(R));
+ {
+ RequireAllocationGuard g;
+ if (DisableAllocations) g.requireExactly(0);
+ LHS.concat(RHS, REnd);
+ }
+ assert(LHS == E);
+ }
+}
+
+template <class CharT>
+void doConcatSourceTest(ConcatOperatorTestcase const& TC)
+{
+ using namespace fs;
+ using Ptr = CharT const*;
+ using Str = std::basic_string<CharT>;
+ using InputIter = input_iterator<Ptr>;
+ const Ptr L = TC.lhs;
+ const Ptr R = TC.rhs;
+ const Ptr E = TC.expect;
+ // basic_string
+ {
+ path LHS(L);
+ Str RHS(R);
+ path& Ref = (LHS += RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ Str RHS(R);
+ path& Ref = LHS.concat(RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ // Char*
+ {
+ path LHS(L);
+ Str RHS(R);
+ path& Ref = (LHS += RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ Ptr RHS(R);
+ path& Ref = LHS.concat(RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ Ptr RHS(R);
+ path& Ref = LHS.concat(RHS, StrEnd(RHS));
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ // iterators
+ {
+ path LHS(L);
+ InputIter RHS(R);
+ path& Ref = (LHS += RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L); InputIter RHS(R);
+ path& Ref = LHS.concat(RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ InputIter RHS(R);
+ InputIter REnd(StrEnd(R));
+ path& Ref = LHS.concat(RHS, REnd);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+}
+
+template <class CharT>
+void doConcatECharTest(ConcatOperatorTestcase const& TC)
+{
+ using namespace fs;
+ using Ptr = CharT const*;
+ const Ptr RStr = TC.rhs;
+ assert(StrLen(RStr) == 1);
+ const Ptr L = TC.lhs;
+ const CharT R = RStr[0];
+ const Ptr E = TC.expect;
+ {
+ path LHS(L);
+ path& Ref = (LHS += R);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+}
+
+int main()
+{
+ using namespace fs;
+ for (auto const & TC : Cases) {
+ {
+ path LHS((const char*)TC.lhs);
+ path RHS((const char*)TC.rhs);
+ path& Ref = (LHS += RHS);
+ assert(LHS == (const char*)TC.expect);
+ assert(&Ref == &LHS);
+ }
+ doConcatSourceTest<char> (TC);
+ doConcatSourceTest<wchar_t> (TC);
+ doConcatSourceTest<char16_t>(TC);
+ doConcatSourceTest<char32_t>(TC);
+ }
+ for (auto const & TC : LongLHSCases) {
+ // Do path test
+ {
+ path LHS((const char*)TC.lhs);
+ path RHS((const char*)TC.rhs);
+ const char* E = TC.expect;
+ PathReserve(LHS, StrLen(E) + 5);
+ {
+ DisableAllocationGuard g;
+ path& Ref = (LHS += RHS);
+ assert(&Ref == &LHS);
+ }
+ assert(LHS == E);
+ }
+ doConcatSourceAllocTest<char>(TC);
+ doConcatSourceAllocTest<wchar_t>(TC);
+ }
+ for (auto const& TC : CharTestCases) {
+ doConcatECharTest<char>(TC);
+ doConcatECharTest<wchar_t>(TC);
+ doConcatECharTest<char16_t>(TC);
+ doConcatECharTest<char32_t>(TC);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path(path const&)
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+ static_assert(std::is_copy_constructible<path>::value, "");
+ static_assert(!std::is_nothrow_copy_constructible<path>::value, "should not be noexcept");
+ const std::string s("foo");
+ const path p(s);
+ path p2(p);
+ assert(p.native() == s);
+ assert(p2.native() == s);
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path() noexcept
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+ static_assert(std::is_nothrow_default_constructible<path>::value, "");
+ const path p;
+ assert(p.empty());
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path(path&&) noexcept
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+ static_assert(std::is_nothrow_move_constructible<path>::value, "");
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ const std::string s("we really really really really really really really "
+ "really really long string so that we allocate");
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ path p(s);
+ {
+ DisableAllocationGuard g;
+ path p2(std::move(p));
+ assert(p2.native() == s);
+ assert(p.native() != s); // Testing moved from state
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class Source>
+// path(const Source& source);
+// template <class InputIterator>
+// path(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+template <class CharT>
+void RunTestCase(MultiStringType const& MS) {
+ using namespace fs;
+ const char* Expect = MS;
+ const CharT* TestPath = MS;
+ const CharT* TestPathEnd = StrEnd(TestPath);
+ const std::size_t Size = TestPathEnd - TestPath;
+ const std::size_t SSize = StrEnd(Expect) - Expect;
+ assert(Size == SSize);
+ // StringTypes
+ {
+ const std::basic_string<CharT> S(TestPath);
+ path p(S);
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ assert(p.string<CharT>() == S);
+ }
+ // Char* pointers
+ {
+ path p(TestPath);
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ {
+ path p(TestPath, TestPathEnd);
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ // Iterators
+ {
+ using It = input_iterator<const CharT*>;
+ path p(It{TestPath});
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ {
+ using It = input_iterator<const CharT*>;
+ path p(It{TestPath}, It{TestPathEnd});
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+}
+
+int main() {
+ for (auto const& MS : PathList) {
+ RunTestCase<char>(MS);
+ RunTestCase<wchar_t>(MS);
+ RunTestCase<char16_t>(MS);
+ RunTestCase<char32_t>(MS);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,198 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// 8.4.9 path decomposition [path.decompose]
+//------------------------------------------
+// path root_name() const;
+// path root_directory() const;
+// path root_path() const;
+// path relative_path() const;
+// path parent_path() const;
+// path filename() const;
+// path stem() const;
+// path extension() const;
+//-------------------------------
+// 8.4.10 path query [path.query]
+//-------------------------------
+// bool empty() const noexcept;
+// bool has_root_path() const;
+// bool has_root_name() const;
+// bool has_root_directory() const;
+// bool has_relative_path() const;
+// bool has_parent_path() const;
+// bool has_filename() const;
+// bool has_stem() const;
+// bool has_extension() const;
+// bool is_absolute() const;
+// bool is_relative() const;
+//-------------------------------
+// 8.5 path iterators [path.itr]
+//-------------------------------
+// iterator begin() const;
+// iterator end() const;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+template <class It>
+std::reverse_iterator<It> mkRev(It it) {
+ return std::reverse_iterator<It>(it);
+}
+
+
+namespace fs = std::experimental::filesystem;
+struct PathDecomposeTestcase
+{
+ std::string raw;
+ std::vector<std::string> elements;
+ std::string root_path;
+ std::string root_name;
+ std::string root_directory;
+ std::string relative_path;
+ std::string parent_path;
+ std::string filename;
+};
+
+const PathDecomposeTestcase PathTestCases[] =
+ {
+ {"", {}, "", "", "", "", "", ""}
+ , {".", {"."}, "", "", "", ".", "", "."}
+ , {"..", {".."}, "", "", "", "..", "", ".."}
+ , {"foo", {"foo"}, "", "", "", "foo", "", "foo"}
+ , {"/", {"/"}, "/", "", "/", "", "", "/"}
+ , {"/foo", {"/", "foo"}, "/", "", "/", "foo", "/", "foo"}
+ , {"foo/", {"foo", "."}, "", "", "", "foo/", "foo", "."}
+ , {"/foo/", {"/", "foo", "."}, "/", "", "/", "foo/", "/foo", "."}
+ , {"foo/bar", {"foo","bar"}, "", "", "", "foo/bar", "foo", "bar"}
+ , {"/foo//bar", {"/","foo","bar"}, "/", "", "/", "foo/bar", "/foo", "bar"}
+ , {"//net", {"//net"}, "//net", "//net", "", "", "", "//net"}
+ , {"//net/foo", {"//net", "/", "foo"}, "//net/", "//net", "/", "foo", "//net/", "foo"}
+ , {"///foo///", {"/", "foo", "."}, "/", "", "/", "foo///", "///foo", "."}
+ , {"///foo///bar", {"/", "foo", "bar"}, "/", "", "/", "foo///bar", "///foo", "bar"}
+ , {"/.", {"/", "."}, "/", "", "/", ".", "/", "."}
+ , {"./", {".", "."}, "", "", "", "./", ".", "."}
+ , {"/..", {"/", ".."}, "/", "", "/", "..", "/", ".."}
+ , {"../", {"..", "."}, "", "", "", "../", "..", "."}
+ , {"foo/.", {"foo", "."}, "", "", "", "foo/.", "foo", "."}
+ , {"foo/..", {"foo", ".."}, "", "", "", "foo/..", "foo", ".."}
+ , {"foo/./", {"foo", ".", "."}, "", "", "", "foo/./", "foo/.", "."}
+ , {"foo/./bar", {"foo", ".", "bar"}, "", "", "", "foo/./bar", "foo/.", "bar"}
+ , {"foo/../", {"foo", "..", "."}, "", "", "", "foo/../", "foo/..", "."}
+ , {"foo/../bar", {"foo", "..", "bar"}, "", "", "", "foo/../bar", "foo/..", "bar"}
+ , {"c:", {"c:"}, "", "", "", "c:", "", "c:"}
+ , {"c:/", {"c:", "."}, "", "", "", "c:/", "c:", "."}
+ , {"c:foo", {"c:foo"}, "", "", "", "c:foo", "", "c:foo"}
+ , {"c:/foo", {"c:", "foo"}, "", "", "", "c:/foo", "c:", "foo"}
+ , {"c:foo/", {"c:foo", "."}, "", "", "", "c:foo/", "c:foo", "."}
+ , {"c:/foo/", {"c:", "foo", "."}, "", "", "", "c:/foo/", "c:/foo", "."}
+ , {"c:/foo/bar", {"c:", "foo", "bar"}, "", "", "", "c:/foo/bar", "c:/foo", "bar"}
+ , {"prn:", {"prn:"}, "", "", "", "prn:", "", "prn:"}
+ , {"c:\\", {"c:\\"}, "", "", "", "c:\\", "", "c:\\"}
+ , {"c:\\foo", {"c:\\foo"}, "", "", "", "c:\\foo", "", "c:\\foo"}
+ , {"c:foo\\", {"c:foo\\"}, "", "", "", "c:foo\\", "", "c:foo\\"}
+ , {"c:\\foo\\", {"c:\\foo\\"}, "", "", "", "c:\\foo\\", "", "c:\\foo\\"}
+ , {"c:\\foo/", {"c:\\foo", "."}, "", "", "", "c:\\foo/", "c:\\foo", "."}
+ , {"c:/foo\\bar", {"c:", "foo\\bar"}, "", "", "", "c:/foo\\bar", "c:", "foo\\bar"}
+ , {"//", {"//"}, "//", "//", "", "", "", "//"}
+ };
+
+void decompPathTest()
+{
+ using namespace fs;
+ for (auto const & TC : PathTestCases) {
+ path p(TC.raw);
+ assert(p == TC.raw);
+
+ assert(p.root_path() == TC.root_path);
+ assert(p.has_root_path() != TC.root_path.empty());
+
+ assert(p.root_name() == TC.root_name);
+ assert(p.has_root_name() != TC.root_name.empty());
+
+ assert(p.root_directory() == TC.root_directory);
+ assert(p.has_root_directory() != TC.root_directory.empty());
+
+ assert(p.relative_path() == TC.relative_path);
+ assert(p.has_relative_path() != TC.relative_path.empty());
+
+ assert(p.parent_path() == TC.parent_path);
+ assert(p.has_parent_path() != TC.parent_path.empty());
+
+ assert(p.filename() == TC.filename);
+ assert(p.has_filename() != TC.filename.empty());
+
+ assert(p.is_absolute() == p.has_root_directory());
+ assert(p.is_relative() != p.is_absolute());
+
+ assert(checkCollectionsEqual(p.begin(), p.end(),
+ TC.elements.begin(), TC.elements.end()));
+ // check backwards
+ assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()),
+ TC.elements.rbegin(), TC.elements.rend()));
+ }
+}
+
+
+struct FilenameDecompTestcase
+{
+ std::string raw;
+ std::string filename;
+ std::string stem;
+ std::string extension;
+};
+
+const FilenameDecompTestcase FilenameTestCases[] =
+{
+ {"", "", "", ""}
+ , {".", ".", ".", ""}
+ , {"..", "..", "..", ""}
+ , {"/", "/", "/", ""}
+ , {"foo", "foo", "foo", ""}
+ , {"/foo/bar.txt", "bar.txt", "bar", ".txt"}
+ , {"foo..txt", "foo..txt", "foo.", ".txt"}
+};
+
+
+void decompFilenameTest()
+{
+ using namespace fs;
+ for (auto const & TC : FilenameTestCases) {
+ path p(TC.raw);
+ assert(p == TC.raw);
+
+ assert(p.filename() == TC.filename);
+ assert(p.has_filename() != TC.filename.empty());
+
+ assert(p.stem() == TC.stem);
+ assert(p.has_stem() != TC.stem.empty());
+
+ assert(p.extension() == TC.extension);
+ assert(p.has_extension() != TC.extension.empty());
+ }
+}
+
+int main()
+{
+ decompPathTest();
+ decompFilenameTest();
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class ECharT, class Traits = char_traits<ECharT>,
+// class Allocator = allocator<ECharT>>
+// basic_string<ECharT, Traits, Allocator>
+// generic_string(const Allocator& a = Allocator()) const;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+
+// generic_string<C, T, A> forwards to string<C, T, A>. Tests for
+// string<C, T, A>() are in "path.native.op/string_alloc.pass.cpp".
+// generic_string is minimally tested here.
+int main()
+{
+ using namespace fs;
+ using CharT = wchar_t;
+ using Traits = std::char_traits<CharT>;
+ using Alloc = malloc_allocator<CharT>;
+ using Str = std::basic_string<CharT, Traits, Alloc>;
+ const wchar_t* expect = longString;
+ const path p((const char*)longString);
+ {
+ DisableAllocationGuard g;
+ Alloc a;
+ Alloc::disable_default_constructor = true;
+ Str s = p.generic_string<wchar_t, Traits, Alloc>(a);
+ assert(s == expect);
+ assert(Alloc::alloc_count > 0);
+ assert(Alloc::outstanding_alloc() == 1);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// std::string generic_string() const;
+// std::wstring generic_wstring() const;
+// std::u8string generic_u8string() const;
+// std::u16string generic_u16string() const;
+// std::u32string generic_u32string() const;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+int main()
+{
+ using namespace fs;
+ auto const& MS = longString;
+ const char* value = longString;
+ const path p(value);
+ {
+ std::string s = p.generic_string();
+ assert(s == value);
+ }
+ {
+ std::string s = p.generic_u8string();
+ assert(s == (const char*)MS);
+ }
+ {
+ std::wstring s = p.generic_wstring();
+ assert(s == (const wchar_t*)MS);
+ }
+ {
+ std::u16string s = p.generic_u16string();
+ assert(s == (const char16_t*)MS);
+ }
+ {
+ std::u32string s = p.generic_u32string();
+ assert(s == (const char32_t*)MS);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// void clear() noexcept
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+ const path p("/foo/bar/baz");
+ {
+ path p;
+ ASSERT_NOEXCEPT(p.clear());
+ ASSERT_SAME_TYPE(void, decltype(p.clear()));
+ p.clear();
+ assert(p.empty());
+ }
+ {
+ path p2(p);
+ assert(p == p2);
+ p2.clear();
+ assert(p2.empty());
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path& make_preferred()
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct MakePreferredTestcase {
+ const char* value;
+};
+
+const MakePreferredTestcase TestCases[] =
+ {
+ {""}
+ , {"hello_world"}
+ , {"/"}
+ , {"/foo/bar/baz/"}
+ , {"\\"}
+ , {"\\foo\\bar\\baz\\"}
+ , {"\\foo\\/bar\\/baz\\"}
+ };
+
+int main()
+{
+ // This operation is an identity operation on linux.
+ using namespace fs;
+ for (auto const & TC : TestCases) {
+ path p(TC.value);
+ assert(p == TC.value);
+ path& Ref = (p.make_preferred());
+ assert(p.native() == TC.value);
+ assert(&Ref == &p);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path& remove_filename()
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct RemoveFilenameTestcase {
+ const char* value;
+ const char* expect;
+};
+
+const RemoveFilenameTestcase TestCases[] =
+ {
+ {"", ""}
+ , {"/", ""}
+ , {"\\", ""}
+ , {".", ""}
+ , {"..", ""}
+ , {"/foo", "/"}
+ , {"/foo/", "/foo"}
+ , {"/foo/.", "/foo"}
+ , {"/foo/..", "/foo"}
+ , {"/foo/////", "/foo"}
+ , {"/foo\\\\", "/"}
+ , {"/foo//\\/", "/foo//\\"}
+ , {"file.txt", ""}
+ , {"bar/../baz/./file.txt", "bar/../baz/."}
+ };
+
+int main()
+{
+ using namespace fs;
+ for (auto const & TC : TestCases) {
+ path const p_orig(TC.value);
+ path p(p_orig);
+ assert(p == TC.value);
+ path& Ref = (p.remove_filename());
+ assert(p == TC.expect);
+ assert(&Ref == &p);
+ {
+ const path parentp = p_orig.parent_path();
+ if (parentp == p_orig.root_name()) {
+
+ assert(p.empty());
+ } else {
+ assert(p == parentp);
+ }
+ }
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// path& replace_extension(path const& p = path())
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct ReplaceExtensionTestcase {
+ const char* value;
+ const char* expect;
+ const char* extension;
+};
+
+const ReplaceExtensionTestcase TestCases[] =
+ {
+ {"", "", ""}
+ , {"foo.cpp", "foo", ""}
+ , {"foo.cpp", "foo.", "."}
+ , {"foo..cpp", "foo..txt", "txt"}
+ , {"", ".txt", "txt"}
+ , {"", ".txt", ".txt"}
+ , {"/foo", "/foo.txt", ".txt"}
+ , {"/foo", "/foo.txt", "txt"}
+ , {"/foo.cpp", "/foo.txt", ".txt"}
+ , {"/foo.cpp", "/foo.txt", "txt"}
+ };
+const ReplaceExtensionTestcase NoArgCases[] =
+ {
+ {"", ""}
+ , {"foo", "foo"}
+ , {"foo.cpp", "foo"}
+ , {"foo..cpp", "foo."}
+};
+
+int main()
+{
+ using namespace fs;
+ for (auto const & TC : TestCases) {
+ path p(TC.value);
+ assert(p == TC.value);
+ path& Ref = (p.replace_extension(TC.extension));
+ assert(p == TC.expect);
+ assert(&Ref == &p);
+ }
+ for (auto const& TC : NoArgCases) {
+ path p(TC.value);
+ assert(p == TC.value);
+ path& Ref = (p.replace_extension());
+ assert(p == TC.expect);
+ assert(&Ref == &p);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp Fri Jun 17 14:46:40 2016
@@ -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
+
+// <experimental/filesystem>
+
+// class path
+
+// path& replace_filename()
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct ReplaceFilenameTestcase {
+ const char* value;
+ const char* expect;
+ const char* filename;
+};
+
+const ReplaceFilenameTestcase TestCases[] =
+ {
+ {"/foo", "/bar", "bar"}
+ , {"/foo", "/", ""}
+ , {"foo", "bar", "bar"}
+ , {"/", "bar", "bar"}
+ , {"\\", "bar", "bar"}
+ , {"///", "bar", "bar"}
+ , {"\\\\", "bar", "bar"}
+ , {"\\/\\", "\\/bar", "bar"}
+ , {".", "bar", "bar"}
+ , {"..", "bar", "bar"}
+ , {"/foo\\baz/bong/", "/foo\\baz/bong/bar", "bar"}
+ , {"/foo\\baz/bong", "/foo\\baz/bar", "bar"}
+ };
+
+int main()
+{
+ using namespace fs;
+ for (auto const & TC : TestCases) {
+ path p(TC.value);
+ assert(p == TC.value);
+ path& Ref = (p.replace_filename(TC.filename));
+ assert(p == TC.expect);
+ assert(&Ref == &p);
+ // Tests Effects "as-if": remove_filename() append(filename)
+ {
+ path p2(TC.value);
+ path replace(TC.filename);
+ p2.remove_filename();
+ p2 /= replace;
+ assert(p2 == p);
+ }
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// void swap(path& rhs) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct SwapTestcase {
+ const char* value1;
+ const char* value2;
+};
+
+#define LONG_STR1 "_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG"
+#define LONG_STR2 "_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2"
+const SwapTestcase TestCases[] =
+ {
+ {"", ""}
+ , {"shortstr", LONG_STR1}
+ , {LONG_STR1, "shortstr"}
+ , {LONG_STR1, LONG_STR2}
+ };
+#undef LONG_STR1
+#undef LONG_STR2
+
+int main()
+{
+ using namespace fs;
+ {
+ path p;
+ ASSERT_NOEXCEPT(p.swap(p));
+ ASSERT_SAME_TYPE(void, decltype(p.swap(p)));
+ }
+ for (auto const & TC : TestCases) {
+ path p1(TC.value1);
+ path p2(TC.value2);
+ {
+ DisableAllocationGuard g;
+ p1.swap(p2);
+ }
+ assert(p1 == TC.value2);
+ assert(p2 == TC.value1);
+ {
+ DisableAllocationGuard g;
+ p1.swap(p2);
+ }
+ assert(p1 == TC.value1);
+ assert(p2 == TC.value2);
+ }
+ // self-swap
+ {
+ const char* Val = "aoeuaoeuaoeuaoeuaoeuaoeuaoeuaoeuaoeu";
+ path p1(Val);
+ assert(p1 == Val);
+ {
+ DisableAllocationGuard g;
+ p1.swap(p1);
+ }
+ assert(p1 == Val);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,43 @@
+
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// const value_type* c_str() const noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main()
+{
+ using namespace fs;
+ const char* const value = "hello world";
+ const std::string str_value = value;
+ path p(value);
+ { // Check signature
+ ASSERT_SAME_TYPE(path::value_type const*, decltype(p.c_str()));
+ ASSERT_NOEXCEPT(p.c_str());
+ }
+ {
+ path p(value);
+ assert(p.c_str() == str_value);
+ assert(p.native().c_str() == p.c_str());
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// std::string string() const;
+// std::wstring wstring() const;
+// std::u8string u8string() const;
+// std::u16string u16string() const;
+// std::u32string u32string() const;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+int main()
+{
+ using namespace fs;
+ auto const& MS = longString;
+ const char* value = longString;
+ const path p(value);
+ {
+ std::string s = p.string();
+ assert(s == value);
+ }
+ {
+ std::string s = p.u8string();
+ assert(s == (const char*)MS);
+ }
+ {
+ std::wstring s = p.wstring();
+ assert(s == (const wchar_t*)MS);
+ }
+ {
+ std::u16string s = p.u16string();
+ assert(s == (const char16_t*)MS);
+ }
+ {
+ std::u32string s = p.u32string();
+ assert(s == (const char32_t*)MS);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// const string_type& native() const noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main()
+{
+ using namespace fs;
+ const char* const value = "hello world";
+ path p(value);
+ { // Check signature
+ ASSERT_SAME_TYPE(path::string_type const&, decltype(p.native()));
+ ASSERT_NOEXCEPT(p.native());
+ }
+ { // native() is tested elsewhere
+ path p(value);
+ assert(p.native() == value);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,47 @@
+
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// operator string_type() const;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main()
+{
+ using namespace fs;
+ using string_type = path::string_type;
+ const char* const value = "hello world";
+ path p(value);
+ { // Check signature
+ static_assert(std::is_convertible<path, string_type>::value, "");
+ static_assert(std::is_constructible<string_type, path>::value, "");
+ ASSERT_SAME_TYPE(string_type, decltype(p.operator string_type()));
+ ASSERT_NOT_NOEXCEPT(p.operator string_type());
+ }
+ {
+ path p(value);
+ assert(p.native() == value);
+ string_type s = p;
+ assert(s == value);
+ assert(p == value);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class ECharT, class Traits = char_traits<ECharT>,
+// class Allocator = allocator<ECharT>>
+// basic_string<ECharT, Traits, Allocator>
+// string(const Allocator& a = Allocator()) const;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+MultiStringType shortString = MKSTR("abc");
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+template <class CharT>
+void doShortStringTest(MultiStringType const& MS) {
+ using namespace fs;
+ using Ptr = CharT const*;
+ using Str = std::basic_string<CharT>;
+ using Alloc = std::allocator<CharT>;
+ Ptr value = MS;
+ const path p((const char*)MS);
+ {
+ DisableAllocationGuard g; // should not allocate
+ Str s = p.string<CharT>();
+ assert(s == value);
+ Str s2 = p.string<CharT>(Alloc{});
+ assert(s2 == value);
+ }
+}
+
+template <class CharT>
+void doLongStringTest(MultiStringType const& MS) {
+ using namespace fs;
+ using Ptr = CharT const*;
+ using Str = std::basic_string<CharT>;
+ Ptr value = MS;
+ const path p((const char*)MS);
+ { // Default allocator
+ using Alloc = std::allocator<CharT>;
+ RequireAllocationGuard g; // should not allocate because
+ Str s = p.string<CharT>();
+ assert(s == value);
+ Str s2 = p.string<CharT>(Alloc{});
+ assert(s2 == value);
+ }
+ using MAlloc = malloc_allocator<CharT>;
+ MAlloc::reset();
+ { // Other allocator - default construct
+ using Traits = std::char_traits<CharT>;
+ using AStr = std::basic_string<CharT, Traits, MAlloc>;
+ DisableAllocationGuard g;
+ AStr s = p.string<CharT, Traits, MAlloc>();
+ assert(s == value);
+ assert(MAlloc::alloc_count > 0);
+ assert(MAlloc::outstanding_alloc() == 1);
+ }
+ MAlloc::reset();
+ { // Other allocator - provided copy
+ using Traits = std::char_traits<CharT>;
+ using AStr = std::basic_string<CharT, Traits, MAlloc>;
+ DisableAllocationGuard g;
+ MAlloc a;
+ // don't allow another allocator to be default constructed.
+ MAlloc::disable_default_constructor = true;
+ AStr s = p.string<CharT, Traits, MAlloc>(a);
+ assert(s == value);
+ assert(MAlloc::alloc_count > 0);
+ assert(MAlloc::outstanding_alloc() == 1);
+ }
+ MAlloc::reset();
+ /////////////////////////////////////////////////////////////////////////////
+}
+
+int main()
+{
+ using namespace fs;
+ {
+ auto const& S = shortString;
+ doShortStringTest<char>(S);
+ doShortStringTest<wchar_t>(S);
+ doShortStringTest<char16_t>(S);
+ doShortStringTest<char32_t>(S);
+ }
+ {
+ auto const& S = longString;
+ doLongStringTest<char>(S);
+ doLongStringTest<wchar_t>(S);
+ doLongStringTest<char16_t>(S);
+ doLongStringTest<char32_t>(S);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+//-------------------------------
+// 8.4.10 path query [path.query]
+//-------------------------------
+// bool empty() const noexcept;
+// bool has_root_path() const;
+// bool has_root_name() const;
+// bool has_root_directory() const;
+// bool has_relative_path() const;
+// bool has_parent_path() const;
+// bool has_filename() const;
+// bool has_stem() const;
+// bool has_extension() const;
+// bool is_absolute() const;
+// bool is_relative() const;
+
+// tested in path.decompose
+int main() {}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// path operator/(path const&, path const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+// This is mainly tested via the member append functions.
+int main()
+{
+ using namespace fs;
+ path p1("abc");
+ path p2("def");
+ path p3 = p1 / p2;
+ assert(p3 == "abc/def");
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,14 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// The comparison operators are tested as part of [path.compare]
+// in class.path/path.members/path.compare.pass.cpp
+int main() {}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,14 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// The "hash_value" function is tested as part of [path.compare]
+// in class.path/path.members/path.compare.pass.cpp
+int main() {}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp Fri Jun 17 14:46:40 2016
@@ -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
+
+// <experimental/filesystem>
+
+// template <class Source>
+// path u8path(Source const&);
+// template <class InputIter>
+// path u8path(InputIter, InputIter);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main()
+{
+ using namespace fs;
+ const char* In1 = "abcd/efg";
+ const std::string In2(In1);
+ const auto In3 = In2.begin();
+ const auto In3End = In2.end();
+ {
+ path p = fs::u8path(In1);
+ assert(p == In1);
+ }
+ {
+ path p = fs::u8path(In2);
+ assert(p == In1);
+ }
+ {
+ path p = fs::u8path(In3);
+ assert(p == In1);
+ }
+ {
+ path p = fs::u8path(In3, In3End);
+ assert(p == In1);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const path& p);
+//
+// template <class charT, class traits>
+// basic_istream<charT, traits>&
+// operator>>(basic_istream<charT, traits>& is, path& p)
+//
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <sstream>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789");
+MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\"");
+
+template <class CharT>
+void doIOTest() {
+ using namespace fs;
+ using Ptr = const CharT*;
+ using StrStream = std::basic_stringstream<CharT>;
+ const char* const InCStr = InStr;
+ const Ptr E = OutStr;
+ const path p((const char*)InStr);
+ StrStream ss;
+ { // test output
+ auto& ret = (ss << p);
+ assert(ss.str() == E);
+ assert(&ret == &ss);
+ }
+ { // test input
+ path p_in;
+ auto& ret = ss >> p_in;
+ assert(p_in.native() == (const char*)InStr);
+ assert(&ret == &ss);
+ }
+}
+
+
+int main() {
+ doIOTest<char>();
+ doIOTest<wchar_t>();
+ //doIOTest<char16_t>();
+ //doIOTest<char32_t>();
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp Fri Jun 17 14:46:40 2016
@@ -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
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const path& p);
+//
+// template <class charT, class traits>
+// basic_istream<charT, traits>&
+// operator>>(basic_istream<charT, traits>& is, path& p)
+//
+
+// TODO(EricWF) This test fails because "std::quoted" fails to compile
+// for char16_t and char32_t types. Combine with path.io.pass.cpp when this
+// passes.
+// XFAIL: *
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <sstream>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789");
+MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\"");
+
+template <class CharT>
+void doIOTest() {
+ using namespace fs;
+ using Ptr = const CharT*;
+ using StrStream = std::basic_stringstream<CharT>;
+ const char* const InCStr = InStr;
+ const Ptr E = OutStr;
+ const path p((const char*)InStr);
+ StrStream ss;
+ { // test output
+ auto& ret = (ss << p);
+ assert(ss.str() == E);
+ assert(&ret == &ss);
+ }
+ { // test input
+ path p_in;
+ auto& ret = ss >> p_in;
+ assert(p_in.native() == (const char*)InStr);
+ assert(&ret == &ss);
+ }
+}
+
+
+int main() {
+ doIOTest<char16_t>();
+ doIOTest<char32_t>();
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// void swap(path& lhs, path& rhs) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+// NOTE: this is tested in path.members/path.modifiers via the member swap.
+int main()
+{
+ using namespace fs;
+ const char* value1 = "foo/bar/baz";
+ const char* value2 = "_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG";
+ path p1(value1);
+ path p2(value2);
+ {
+ using namespace std; using namespace fs;
+ ASSERT_NOEXCEPT(swap(p1, p2));
+ ASSERT_SAME_TYPE(void, decltype(swap(p1, p2)));
+ }
+ {
+ DisableAllocationGuard g;
+ using namespace std;
+ using namespace fs;
+ swap(p1, p2);
+ assert(p1.native() == value2);
+ assert(p2.native() == value1);
+ swap(p1, p2);
+ assert(p1.native() == value1);
+ assert(p2.native() == value2);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.path/synop.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/synop.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.path/synop.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.path/synop.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class path
+
+// typedef ... value_type;
+// typedef basic_string<value_type> string_type;
+// static constexpr value_type preferred_separator = ...;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+ using namespace fs;
+ ASSERT_SAME_TYPE(path::value_type, char);
+ ASSERT_SAME_TYPE(path::string_type, std::basic_string<path::value_type>);
+ {
+ ASSERT_SAME_TYPE(const path::value_type, decltype(path::preferred_separator));
+ static_assert(path::preferred_separator == '/', "");
+ // Make preferred_separator ODR used by taking it's address.
+ const char* dummy = &path::preferred_separator;
+ ((void)dummy);
+ }
+}
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_recursive_directory_iterator(recursive_recursive_directory_iterator const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_copy_construct_tests)
+
+TEST_CASE(test_constructor_signature)
+{
+ using D = recursive_directory_iterator;
+ static_assert(std::is_copy_constructible<D>::value, "");
+ //static_assert(!std::is_nothrow_copy_constructible<D>::value, "");
+}
+
+TEST_CASE(test_copy_end_iterator)
+{
+ const recursive_directory_iterator endIt;
+ recursive_directory_iterator it(endIt);
+ TEST_CHECK(it == endIt);
+}
+
+TEST_CASE(test_copy_valid_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+ const recursive_directory_iterator endIt{};
+
+ // build 'it' up with "interesting" non-default state so we can test
+ // that it gets copied. We want to get 'it' into a state such that:
+ // it.options() != directory_options::none
+ // it.depth() != 0
+ // it.recursion_pending() != true
+ const directory_options opts = directory_options::skip_permission_denied;
+ recursive_directory_iterator it(testDir, opts);
+ TEST_REQUIRE(it != endIt);
+ while (it.depth() == 0) {
+ ++it;
+ TEST_REQUIRE(it != endIt);
+ }
+ it.disable_recursion_pending();
+ TEST_CHECK(it.options() == opts);
+ TEST_CHECK(it.depth() == 1);
+ TEST_CHECK(it.recursion_pending() == false);
+ const path entry = *it;
+
+ // OPERATION UNDER TEST //
+ const recursive_directory_iterator it2(it);
+ // ------------------- //
+
+ TEST_REQUIRE(it2 == it);
+ TEST_CHECK(*it2 == entry);
+ TEST_CHECK(it2.depth() == 1);
+ TEST_CHECK(it2.recursion_pending() == false);
+ TEST_CHECK(it != endIt);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,158 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator& operator=(recursive_directory_iterator const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_copy_assign_tests)
+
+recursive_directory_iterator createInterestingIterator()
+ // Create an "interesting" iterator where all fields are
+ // in a non-default state. The returned 'it' is in a
+ // state such that:
+ // it.options() == directory_options::skip_permission_denied
+ // it.depth() == 1
+ // it.recursion_pending() == true
+{
+ const path testDir = StaticEnv::Dir;
+ const recursive_directory_iterator endIt;
+ recursive_directory_iterator it(testDir,
+ directory_options::skip_permission_denied);
+ TEST_ASSERT(it != endIt);
+ while (it.depth() != 1) {
+ ++it;
+ TEST_ASSERT(it != endIt);
+ }
+ TEST_ASSERT(it.depth() == 1);
+ it.disable_recursion_pending();
+ return it;
+}
+
+
+recursive_directory_iterator createDifferentInterestingIterator()
+ // Create an "interesting" iterator where all fields are
+ // in a non-default state. The returned 'it' is in a
+ // state such that:
+ // it.options() == directory_options::follow_directory_symlink
+ // it.depth() == 2
+ // it.recursion_pending() == false
+{
+ const path testDir = StaticEnv::Dir;
+ const recursive_directory_iterator endIt;
+ recursive_directory_iterator it(testDir,
+ directory_options::follow_directory_symlink);
+ TEST_ASSERT(it != endIt);
+ while (it.depth() != 2) {
+ ++it;
+ TEST_ASSERT(it != endIt);
+ }
+ TEST_ASSERT(it.depth() == 2);
+ return it;
+}
+
+TEST_CASE(test_assignment_signature) {
+ using D = recursive_directory_iterator;
+ static_assert(std::is_copy_assignable<D>::value, "");
+}
+
+TEST_CASE(test_copy_to_end_iterator)
+{
+ const recursive_directory_iterator endIt;
+
+ const recursive_directory_iterator from = createInterestingIterator();
+ const path entry = *from;
+
+ recursive_directory_iterator to;
+ to = from;
+ TEST_REQUIRE(to == from);
+ TEST_CHECK(*to == entry);
+ TEST_CHECK(to.options() == from.options());
+ TEST_CHECK(to.depth() == from.depth());
+ TEST_CHECK(to.recursion_pending() == from.recursion_pending());
+}
+
+
+TEST_CASE(test_copy_from_end_iterator)
+{
+ const recursive_directory_iterator from;
+ recursive_directory_iterator to = createInterestingIterator();
+
+ to = from;
+ TEST_REQUIRE(to == from);
+ TEST_CHECK(to == recursive_directory_iterator{});
+}
+
+TEST_CASE(test_copy_valid_iterator)
+{
+ const recursive_directory_iterator endIt;
+
+ const recursive_directory_iterator it = createInterestingIterator();
+ const path entry = *it;
+
+ recursive_directory_iterator it2 = createDifferentInterestingIterator();
+ TEST_REQUIRE(it2 != it);
+ TEST_CHECK(it2.options() != it.options());
+ TEST_CHECK(it2.depth() != it.depth());
+ TEST_CHECK(it2.recursion_pending() != it.recursion_pending());
+ TEST_CHECK(*it2 != entry);
+
+ it2 = it;
+ TEST_REQUIRE(it2 == it);
+ TEST_CHECK(it2.options() == it.options());
+ TEST_CHECK(it2.depth() == it.depth());
+ TEST_CHECK(it2.recursion_pending() == it.recursion_pending());
+ TEST_CHECK(*it2 == entry);
+}
+
+TEST_CASE(test_returns_reference_to_self)
+{
+ const recursive_directory_iterator it;
+ recursive_directory_iterator it2;
+ recursive_directory_iterator& ref = (it2 = it);
+ TEST_CHECK(&ref == &it2);
+}
+
+TEST_CASE(test_self_copy)
+{
+ // Create two non-equal iterators that have exactly the same state.
+ recursive_directory_iterator it = createInterestingIterator();
+ recursive_directory_iterator it2 = createInterestingIterator();
+ TEST_CHECK(it != it2);
+ TEST_CHECK(it2.options() == it.options());
+ TEST_CHECK(it2.depth() == it.depth());
+ TEST_CHECK(it2.recursion_pending() == it.recursion_pending());
+ TEST_CHECK(*it2 == *it);
+
+ // perform a self-copy and check that the state still matches the
+ // other unmodified iterator.
+ recursive_directory_iterator const& cit = it;
+ it = cit;
+ TEST_CHECK(it2.options() == it.options());
+ TEST_CHECK(it2.depth() == it.depth());
+ TEST_CHECK(it2.recursion_pending() == it.recursion_pending());
+ TEST_CHECK(*it2 == *it);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,240 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class directory_iterator
+
+//
+// explicit recursive_directory_iterator(const path& p);
+// recursive_directory_iterator(const path& p, directory_options options);
+// recursive_directory_iterator(const path& p, error_code& ec) noexcept;
+// recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+using RDI = recursive_directory_iterator;
+
+TEST_SUITE(recursive_directory_iterator_constructor_tests)
+
+TEST_CASE(test_constructor_signatures)
+{
+ using D = recursive_directory_iterator;
+
+ // explicit directory_iterator(path const&);
+ static_assert(!std::is_convertible<path, D>::value, "");
+ static_assert(std::is_constructible<D, path>::value, "");
+ static_assert(!std::is_nothrow_constructible<D, path>::value, "");
+
+ // directory_iterator(path const&, error_code&) noexcept
+ static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, "");
+
+ // directory_iterator(path const&, directory_options);
+ static_assert(std::is_constructible<D, path, directory_options>::value, "");
+ static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, "");
+
+ // directory_iterator(path const&, directory_options, error_code&) noexcept
+ static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, "");
+}
+
+TEST_CASE(test_construction_from_bad_path)
+{
+ std::error_code ec;
+ directory_options opts = directory_options::none;
+ const RDI endIt;
+
+ const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink };
+ for (path const& testPath : testPaths)
+ {
+ {
+ RDI it(testPath, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(it == endIt);
+ }
+ {
+ RDI it(testPath, opts, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(it == endIt);
+ }
+ {
+ TEST_CHECK_THROW(filesystem_error, RDI(testPath));
+ TEST_CHECK_THROW(filesystem_error, RDI(testPath, opts));
+ }
+ }
+}
+
+TEST_CASE(access_denied_test_case)
+{
+ using namespace std::experimental::filesystem;
+ scoped_test_env env;
+ path const testDir = env.make_env_path("dir1");
+ path const testFile = testDir / "testFile";
+ env.create_dir(testDir);
+ env.create_file(testFile, 42);
+
+ // Test that we can iterator over the directory before changing the perms
+ RDI it(testDir);
+ TEST_REQUIRE(it != RDI{});
+
+ // Change the permissions so we can no longer iterate
+ permissions(testDir, perms::none);
+
+ // Check that the construction fails when skip_permissions_denied is
+ // not given.
+ {
+ std::error_code ec;
+ RDI it(testDir, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(it == RDI{});
+ }
+ // Check that construction does not report an error when
+ // 'skip_permissions_denied' is given.
+ {
+ std::error_code ec;
+ RDI it(testDir, directory_options::skip_permission_denied, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(it == RDI{});
+ }
+}
+
+
+TEST_CASE(access_denied_to_file_test_case)
+{
+ using namespace std::experimental::filesystem;
+ scoped_test_env env;
+ path const testFile = env.make_env_path("file1");
+ env.create_file(testFile, 42);
+
+ // Change the permissions so we can no longer iterate
+ permissions(testFile, perms::none);
+
+ // Check that the construction fails when skip_permissions_denied is
+ // not given.
+ {
+ std::error_code ec;
+ RDI it(testFile, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(it == RDI{});
+ }
+ // Check that construction still fails when 'skip_permissions_denied' is given
+ // because we tried to open a file and not a directory.
+ {
+ std::error_code ec;
+ RDI it(testFile, directory_options::skip_permission_denied, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(it == RDI{});
+ }
+}
+
+TEST_CASE(test_open_on_empty_directory_equals_end)
+{
+ scoped_test_env env;
+ const path testDir = env.make_env_path("dir1");
+ env.create_dir(testDir);
+
+ const RDI endIt;
+ {
+ std::error_code ec;
+ RDI it(testDir, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(it == endIt);
+ }
+ {
+ RDI it(testDir);
+ TEST_CHECK(it == endIt);
+ }
+}
+
+TEST_CASE(test_open_on_directory_succeeds)
+{
+ const path testDir = StaticEnv::Dir;
+ std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList),
+ std::end( StaticEnv::DirIterationList));
+ const RDI endIt{};
+
+ {
+ std::error_code ec;
+ RDI it(testDir, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(it != endIt);
+ TEST_CHECK(dir_contents.count(*it));
+ }
+ {
+ RDI it(testDir);
+ TEST_CHECK(it != endIt);
+ TEST_CHECK(dir_contents.count(*it));
+ }
+}
+
+TEST_CASE(test_open_on_file_fails)
+{
+ const path testFile = StaticEnv::File;
+ const RDI endIt{};
+ {
+ std::error_code ec;
+ RDI it(testFile, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(it == endIt);
+ }
+ {
+ TEST_CHECK_THROW(filesystem_error, RDI(testFile));
+ }
+}
+
+TEST_CASE(test_options_post_conditions)
+{
+ const path goodDir = StaticEnv::Dir;
+ const path badDir = StaticEnv::DNE;
+
+ {
+ std::error_code ec;
+
+ RDI it1(goodDir, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(it1.options() == directory_options::none);
+
+ RDI it2(badDir, ec);
+ TEST_REQUIRE(ec);
+ TEST_REQUIRE(it2 == RDI{});
+ }
+ {
+ std::error_code ec;
+ const directory_options opts = directory_options::skip_permission_denied;
+
+ RDI it1(goodDir, opts, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(it1.options() == opts);
+
+ RDI it2(badDir, opts, ec);
+ TEST_REQUIRE(ec);
+ TEST_REQUIRE(it2 == RDI{});
+ }
+ {
+ RDI it(goodDir);
+ TEST_CHECK(it.options() == directory_options::none);
+ }
+ {
+ const directory_options opts = directory_options::follow_directory_symlink;
+ RDI it(goodDir, opts);
+ TEST_CHECK(it.options() == opts);
+ }
+}
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// int depth() const
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_depth_tests)
+
+TEST_CASE(test_depth)
+{
+ const path testDir = StaticEnv::Dir;
+ const path DirDepth1 = StaticEnv::Dir2;
+ const path DirDepth2 = StaticEnv::Dir3;
+ const recursive_directory_iterator endIt{};
+
+ std::error_code ec;
+ recursive_directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(it.depth() == 0);
+
+ bool seen_d1, seen_d2;
+ seen_d1 = seen_d2 = false;
+
+ while (it != endIt) {
+ const path entry = *it;
+ const path parent = entry.parent_path();
+ if (parent == testDir) {
+ TEST_CHECK(it.depth() == 0);
+ } else if (parent == DirDepth1) {
+ TEST_CHECK(it.depth() == 1);
+ seen_d1 = true;
+ } else if (parent == DirDepth2) {
+ TEST_CHECK(it.depth() == 2);
+ seen_d2 = true;
+ } else {
+ TEST_CHECK(!"Unexpected depth while iterating over static env");
+ }
+ ++it;
+ }
+ TEST_REQUIRE(seen_d1 && seen_d2);
+ TEST_CHECK(it == endIt);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// void disable_recursion_pending();
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_disable_recursion_pending_tests)
+
+// NOTE: The main semantics of disable_recursion_pending are tested
+// in the 'recursion_pending()' tests.
+TEST_CASE(basic_test)
+{
+ recursive_directory_iterator it(StaticEnv::Dir);
+ TEST_REQUIRE(it.recursion_pending() == true);
+ it.disable_recursion_pending();
+ TEST_CHECK(it.recursion_pending() == false);
+ it.disable_recursion_pending();
+ TEST_CHECK(it.recursion_pending() == false);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,228 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator& operator++();
+// recursive_directory_iterator& increment(error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+#include <iostream>
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_increment_tests)
+
+TEST_CASE(test_increment_signatures)
+{
+ using D = recursive_directory_iterator;
+ recursive_directory_iterator d; ((void)d);
+ std::error_code ec; ((void)ec);
+
+ ASSERT_SAME_TYPE(decltype(++d), recursive_directory_iterator&);
+ ASSERT_NOT_NOEXCEPT(++d);
+
+ ASSERT_SAME_TYPE(decltype(d.increment(ec)), recursive_directory_iterator&);
+ ASSERT_NOEXCEPT(d.increment(ec));
+}
+
+TEST_CASE(test_prefix_increment)
+{
+ const path testDir = StaticEnv::Dir;
+ const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList),
+ std::end( StaticEnv::RecDirIterationList));
+ const recursive_directory_iterator endIt{};
+
+ std::error_code ec;
+ recursive_directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+
+ std::set<path> unseen_entries = dir_contents;
+ while (!unseen_entries.empty()) {
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+ TEST_REQUIRE(unseen_entries.erase(entry) == 1);
+ recursive_directory_iterator& it_ref = ++it;
+ TEST_CHECK(&it_ref == &it);
+ }
+
+ TEST_CHECK(it == endIt);
+}
+
+TEST_CASE(test_postfix_increment)
+{
+ const path testDir = StaticEnv::Dir;
+ const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList),
+ std::end( StaticEnv::RecDirIterationList));
+ const recursive_directory_iterator endIt{};
+
+ std::error_code ec;
+ recursive_directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+
+ std::set<path> unseen_entries = dir_contents;
+ while (!unseen_entries.empty()) {
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+ TEST_REQUIRE(unseen_entries.erase(entry) == 1);
+ const path entry2 = *it++;
+ TEST_CHECK(entry2 == entry);
+ }
+ TEST_CHECK(it == endIt);
+}
+
+
+TEST_CASE(test_increment_method)
+{
+ const path testDir = StaticEnv::Dir;
+ const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList),
+ std::end( StaticEnv::RecDirIterationList));
+ const recursive_directory_iterator endIt{};
+
+ std::error_code ec;
+ recursive_directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+
+ std::set<path> unseen_entries = dir_contents;
+ while (!unseen_entries.empty()) {
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+ TEST_REQUIRE(unseen_entries.erase(entry) == 1);
+ recursive_directory_iterator& it_ref = it.increment(ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(&it_ref == &it);
+ }
+
+ TEST_CHECK(it == endIt);
+}
+
+TEST_CASE(test_follow_symlinks)
+{
+ const path testDir = StaticEnv::Dir;
+ auto const& IterList = StaticEnv::RecDirFollowSymlinksIterationList;
+
+ const std::set<path> dir_contents(std::begin(IterList), std::end(IterList));
+ const recursive_directory_iterator endIt{};
+
+ std::error_code ec;
+ recursive_directory_iterator it(testDir,
+ directory_options::follow_directory_symlink, ec);
+ TEST_REQUIRE(!ec);
+
+ std::set<path> unseen_entries = dir_contents;
+ while (!unseen_entries.empty()) {
+ TEST_REQUIRE(it != endIt);
+ const path entry = *it;
+
+ TEST_REQUIRE(unseen_entries.erase(entry) == 1);
+ recursive_directory_iterator& it_ref = it.increment(ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(&it_ref == &it);
+ }
+ TEST_CHECK(it == endIt);
+}
+
+TEST_CASE(access_denied_on_recursion_test_case)
+{
+ using namespace std::experimental::filesystem;
+ scoped_test_env env;
+ const path testFiles[] = {
+ env.create_dir("dir1"),
+ env.create_dir("dir1/dir2"),
+ env.create_file("dir1/dir2/file1"),
+ env.create_file("dir1/file2")
+ };
+ const path startDir = testFiles[0];
+ const path permDeniedDir = testFiles[1];
+ const path otherFile = testFiles[3];
+
+ // Change the permissions so we can no longer iterate
+ permissions(permDeniedDir, perms::none);
+
+ const recursive_directory_iterator endIt;
+
+ // Test that recursion resulting in a "EACCESS" error is not ignored
+ // by default.
+ {
+ std::error_code ec;
+ recursive_directory_iterator it(startDir, ec);
+ TEST_REQUIRE(!ec);
+ TEST_REQUIRE(it != endIt);
+ const path elem = *it;
+ TEST_REQUIRE(elem == permDeniedDir);
+
+ it.increment(ec);
+ TEST_REQUIRE(ec);
+ TEST_REQUIRE(it == endIt);
+ }
+ // Same as obove but test operator++().
+ {
+ std::error_code ec;
+ recursive_directory_iterator it(startDir, ec);
+ TEST_REQUIRE(!ec);
+ TEST_REQUIRE(it != endIt);
+ const path elem = *it;
+ TEST_REQUIRE(elem == permDeniedDir);
+
+ TEST_REQUIRE_THROW(filesystem_error, ++it);
+ }
+ // Test that recursion resulting in a "EACCESS" error is ignored when the
+ // correct options are given to the constructor.
+ {
+ std::error_code ec;
+ recursive_directory_iterator it(
+ startDir,directory_options::skip_permission_denied,
+ ec);
+ TEST_REQUIRE(!ec);
+ TEST_REQUIRE(it != endIt);
+ const path elem = *it;
+ TEST_REQUIRE(elem == permDeniedDir);
+
+ it.increment(ec);
+ TEST_REQUIRE(!ec);
+ TEST_REQUIRE(it != endIt);
+ TEST_CHECK(*it == otherFile);
+ }
+ // Test that construction resulting in a "EACCESS" error is not ignored
+ // by default.
+ {
+ std::error_code ec;
+ recursive_directory_iterator it(permDeniedDir, ec);
+ TEST_REQUIRE(ec);
+ TEST_REQUIRE(it == endIt);
+ }
+ // Same as obove but testing the throwing constructors
+ {
+ TEST_REQUIRE_THROW(filesystem_error,
+ recursive_directory_iterator(permDeniedDir));
+ }
+ // Test that construction resulting in a "EACCESS" error constructs the
+ // end iterator when the correct options are given.
+ {
+ std::error_code ec;
+ recursive_directory_iterator it(permDeniedDir,
+ directory_options::skip_permission_denied,
+ ec);
+ TEST_REQUIRE(!ec);
+ TEST_REQUIRE(it == endIt);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator(recursive_directory_iterator&&) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_move_construct_tests)
+
+TEST_CASE(test_constructor_signature)
+{
+ using D = recursive_directory_iterator;
+ static_assert(std::is_nothrow_move_constructible<D>::value, "");
+}
+
+TEST_CASE(test_move_end_iterator)
+{
+ const recursive_directory_iterator endIt;
+ recursive_directory_iterator endIt2{};
+
+ recursive_directory_iterator it(std::move(endIt2));
+ TEST_CHECK(it == endIt);
+ TEST_CHECK(endIt2 == endIt);
+}
+
+TEST_CASE(test_move_valid_iterator)
+{
+ const path testDir = StaticEnv::Dir;
+ const recursive_directory_iterator endIt{};
+
+ // build 'it' up with "interesting" non-default state so we can test
+ // that it gets copied. We want to get 'it' into a state such that:
+ // it.options() != directory_options::none
+ // it.depth() != 0
+ // it.recursion_pending() != true
+ const directory_options opts = directory_options::skip_permission_denied;
+ recursive_directory_iterator it(testDir, opts);
+ TEST_REQUIRE(it != endIt);
+ while (it.depth() == 0) {
+ ++it;
+ TEST_REQUIRE(it != endIt);
+ }
+ it.disable_recursion_pending();
+ TEST_CHECK(it.options() == opts);
+ TEST_CHECK(it.depth() == 1);
+ TEST_CHECK(it.recursion_pending() == false);
+ const path entry = *it;
+
+ // OPERATION UNDER TEST //
+ const recursive_directory_iterator it2(std::move(it));
+ // ------------------- //
+
+ TEST_REQUIRE(it2 != endIt);
+ TEST_CHECK(*it2 == entry);
+ TEST_CHECK(it2.depth() == 1);
+ TEST_CHECK(it2.recursion_pending() == false);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,163 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator& operator=(recursive_directory_iterator const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_move_assign_tests)
+
+recursive_directory_iterator createInterestingIterator()
+ // Create an "interesting" iterator where all fields are
+ // in a non-default state. The returned 'it' is in a
+ // state such that:
+ // it.options() == directory_options::skip_permission_denied
+ // it.depth() == 1
+ // it.recursion_pending() == true
+{
+ const path testDir = StaticEnv::Dir;
+ const recursive_directory_iterator endIt;
+ recursive_directory_iterator it(testDir,
+ directory_options::skip_permission_denied);
+ TEST_ASSERT(it != endIt);
+ while (it.depth() != 1) {
+ ++it;
+ TEST_ASSERT(it != endIt);
+ }
+ TEST_ASSERT(it.depth() == 1);
+ it.disable_recursion_pending();
+ return it;
+}
+
+recursive_directory_iterator createDifferentInterestingIterator()
+ // Create an "interesting" iterator where all fields are
+ // in a non-default state. The returned 'it' is in a
+ // state such that:
+ // it.options() == directory_options::follow_directory_symlink
+ // it.depth() == 2
+ // it.recursion_pending() == false
+{
+ const path testDir = StaticEnv::Dir;
+ const recursive_directory_iterator endIt;
+ recursive_directory_iterator it(testDir,
+ directory_options::follow_directory_symlink);
+ TEST_ASSERT(it != endIt);
+ while (it.depth() != 2) {
+ ++it;
+ TEST_ASSERT(it != endIt);
+ }
+ TEST_ASSERT(it.depth() == 2);
+ return it;
+}
+
+
+TEST_CASE(test_assignment_signature)
+{
+ using D = recursive_directory_iterator;
+ static_assert(std::is_nothrow_move_assignable<D>::value, "");
+}
+
+
+TEST_CASE(test_move_to_end_iterator)
+{
+ const recursive_directory_iterator endIt;
+
+ recursive_directory_iterator from = createInterestingIterator();
+ const recursive_directory_iterator from_copy(from);
+ const path entry = *from;
+
+ recursive_directory_iterator to;
+ to = std::move(from);
+ TEST_REQUIRE(to != endIt);
+ TEST_CHECK(*to == entry);
+ TEST_CHECK(to.options() == from_copy.options());
+ TEST_CHECK(to.depth() == from_copy.depth());
+ TEST_CHECK(to.recursion_pending() == from_copy.recursion_pending());
+ TEST_CHECK(from == endIt || from == to);
+}
+
+
+TEST_CASE(test_move_from_end_iterator)
+{
+ recursive_directory_iterator from;
+ recursive_directory_iterator to = createInterestingIterator();
+
+ to = std::move(from);
+ TEST_REQUIRE(to == from);
+ TEST_CHECK(to == recursive_directory_iterator{});
+}
+
+TEST_CASE(test_move_valid_iterator)
+{
+ const recursive_directory_iterator endIt;
+
+ recursive_directory_iterator it = createInterestingIterator();
+ const recursive_directory_iterator it_copy(it);
+ const path entry = *it;
+
+ recursive_directory_iterator it2 = createDifferentInterestingIterator();
+ const recursive_directory_iterator it2_copy(it2);
+ TEST_REQUIRE(it2 != it);
+ TEST_CHECK(it2.options() != it.options());
+ TEST_CHECK(it2.depth() != it.depth());
+ TEST_CHECK(it2.recursion_pending() != it.recursion_pending());
+ TEST_CHECK(*it2 != entry);
+
+ it2 = std::move(it);
+ TEST_REQUIRE(it2 != it2_copy && it2 != endIt);
+ TEST_CHECK(it2.options() == it_copy.options());
+ TEST_CHECK(it2.depth() == it_copy.depth());
+ TEST_CHECK(it2.recursion_pending() == it_copy.recursion_pending());
+ TEST_CHECK(*it2 == entry);
+ TEST_CHECK(it == endIt || it == it2);
+}
+
+TEST_CASE(test_returns_reference_to_self)
+{
+ recursive_directory_iterator it;
+ recursive_directory_iterator it2;
+ recursive_directory_iterator& ref = (it2 = std::move(it));
+ TEST_CHECK(&ref == &it2);
+}
+
+TEST_CASE(test_self_move)
+{
+ // Create two non-equal iterators that have exactly the same state.
+ recursive_directory_iterator it = createInterestingIterator();
+ recursive_directory_iterator it2 = createInterestingIterator();
+ TEST_CHECK(it != it2);
+ TEST_CHECK(it2.options() == it.options());
+ TEST_CHECK(it2.depth() == it.depth());
+ TEST_CHECK(it2.recursion_pending() == it.recursion_pending());
+ TEST_CHECK(*it2 == *it);
+
+ it = std::move(it);
+ TEST_CHECK(it2.options() == it.options());
+ TEST_CHECK(it2.depth() == it.depth());
+ TEST_CHECK(it2.recursion_pending() == it.recursion_pending());
+ TEST_CHECK(*it2 == *it);
+}
+
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// void pop();
+// void pop(error_code& ec);
+
+#include <experimental/filesystem>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_pop_tests)
+
+TEST_CASE(signature_tests)
+{
+ recursive_directory_iterator it{}; ((void)it);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(it.pop());
+ ASSERT_NOT_NOEXCEPT(it.pop(ec)); // may require allocation or other things
+}
+
+// NOTE: Since the order of iteration is unspecified we use a list of
+// seen files at each depth to determine the new depth after a 'pop()' operation.
+TEST_CASE(test_depth)
+{
+ const recursive_directory_iterator endIt{};
+
+ auto& DE0 = StaticEnv::DirIterationList;
+ std::set<path> notSeenDepth0(std::begin(DE0), std::end(DE0));
+
+ auto& DE1 = StaticEnv::DirIterationListDepth1;
+ std::set<path> notSeenDepth1(std::begin(DE1), std::end(DE1));
+
+ std::error_code ec;
+ recursive_directory_iterator it(StaticEnv::Dir, ec);
+ TEST_REQUIRE(it != endIt);
+ TEST_CHECK(it.depth() == 0);
+
+ while (it.depth() != 2) {
+ if (it.depth() == 0)
+ notSeenDepth0.erase(it->path());
+ else
+ notSeenDepth1.erase(it->path());
+ ++it;
+ TEST_REQUIRE(it != endIt);
+ }
+
+ while (true) {
+ auto set_ec = std::make_error_code(std::errc::address_in_use);
+ it.pop(set_ec);
+ TEST_REQUIRE(!set_ec);
+
+ if (it == endIt) {
+ // We must have seen every entry at depth 0 and 1.
+ TEST_REQUIRE(notSeenDepth0.empty() && notSeenDepth1.empty());
+ break;
+ }
+ else if (it.depth() == 1) {
+ // If we popped to depth 1 then there must be unseen entries
+ // at this level.
+ TEST_REQUIRE(!notSeenDepth1.empty());
+ TEST_CHECK(notSeenDepth1.count(it->path()));
+ notSeenDepth1.clear();
+ }
+ else if (it.depth() == 0) {
+ // If we popped to depth 0 there must be unseen entries at this
+ // level. There should also be no unseen entries at depth 1.
+ TEST_REQUIRE(!notSeenDepth0.empty());
+ TEST_REQUIRE(notSeenDepth1.empty());
+ TEST_CHECK(notSeenDepth0.count(it->path()));
+ notSeenDepth0.clear();
+ }
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// bool recursion_pending() const;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_recursion_pending_tests)
+
+TEST_CASE(initial_value_test)
+{
+ recursive_directory_iterator it(StaticEnv::Dir);
+ TEST_REQUIRE(it.recursion_pending() == true);
+}
+
+TEST_CASE(value_after_copy_construction_and_assignment_test)
+{
+ recursive_directory_iterator rec_pending_it(StaticEnv::Dir);
+ recursive_directory_iterator no_rec_pending_it(StaticEnv::Dir);
+ no_rec_pending_it.disable_recursion_pending();
+
+ { // copy construction
+ recursive_directory_iterator it(rec_pending_it);
+ TEST_CHECK(it.recursion_pending() == true);
+ it.disable_recursion_pending();
+ TEST_REQUIRE(rec_pending_it.recursion_pending() == true);
+
+ recursive_directory_iterator it2(no_rec_pending_it);
+ TEST_CHECK(it2.recursion_pending() == false);
+ }
+ { // copy assignment
+ recursive_directory_iterator it(StaticEnv::Dir);
+ it.disable_recursion_pending();
+ it = rec_pending_it;
+ TEST_CHECK(it.recursion_pending() == true);
+ it.disable_recursion_pending();
+ TEST_REQUIRE(rec_pending_it.recursion_pending() == true);
+
+ recursive_directory_iterator it2(StaticEnv::Dir);
+ it2 = no_rec_pending_it;
+ TEST_CHECK(it2.recursion_pending() == false);
+ }
+ TEST_CHECK(rec_pending_it.recursion_pending() == true);
+ TEST_CHECK(no_rec_pending_it.recursion_pending() == false);
+}
+
+
+TEST_CASE(value_after_move_construction_and_assignment_test)
+{
+ recursive_directory_iterator rec_pending_it(StaticEnv::Dir);
+ recursive_directory_iterator no_rec_pending_it(StaticEnv::Dir);
+ no_rec_pending_it.disable_recursion_pending();
+
+ { // move construction
+ recursive_directory_iterator it_cp(rec_pending_it);
+ recursive_directory_iterator it(std::move(it_cp));
+ TEST_CHECK(it.recursion_pending() == true);
+
+ recursive_directory_iterator it_cp2(no_rec_pending_it);
+ recursive_directory_iterator it2(std::move(it_cp2));
+ TEST_CHECK(it2.recursion_pending() == false);
+ }
+ { // copy assignment
+ recursive_directory_iterator it(StaticEnv::Dir);
+ it.disable_recursion_pending();
+ recursive_directory_iterator it_cp(rec_pending_it);
+ it = std::move(it_cp);
+ TEST_CHECK(it.recursion_pending() == true);
+
+ recursive_directory_iterator it2(StaticEnv::Dir);
+ recursive_directory_iterator it_cp2(no_rec_pending_it);
+ it2 = std::move(it_cp2);
+ TEST_CHECK(it2.recursion_pending() == false);
+ }
+ TEST_CHECK(rec_pending_it.recursion_pending() == true);
+ TEST_CHECK(no_rec_pending_it.recursion_pending() == false);
+}
+
+TEST_CASE(increment_resets_value)
+{
+ const recursive_directory_iterator endIt;
+ {
+ recursive_directory_iterator it(StaticEnv::Dir);
+ it.disable_recursion_pending();
+ TEST_CHECK(it.recursion_pending() == false);
+ ++it;
+ TEST_CHECK(it.recursion_pending() == true);
+ TEST_CHECK(it.depth() == 0);
+ }
+ {
+ recursive_directory_iterator it(StaticEnv::Dir);
+ it.disable_recursion_pending();
+ TEST_CHECK(it.recursion_pending() == false);
+ it++;
+ TEST_CHECK(it.recursion_pending() == true);
+ TEST_CHECK(it.depth() == 0);
+ }
+ {
+ recursive_directory_iterator it(StaticEnv::Dir);
+ it.disable_recursion_pending();
+ TEST_CHECK(it.recursion_pending() == false);
+ std::error_code ec;
+ it.increment(ec);
+ TEST_CHECK(it.recursion_pending() == true);
+ TEST_CHECK(it.depth() == 0);
+ }
+}
+
+TEST_CASE(pop_does_not_reset_value)
+{
+ const recursive_directory_iterator endIt;
+ recursive_directory_iterator it(StaticEnv::Dir);
+
+ while (it.depth() == 0) {
+ ++it;
+ TEST_REQUIRE(it != endIt);
+ }
+ it.disable_recursion_pending();
+ it.pop();
+ TEST_REQUIRE(it != endIt);
+ TEST_CHECK(it.recursion_pending() == false);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
+// recursive_directory_iterator end(recursive_directory_iterator iter) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+#include <iostream>
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(recursive_directory_iterator_begin_end_tests)
+
+TEST_CASE(test_function_signatures)
+{
+ using D = recursive_directory_iterator;
+ recursive_directory_iterator d; ((void)d);
+
+ ASSERT_SAME_TYPE(decltype(begin(d)), recursive_directory_iterator);
+ ASSERT_NOEXCEPT(begin(std::move(d)));
+
+ ASSERT_SAME_TYPE(decltype(end(d)), recursive_directory_iterator);
+ ASSERT_NOEXCEPT(end(std::move(d)));
+}
+
+TEST_CASE(test_ranged_for_loop)
+{
+ const path testDir = StaticEnv::Dir;
+ std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList),
+ std::end( StaticEnv::RecDirIterationList));
+
+ std::error_code ec;
+ recursive_directory_iterator it(testDir, ec);
+ TEST_REQUIRE(!ec);
+
+ for (auto& elem : it) {
+ TEST_CHECK(dir_contents.erase(elem) == 1);
+ }
+ TEST_CHECK(dir_contents.empty());
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,75 @@
+#ifndef TEST_BITMASK_TYPE_HPP
+#define TEST_BITMASK_TYPE_HPP
+
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+
+template <class EnumType, EnumType Val1, EnumType Val2,
+ class UT = typename std::underlying_type<EnumType>::type,
+ UT UVal1 = static_cast<UT>(Val1),
+ UT UVal2 = static_cast<UT>(Val2),
+ UT UZero = static_cast<UT>(0),
+ EnumType Zero = static_cast<EnumType>(0)
+ >
+struct check_bitmask_type {
+
+ static constexpr UT dcast(EnumType e) { return static_cast<UT>(e); }
+ static constexpr UT unpromote(decltype(~UZero) promoted) { return static_cast<UT>(promoted); }
+ // We need two values that are non-zero and share at least one bit.
+ static_assert(Val1 != Zero && Val2 != Zero, "");
+ static_assert(Val1 != Val2, "");
+ static_assert((UVal1 & UVal2) == 0, "");
+
+
+ static bool check()
+ {
+ {
+ EnumType ValRef = Val1;
+ ASSERT_SAME_TYPE(EnumType, decltype(Val1 & Val2));
+ ASSERT_SAME_TYPE(EnumType, decltype(Val1 | Val2));
+ ASSERT_SAME_TYPE(EnumType, decltype(Val1 ^ Val2));
+ ASSERT_SAME_TYPE(EnumType, decltype(~Val1));
+ ASSERT_SAME_TYPE(EnumType&, decltype(ValRef &= Val2));
+ ASSERT_SAME_TYPE(EnumType&, decltype(ValRef |= Val2));
+ ASSERT_SAME_TYPE(EnumType&, decltype(ValRef ^= Val2));
+ }
+
+ static_assert((Val1 & Zero) == Zero, "");
+ static_assert((Val1 & Val1) == Val1, "");
+ static_assert(dcast(Val1 & Val2) == (UVal1 & UVal2), "");
+
+ static_assert((Val1 | Zero) == Val1, "");
+ static_assert(dcast(Val1 | Val2) == (UVal1 | UVal2), "");
+
+ static_assert((Val1 ^ Zero) == Val1, "");
+ static_assert(dcast(Val1 ^ Val2) == (UVal1 ^ UVal2), "");
+
+ static_assert(dcast(~Zero) == unpromote(~UZero), "");
+ static_assert(dcast(~Val1) == unpromote(~UVal1), "");
+
+ {
+ EnumType e = Val1;
+ EnumType& eref = (e &= Val2);
+ assert(&eref == &e);
+ assert(dcast(eref) == (UVal1 & UVal2));
+ }
+ {
+ EnumType e = Val1;
+ EnumType& eref = (e |= Val2);
+ assert(&eref == &e);
+ assert(dcast(eref) == (UVal1 | UVal2));
+ }
+ {
+ EnumType e = Val1;
+ EnumType& eref = (e ^= Val2);
+ assert(&eref == &e);
+ assert(dcast(eref) == (UVal1 ^ UVal2));
+ }
+ return true;
+ }
+};
+
+#endif // TEST_BITMASK_TYPE
Added: libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// enum class copy_options;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "check_bitmask_types.hpp"
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+constexpr fs::copy_options ME(int val) { return static_cast<fs::copy_options>(val); }
+
+int main() {
+ typedef fs::copy_options E;
+ static_assert(std::is_enum<E>::value, "");
+
+ // Check that E is a scoped enum by checking for conversions.
+ typedef std::underlying_type<E>::type UT;
+ static_assert(!std::is_convertible<E, UT>::value, "");
+
+ static_assert(std::is_same<UT, unsigned short>::value, ""); // Implementation detail
+
+ typedef check_bitmask_type<E, E::skip_existing, E::update_existing> BitmaskTester;
+ assert(BitmaskTester::check());
+
+ static_assert(
+ E::none == ME(0),
+ "Expected enumeration values do not match");
+ // Option group for copy_file
+ static_assert(
+ E::skip_existing == ME(1) &&
+ E::overwrite_existing == ME(2) &&
+ E::update_existing == ME(4),
+ "Expected enumeration values do not match");
+ // Option group for copy on directories
+ static_assert(
+ E::recursive == ME(8),
+ "Expected enumeration values do not match");
+ // Option group for copy on symlinks
+ static_assert(
+ E::copy_symlinks == ME(16) &&
+ E::skip_symlinks == ME(32),
+ "Expected enumeration values do not match");
+ // Option group for changing form of copy
+ static_assert(
+ E::directories_only == ME(64) &&
+ E::create_symlinks == ME(128) &&
+ E::create_hard_links == ME(256),
+ "Expected enumeration values do not match");
+}
Added: libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// enum class directory_options;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+#include <sys/stat.h>
+
+#include "test_macros.h"
+#include "check_bitmask_types.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+constexpr fs::directory_options ME(int val) { return static_cast<fs::directory_options>(val); }
+
+int main() {
+ typedef fs::directory_options E;
+ static_assert(std::is_enum<E>::value, "");
+
+ // Check that E is a scoped enum by checking for conversions.
+ typedef std::underlying_type<E>::type UT;
+ static_assert(!std::is_convertible<E, UT>::value, "");
+ static_assert(std::is_same<UT, unsigned char>::value, "");
+
+ typedef check_bitmask_type<E, E::follow_directory_symlink, E::skip_permission_denied> BitmaskTester;
+ assert(BitmaskTester::check());
+
+ static_assert(
+ E::none == ME(0) &&
+ E::follow_directory_symlink == ME(1) &&
+ E::skip_permission_denied == ME(2),
+ "Expected enumeration values do not match");
+
+}
Added: libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp Fri Jun 17 14:46:40 2016
@@ -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
+
+// <experimental/filesystem>
+
+// enum class file_type;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+constexpr fs::file_type ME(int val) { return static_cast<fs::file_type>(val); }
+
+int main() {
+ typedef fs::file_type E;
+ static_assert(std::is_enum<E>::value, "");
+
+ // Check that E is a scoped enum by checking for conversions.
+ typedef std::underlying_type<E>::type UT;
+ static_assert(!std::is_convertible<E, UT>::value, "");
+
+ static_assert(std::is_same<UT, signed char>::value, ""); // Implementation detail
+
+ static_assert(
+ E::none == ME(0) &&
+ E::not_found == ME(-1) &&
+ E::regular == ME(1) &&
+ E::directory == ME(2) &&
+ E::symlink == ME(3) &&
+ E::block == ME(4) &&
+ E::character == ME(5) &&
+ E::fifo == ME(6) &&
+ E::socket == ME(7) &&
+ E::unknown == ME(8),
+ "Expected enumeration values do not match");
+}
Added: libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// enum class perms;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+#include <sys/stat.h>
+
+#include "test_macros.h"
+#include "check_bitmask_types.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+constexpr fs::perms ME(int val) { return static_cast<fs::perms>(val); }
+
+int main() {
+ typedef fs::perms E;
+ static_assert(std::is_enum<E>::value, "");
+
+ // Check that E is a scoped enum by checking for conversions.
+ typedef std::underlying_type<E>::type UT;
+ static_assert(!std::is_convertible<E, UT>::value, "");
+
+ static_assert(std::is_same<UT, unsigned >::value, ""); // Implementation detail
+
+ typedef check_bitmask_type<E, E::group_all, E::owner_all> BitmaskTester;
+ assert(BitmaskTester::check());
+
+ static_assert(
+ E::none == ME(0) &&
+
+ E::owner_read == ME(0400) &&
+ E::owner_write == ME(0200) &&
+ E::owner_exec == ME(0100) &&
+ E::owner_all == ME(0700) &&
+
+ E::group_read == ME(040) &&
+ E::group_write == ME(020) &&
+ E::group_exec == ME(010) &&
+ E::group_all == ME(070) &&
+
+ E::others_read == ME(04) &&
+ E::others_write == ME(02) &&
+ E::others_exec == ME(01) &&
+ E::others_all == ME(07) &&
+ E::all == ME(0777) &&
+ E::set_uid == ME(04000) &&
+ E::set_gid == ME(02000) &&
+ E::sticky_bit == ME(01000) &&
+ E::mask == ME(07777) &&
+ E::unknown == ME(0xFFFF) &&
+ E::add_perms == ME(0x10000) &&
+ E::remove_perms == ME(0x20000) &&
+ E::resolve_symlinks == ME(0x40000),
+ "Expected enumeration values do not match");
+}
Added: libcxx/trunk/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
Added: libcxx/trunk/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// typedef TrivialClock file_time_type;
+
+#include <experimental/filesystem>
+#include <chrono>
+#include <type_traits>
+
+// system_clock is used because it meets the requirements of TrivialClock,
+// and it's resolution and range of system_clock should match the operating
+// systems file time type.
+typedef std::chrono::system_clock ExpectedClock;
+typedef std::chrono::time_point<ExpectedClock> ExpectedTimePoint;
+
+int main() {
+ static_assert(std::is_same<
+ std::experimental::filesystem::file_time_type,
+ ExpectedTimePoint
+ >::value, "");
+}
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// path absolute(const path& p, const path& base=current_path());
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_absolute_path_test_suite)
+
+TEST_CASE(absolute_signature_test)
+{
+ const path p; ((void)p);
+ ASSERT_NOT_NOEXCEPT(absolute(p));
+ ASSERT_NOT_NOEXCEPT(absolute(p, p));
+}
+
+// There are 4 cases is the proposal for absolute path.
+// Each scope tests one of the cases.
+TEST_CASE(absolute_path_test)
+{
+ // has_root_name() && has_root_directory()
+ {
+ const path p("//net/foo");
+ const path base("//net/bar/baz");
+ TEST_REQUIRE(p.has_root_name());
+ TEST_REQUIRE(p.has_root_directory());
+ TEST_CHECK(p.is_absolute());
+ path ret = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == p);
+ }
+ // !has_root_name() && has_root_directory()
+ {
+ const path p("/foo");
+ const path base("//net/bar");
+ TEST_REQUIRE(not p.has_root_name());
+ TEST_REQUIRE(p.has_root_directory());
+ TEST_CHECK(p.is_absolute());
+ // ensure absolute(base) is not recursivly called
+ TEST_REQUIRE(base.has_root_name());
+ TEST_REQUIRE(base.has_root_directory());
+
+ path ret = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret.has_root_name());
+ TEST_CHECK(ret.root_name() == path("//net"));
+ TEST_CHECK(ret.has_root_directory());
+ TEST_CHECK(ret.root_directory() == path("/"));
+ TEST_CHECK(ret == path("//net/foo"));
+ }
+ // has_root_name() && !has_root_directory()
+ {
+ const path p("//net");
+ const path base("//net/foo/bar");
+ TEST_REQUIRE(p.has_root_name());
+ TEST_REQUIRE(not p.has_root_directory());
+ TEST_CHECK(not p.is_absolute());
+ // absolute is called recursivly on base. The following conditions
+ // must be true for it to return base unmodified
+ TEST_REQUIRE(base.has_root_name());
+ TEST_REQUIRE(base.has_root_directory());
+ path ret = absolute(p, base);
+ const path expect("//net/foo/bar");
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == path("//net/foo/bar"));
+ }
+ // !has_root_name() && !has_root_directory()
+ {
+ const path p("bar/baz");
+ const path base("//net/foo");
+ TEST_REQUIRE(not p.has_root_name());
+ TEST_REQUIRE(not p.has_root_directory());
+ TEST_REQUIRE(base.has_root_name());
+ TEST_REQUIRE(base.has_root_directory());
+
+ path ret = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == path("//net/foo/bar/baz"));
+ }
+}
+
+TEST_CASE(absolute_path_with_default_base)
+{
+ const path testCases[] = {
+ "//net/foo", // has_root_name() && has_root_directory()
+ "/foo", // !has_root_name() && has_root_directory()
+ "//net", // has_root_name() && !has_root_directory()
+ "bar/baz" // !has_root_name() && !has_root_directory()
+ };
+ const path base = current_path();
+ for (auto& p : testCases) {
+ const path ret = absolute(p);
+ const path expect = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == expect);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// path canonical(const path& p, const path& base = current_path());
+// path canonical(const path& p, error_code& ec);
+// path canonical(const path& p, const path& base, error_code& ec);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_canonical_path_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(canonical(p));
+ ASSERT_NOT_NOEXCEPT(canonical(p, p));
+ ASSERT_NOT_NOEXCEPT(canonical(p, ec));
+ ASSERT_NOT_NOEXCEPT(canonical(p, p, ec));
+}
+
+// There are 4 cases is the proposal for absolute path.
+// Each scope tests one of the cases.
+TEST_CASE(test_canonical)
+{
+ // has_root_name() && has_root_directory()
+ const path Root = StaticEnv::Root;
+ const path RootName = Root.filename();
+ const path DirName = StaticEnv::Dir.filename();
+ const path SymlinkName = StaticEnv::SymlinkToFile.filename();
+ struct TestCase {
+ path p;
+ path expect;
+ path base = StaticEnv::Root;
+ };
+ const TestCase testCases[] = {
+ { ".", Root, Root},
+ { DirName / ".." / "." / DirName, StaticEnv::Dir, Root},
+ { StaticEnv::Dir2 / "..", StaticEnv::Dir },
+ { StaticEnv::Dir3 / "../..", StaticEnv::Dir },
+ { StaticEnv::Dir / ".", StaticEnv::Dir },
+ { Root / "." / DirName / ".." / DirName, StaticEnv::Dir},
+ { path("..") / "." / RootName / DirName / ".." / DirName, StaticEnv::Dir, Root},
+ { StaticEnv::SymlinkToFile, StaticEnv::File },
+ { SymlinkName, StaticEnv::File, StaticEnv::Root}
+ };
+ for (auto& TC : testCases) {
+ std::error_code ec;
+ const path ret = canonical(TC.p, TC.base, ec);
+ TEST_REQUIRE(!ec);
+ const path ret2 = canonical(TC.p, TC.base);
+ TEST_CHECK(ret == TC.expect);
+ TEST_CHECK(ret == ret2);
+ TEST_CHECK(ret.is_absolute());
+ }
+}
+
+TEST_CASE(test_dne_path)
+{
+ std::error_code ec;
+ {
+ const path ret = canonical(StaticEnv::DNE, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(ret == path{});
+ }
+ ec.clear();
+ {
+ const path ret = canonical(StaticEnv::DNE, StaticEnv::Root, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(ret == path{});
+ }
+ {
+ TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE));
+ TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE, StaticEnv::Root));
+ }
+}
+
+TEST_CASE(test_exception_contains_paths)
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ const path p = "blabla/dne";
+ const path base = StaticEnv::Root;
+ try {
+ canonical(p, base);
+ TEST_REQUIRE(false);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ TEST_CHECK(err.path2() == base);
+ }
+ try {
+ canonical(p);
+ TEST_REQUIRE(false);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ TEST_CHECK(err.path2() == current_path());
+ }
+#endif
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,251 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// void copy(const path& from, const path& to);
+// void copy(const path& from, const path& to, error_code& ec) noexcept;
+// 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) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+using CO = fs::copy_options;
+
+TEST_SUITE(filesystem_copy_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ const copy_options opts{}; ((void)opts);
+ ASSERT_NOT_NOEXCEPT(fs::copy(p, p));
+ ASSERT_NOEXCEPT(fs::copy(p, p, ec));
+ ASSERT_NOT_NOEXCEPT(copy(p, p, opts));
+ ASSERT_NOEXCEPT(copy(p, p, opts, ec));
+}
+
+// There are 4 cases is the proposal for absolute path.
+// Each scope tests one of the cases.
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::copy(f, t);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == t
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path dir = env.create_dir("dir");
+ const path fifo = env.create_fifo("fifo");
+ TEST_REQUIRE(is_other(fifo));
+
+ // !exists(f)
+ {
+ std::error_code ec;
+ const path f = StaticEnv::DNE;
+ const path t = env.test_root;
+ fs::copy(f, t, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(f, t, ec));
+ }
+ { // equivalent(f, t) == true
+ std::error_code ec;
+ fs::copy(file, file, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, file, ec));
+ }
+ { // is_directory(from) && is_file(to)
+ std::error_code ec;
+ fs::copy(dir, file, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(dir, file, ec));
+ }
+ { // is_other(from)
+ std::error_code ec;
+ fs::copy(fifo, dir, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(fifo, dir, ec));
+ }
+ { // is_other(to)
+ std::error_code ec;
+ fs::copy(file, fifo, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, fifo, ec));
+ }
+}
+
+TEST_CASE(from_is_symlink)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path symlink = env.create_symlink(file, "sym");
+ const path dne = env.make_env_path("dne");
+
+ { // skip symlinks
+ std::error_code ec;
+ fs::copy(symlink, dne, copy_options::skip_symlinks, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(dne));
+ }
+ {
+ const path dest = env.make_env_path("dest");
+ std::error_code ec;
+ fs::copy(symlink, dest, copy_options::copy_symlinks, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(exists(dest));
+ TEST_CHECK(is_symlink(dest));
+ }
+ { // copy symlink but target exists
+ std::error_code ec;
+ fs::copy(symlink, file, copy_options::copy_symlinks, ec);
+ TEST_CHECK(ec);
+ }
+ { // create symlinks but target exists
+ std::error_code ec;
+ fs::copy(symlink, file, copy_options::create_symlinks, ec);
+ TEST_CHECK(ec);
+ }
+}
+
+TEST_CASE(from_is_regular_file)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+ { // skip copy because of directory
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ fs::copy(file, dest, CO::directories_only, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(dest));
+ }
+ { // create symlink to file
+ const path dest = env.make_env_path("sym");
+ std::error_code ec;
+ fs::copy(file, dest, CO::create_symlinks, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(file, canonical(dest)));
+ }
+ { // create hard link to file
+ const path dest = env.make_env_path("hardlink");
+ TEST_CHECK(hard_link_count(file) == 1);
+ std::error_code ec;
+ fs::copy(file, dest, CO::create_hard_links, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(exists(dest));
+ TEST_CHECK(hard_link_count(file) == 2);
+ }
+ { // is_directory(t)
+ const path dest_dir = env.create_dir("dest_dir");
+ const path expect_dest = dest_dir / file.filename();
+ std::error_code ec;
+ fs::copy(file, dest_dir, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_regular_file(expect_dest));
+ }
+ { // otherwise copy_file(from, to, ...)
+ const path dest = env.make_env_path("file_copy");
+ std::error_code ec;
+ fs::copy(file, dest, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_regular_file(dest));
+ }
+}
+
+TEST_CASE(from_is_directory)
+{
+ struct FileInfo {
+ path filename;
+ int size;
+ };
+ const FileInfo files[] = {
+ {"file1", 0},
+ {"file2", 42},
+ {"file3", 300}
+ };
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path nested_dir_name = "dir2";
+ const path nested_dir = env.create_dir("dir/dir2");
+
+ for (auto& FI : files) {
+ env.create_file(dir / FI.filename, FI.size);
+ env.create_file(nested_dir / FI.filename, FI.size);
+ }
+ { // test for non-existant directory
+ const path dest = env.make_env_path("dest_dir1");
+ std::error_code ec;
+ fs::copy(dir, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_directory(dest));
+ for (auto& FI : files) {
+ path created = dest / FI.filename;
+ TEST_CHECK(is_regular_file(created));
+ TEST_CHECK(file_size(created) == FI.size);
+ }
+ TEST_CHECK(!is_directory(dest / nested_dir_name));
+ }
+ { // test for existing directory
+ const path dest = env.create_dir("dest_dir2");
+ std::error_code ec;
+ fs::copy(dir, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_directory(dest));
+ for (auto& FI : files) {
+ path created = dest / FI.filename;
+ TEST_CHECK(is_regular_file(created));
+ TEST_CHECK(file_size(created) == FI.size);
+ }
+ TEST_CHECK(!is_directory(dest / nested_dir_name));
+ }
+ { // test recursive copy
+ const path dest = env.make_env_path("dest_dir3");
+ std::error_code ec;
+ fs::copy(dir, dest, CO::recursive, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_directory(dest));
+ const path nested_dest = dest / nested_dir_name;
+ TEST_REQUIRE(is_directory(nested_dest));
+ for (auto& FI : files) {
+ path created = dest / FI.filename;
+ path nested_created = nested_dest / FI.filename;
+ TEST_CHECK(is_regular_file(created));
+ TEST_CHECK(file_size(created) == FI.size);
+ TEST_CHECK(is_regular_file(nested_created));
+ TEST_CHECK(file_size(nested_created) == FI.size);
+ }
+ }
+
+}
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool copy_file(const path& from, const path& to);
+// bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
+// 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) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+using CO = fs::copy_options;
+
+TEST_SUITE(filesystem_copy_file_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ const copy_options opts{}; ((void)opts);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, ec)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts, ec)), bool);
+ ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p));
+ ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts));
+ ASSERT_NOEXCEPT(fs::copy_file(p, p, ec));
+ ASSERT_NOEXCEPT(fs::copy_file(p, p, opts, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::copy_file(f, t);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == t
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path dne = env.make_env_path("dne");
+ { // exists(to) && equivalent(to, from)
+ std::error_code ec;
+ TEST_CHECK(fs::copy_file(file, file, ec) == false);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, file, ec));
+ }
+ { // exists(to) && !(skip_existing | overwrite_existing | update_existing)
+ std::error_code ec;
+ TEST_CHECK(fs::copy_file(file, file2, ec) == false);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, file2, ec));
+ }
+}
+
+TEST_CASE(copy_file)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+
+ { // !exists(to)
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(file, dest, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(dest) == 42);
+ }
+ { // exists(to) && overwrite_existing
+ const path dest = env.create_file("dest2", 55);
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(file, dest,
+ copy_options::overwrite_existing, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(dest) == 42);
+ }
+ { // exists(to) && update_existing
+ using Sec = std::chrono::seconds;
+ const path older = env.create_file("older_file", 1);
+
+ std::this_thread::sleep_for(Sec(2));
+ const path from = env.create_file("update_from", 55);
+
+ std::this_thread::sleep_for(Sec(2));
+ const path newer = env.create_file("newer_file", 2);
+
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(from, older, copy_options::update_existing, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(older) == 55);
+
+ TEST_REQUIRE(fs::copy_file(from, newer, copy_options::update_existing, ec) == false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(newer) == 2);
+ }
+ { // skip_existing
+ const path file2 = env.create_file("file2", 55);
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(file, file2, copy_options::skip_existing, ec) == false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file2) == 55);
+ }
+}
+
+TEST_CASE(test_attributes_get_copied)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path dest = env.make_env_path("file2");
+ auto st = status(file);
+ perms default_perms = st.permissions();
+ perms new_perms = perms::owner_read;
+ permissions(file, new_perms);
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(file, dest, ec) == true);
+ TEST_CHECK(!ec);
+ auto new_st = status(dest);
+ TEST_CHECK(new_st.permissions() == new_perms);
+}
+
+TEST_CASE(copy_dir_test)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path dest = env.create_dir("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::copy_file(file, dest, ec) == false);
+ TEST_CHECK(ec);
+ ec.clear();
+ TEST_CHECK(fs::copy_file(dest, file, ec) == false);
+ TEST_CHECK(ec);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// 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) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_copy_symlink_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::copy_symlink(p, p));
+ ASSERT_NOEXCEPT(fs::copy_symlink(p, p, ec));
+}
+
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::copy_symlink(f, t);
+ return true;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path sym = env.create_symlink(file, "sym");
+ const path dir = env.create_dir("dir");
+ const path dne = env.make_env_path("dne");
+ { // from is a file, not a symlink
+ std::error_code ec;
+ fs::copy_symlink(file, dne, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, dne, ec));
+ }
+ { // from is a file, not a symlink
+ std::error_code ec;
+ fs::copy_symlink(dir, dne, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(dir, dne, ec));
+ }
+ { // destination exists
+ std::error_code ec;
+ fs::copy_symlink(sym, file2, ec);
+ TEST_REQUIRE(ec);
+ }
+}
+
+TEST_CASE(copy_symlink_basic)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir_sym = env.create_symlink(dir, "dir_sym");
+ const path file = env.create_file("file", 42);
+ const path file_sym = env.create_symlink(file, "file_sym");
+ { // test for directory symlinks
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ fs::copy_symlink(dir_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, dir));
+ }
+ { // test for file symlinks
+ const path dest = env.make_env_path("dest2");
+ std::error_code ec;
+ fs::copy_symlink(file_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, file));
+ }
+}
+
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool create_directories(const path& p);
+// bool create_directories(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_directories_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::create_directories(p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directories(p, ec)), bool);
+ ASSERT_NOT_NOEXCEPT(fs::create_directories(p));
+ ASSERT_NOEXCEPT(fs::create_directories(p, ec));
+}
+
+TEST_CASE(create_existing_directory)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directories(dir, ec) == false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+}
+
+TEST_CASE(create_directory_one_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directories(dir, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+}
+
+TEST_CASE(create_directories_multi_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1/dir2/dir3");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directories(dir, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool create_directory(const path& p);
+// bool create_directory(const path& p, error_code& ec) noexcept;
+// bool create_directory(const path& p, const path& attr);
+// bool create_directory(const path& p, const path& attr, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_directory_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, ec)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p, ec)), bool);
+ ASSERT_NOT_NOEXCEPT(fs::create_directory(p));
+ ASSERT_NOEXCEPT(fs::create_directory(p, ec));
+ ASSERT_NOT_NOEXCEPT(fs::create_directory(p, p));
+ ASSERT_NOEXCEPT(fs::create_directory(p, p, ec));
+}
+
+
+TEST_CASE(create_existing_directory)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, ec) == false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+ // Test throwing version
+ TEST_CHECK(fs::create_directory(dir) == false);
+}
+
+TEST_CASE(create_directory_one_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+
+ auto st = status(dir);
+ perms owner_perms = perms::owner_all;
+ perms gperms = perms::group_all;
+ perms other_perms = perms::others_read | perms::others_exec;
+#if defined(__APPLE__) || defined(__FreeBSD__)
+ gperms = perms::group_read | perms::group_exec;
+#endif
+ TEST_CHECK((st.permissions() & perms::owner_all) == owner_perms);
+ TEST_CHECK((st.permissions() & perms::group_all) == gperms);
+ TEST_CHECK((st.permissions() & perms::others_all) == other_perms);
+}
+
+TEST_CASE(create_directory_multi_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1/dir2");
+ const path dir1 = env.make_env_path("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(!is_directory(dir));
+ TEST_CHECK(!is_directory(dir1));
+}
+
+TEST_CASE(dest_is_file)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(file, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(is_regular_file(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool create_directory(const path& p, const path& attr);
+// bool create_directory(const path& p, const path& attr, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_directory_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p, ec)), bool);
+ ASSERT_NOT_NOEXCEPT(fs::create_directory(p, p));
+ ASSERT_NOEXCEPT(fs::create_directory(p, p, ec));
+}
+
+TEST_CASE(create_existing_directory)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir1");
+ const path dir2 = env.create_dir("dir2");
+
+ const perms orig_p = status(dir).permissions();
+ permissions(dir2, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, dir2, ec) == false);
+ TEST_CHECK(!ec);
+
+ // Check that the permissions were unchanged
+ TEST_CHECK(orig_p == status(dir).permissions());
+
+ // Test throwing version
+ TEST_CHECK(fs::create_directory(dir, dir2) == false);
+}
+
+TEST_CASE(create_directory_one_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1");
+ const path attr_dir = env.create_dir("dir2");
+ permissions(attr_dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, attr_dir, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+
+ // Check that the new directory has the same permissions as attr_dir
+ auto st = status(dir);
+ TEST_CHECK(st.permissions() == perms::none);
+}
+
+TEST_CASE(create_directory_multi_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1/dir2");
+ const path dir1 = env.make_env_path("dir1");
+ const path attr_dir = env.create_dir("attr_dir");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, attr_dir, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(!is_directory(dir));
+ TEST_CHECK(!is_directory(dir1));
+}
+
+TEST_CASE(dest_is_file)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path attr_dir = env.create_dir("attr_dir");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(file, attr_dir, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(is_regular_file(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// void create_directory_symlink(const path& existing_symlink, const path& new_symlink);
+// void create_directory_symlink(const path& existing_symlink, const path& new_symlink,
+// error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_directory_symlink_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::create_directory_symlink(p, p));
+ ASSERT_NOEXCEPT(fs::create_directory_symlink(p, p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::create_directory_symlink(f, t);
+ return true;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path sym = env.create_symlink(file, "sym");
+ { // destination exists
+ std::error_code ec;
+ fs::create_directory_symlink(sym, file2, ec);
+ TEST_REQUIRE(ec);
+ }
+}
+
+TEST_CASE(create_directory_symlink_basic)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir_sym = env.create_symlink(dir, "dir_sym");
+
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ fs::create_directory_symlink(dir_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, dir));
+}
+
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// void create_hard_link(const path& existing_symlink, const path& new_symlink);
+// void create_hard_link(const path& existing_symlink, const path& new_symlink,
+// error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_hard_link_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::create_hard_link(p, p));
+ ASSERT_NOEXCEPT(fs::create_hard_link(p, p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::create_hard_link(f, t);
+ return true;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path sym = env.create_symlink(file, "sym");
+ { // destination exists
+ std::error_code ec;
+ fs::create_hard_link(sym, file2, ec);
+ TEST_REQUIRE(ec);
+ }
+}
+
+TEST_CASE(create_file_hard_link)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file");
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ TEST_CHECK(hard_link_count(file) == 1);
+ fs::create_hard_link(file, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(exists(dest));
+ TEST_CHECK(equivalent(dest, file));
+ TEST_CHECK(hard_link_count(file) == 2);
+}
+
+TEST_CASE(create_directory_hard_link_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dest = env.make_env_path("dest2");
+ std::error_code ec;
+
+ fs::create_hard_link(dir, dest, ec);
+ TEST_REQUIRE(ec);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// void create_symlink(const path& existing_symlink, const path& new_symlink);
+// void create_symlink(const path& existing_symlink, const path& new_symlink,
+// error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_symlink_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::create_symlink(p, p));
+ ASSERT_NOEXCEPT(fs::create_symlink(p, p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::create_symlink(f, t);
+ return true;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path sym = env.create_symlink(file, "sym");
+ { // destination exists
+ std::error_code ec;
+ fs::create_symlink(sym, file2, ec);
+ TEST_REQUIRE(ec);
+ }
+}
+
+TEST_CASE(create_symlink_basic)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path file_sym = env.create_symlink(file, "file_sym");
+ const path dir = env.create_dir("dir");
+ const path dir_sym = env.create_symlink(dir, "dir_sym");
+ {
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ fs::create_symlink(file_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, file));
+ }
+ {
+ const path dest = env.make_env_path("dest2");
+ std::error_code ec;
+ fs::create_symlink(dir_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, dir));
+ }
+}
+
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// path current_path();
+// path current_path(error_code& ec);
+// void current_path(path const&);
+// void current_path(path const&, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_current_path_path_test_suite)
+
+TEST_CASE(current_path_signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(current_path());
+ ASSERT_NOT_NOEXCEPT(current_path(ec));
+ ASSERT_NOT_NOEXCEPT(current_path(p));
+ ASSERT_NOEXCEPT(current_path(p, ec));
+}
+
+TEST_CASE(current_path_test)
+{
+ std::error_code ec;
+ const path p = current_path(ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(p.is_absolute());
+ TEST_CHECK(is_directory(p));
+
+ const path p2 = current_path();
+ TEST_CHECK(p2 == p);
+}
+
+TEST_CASE(current_path_after_change_test)
+{
+ const path new_path = StaticEnv::Dir;
+ current_path(new_path);
+ TEST_CHECK(current_path() == new_path);
+}
+
+TEST_CASE(current_path_is_file_test)
+{
+ const path p = StaticEnv::File;
+ std::error_code ec;
+ const path old_p = current_path();
+ current_path(p, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(old_p == current_path());
+}
+
+TEST_CASE(set_to_non_absolute_path)
+{
+ const path base = StaticEnv::Dir;
+ current_path(base);
+ const path p = StaticEnv::Dir2.filename();
+ std::error_code ec;
+ current_path(p, ec);
+ TEST_CHECK(!ec);
+ const path new_cwd = current_path();
+ TEST_CHECK(new_cwd == StaticEnv::Dir2);
+ TEST_CHECK(new_cwd.is_absolute());
+}
+
+TEST_CASE(set_to_empty)
+{
+ const path p = "";
+ std::error_code ec;
+ const path old_p = current_path();
+ current_path(p, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(old_p == current_path());
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool equivalent(path const& lhs, path const& rhs);
+// bool equivalent(path const& lhs, path const& rhs, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(equivalent_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(equivalent(p, p, ec));
+ ASSERT_NOT_NOEXCEPT(equivalent(p, p));
+}
+
+TEST_CASE(equivalent_test)
+{
+ struct TestCase {
+ path lhs;
+ path rhs;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {StaticEnv::Dir, StaticEnv::Dir, true},
+ {StaticEnv::File, StaticEnv::Dir, false},
+ {StaticEnv::Dir, StaticEnv::SymlinkToDir, true},
+ {StaticEnv::Dir, StaticEnv::SymlinkToFile, false},
+ {StaticEnv::File, StaticEnv::File, true},
+ {StaticEnv::File, StaticEnv::SymlinkToFile, true},
+ };
+ for (auto& TC : testCases) {
+ std::error_code ec;
+ TEST_CHECK(equivalent(TC.lhs, TC.rhs, ec) == TC.expect);
+ TEST_CHECK(!ec);
+ }
+}
+
+TEST_CASE(equivalent_reports_double_dne)
+{
+ const path E = StaticEnv::File;
+ const path DNE = StaticEnv::DNE;
+ { // Test that no exception is thrown if one of the paths exists
+ TEST_CHECK(equivalent(E, DNE) == false);
+ TEST_CHECK(equivalent(DNE, E) == false);
+ }
+ { // Test that an exception is thrown if both paths do not exist.
+ TEST_CHECK_THROW(filesystem_error, equivalent(DNE, DNE));
+ }
+ {
+ std::error_code ec;
+ TEST_CHECK(equivalent(DNE, DNE, ec) == false);
+ TEST_CHECK(ec);
+ }
+}
+
+TEST_CASE(equivalent_is_other_succeeds)
+{
+ scoped_test_env env;
+ path const file = env.create_file("file", 42);
+ const path hl1 = env.create_hardlink(file, "hl1");
+ const path hl2 = env.create_hardlink(file, "hl2");
+ TEST_CHECK(equivalent(file, hl1));
+ TEST_CHECK(equivalent(file, hl2));
+ TEST_CHECK(equivalent(hl1, hl2));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool exists(file_status s) noexcept
+// bool exists(path const& p);
+// bool exists(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(exists_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(exists(s));
+ ASSERT_NOEXCEPT(exists(p, ec));
+ ASSERT_NOT_NOEXCEPT(exists(p));
+}
+
+TEST_CASE(exists_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, true},
+ {file_type::directory, true},
+ {file_type::symlink, true},
+ {file_type::block, true},
+ {file_type::character, true},
+ {file_type::fifo, true},
+ {file_type::socket, true},
+ {file_type::unknown, true}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(exists(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(exists(p) == false);
+}
+
+TEST_CASE(test_exists_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(exists(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, exists(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// uintmax_t file_size(const path& p);
+// uintmax_t file_size(const path& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(file_size_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(file_size(p)), uintmax_t);
+ ASSERT_SAME_TYPE(decltype(file_size(p, ec)), uintmax_t);
+ ASSERT_NOT_NOEXCEPT(file_size(p));
+ ASSERT_NOEXCEPT(file_size(p, ec));
+}
+
+TEST_CASE(file_size_empty_test)
+{
+ const path p = StaticEnv::EmptyFile;
+ TEST_CHECK(file_size(p) == 0);
+ std::error_code ec;
+ TEST_CHECK(file_size(p, ec) == 0);
+}
+
+TEST_CASE(file_size_non_empty)
+{
+ scoped_test_env env;
+ const path p = env.create_file("file", 42);
+ TEST_CHECK(file_size(p) == 42);
+ std::error_code ec;
+ TEST_CHECK(file_size(p, ec) == 42);
+}
+
+TEST_CASE(symlink_test_case)
+{
+ const path p = StaticEnv::File;
+ const path p2 = StaticEnv::SymlinkToFile;
+ TEST_CHECK(file_size(p) == file_size(p2));
+}
+
+TEST_CASE(file_size_error_cases)
+{
+ const path testCases[] = {
+ StaticEnv::Dir,
+ StaticEnv::SymlinkToDir,
+ StaticEnv::BadSymlink,
+ StaticEnv::DNE
+ };
+ const uintmax_t expect = static_cast<uintmax_t>(-1);
+ for (auto& TC : testCases) {
+ std::error_code ec;
+ TEST_CHECK(file_size(TC, ec) == expect);
+ TEST_CHECK(ec);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// uintmax_t hard_link_count(const path& p);
+// uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(hard_link_count_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(hard_link_count(p)), uintmax_t);
+ ASSERT_SAME_TYPE(decltype(hard_link_count(p, ec)), uintmax_t);
+ ASSERT_NOT_NOEXCEPT(hard_link_count(p));
+ ASSERT_NOEXCEPT(hard_link_count(p, ec));
+}
+
+TEST_CASE(hard_link_count_for_file)
+{
+ TEST_CHECK(hard_link_count(StaticEnv::File) == 1);
+ std::error_code ec;
+ TEST_CHECK(hard_link_count(StaticEnv::File, ec) == 1);
+}
+
+TEST_CASE(hard_link_count_for_directory)
+{
+ uintmax_t DirExpect = 3;
+ uintmax_t Dir3Expect = 2;
+#if defined(__APPLE__)
+ DirExpect += 2;
+ Dir3Expect += 1;
+#endif
+ TEST_CHECK(hard_link_count(StaticEnv::Dir) == DirExpect);
+ TEST_CHECK(hard_link_count(StaticEnv::Dir3) == Dir3Expect);
+
+ std::error_code ec;
+ TEST_CHECK(hard_link_count(StaticEnv::Dir, ec) == DirExpect);
+ TEST_CHECK(hard_link_count(StaticEnv::Dir3, ec) == Dir3Expect);
+}
+TEST_CASE(hard_link_count_increments_test)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ TEST_CHECK(hard_link_count(file) == 1);
+
+ env.create_hardlink(file, "file_hl");
+ TEST_CHECK(hard_link_count(file) == 2);
+}
+
+
+TEST_CASE(hard_link_count_error_cases)
+{
+ const path testCases[] = {
+ StaticEnv::BadSymlink,
+ StaticEnv::DNE
+ };
+ const uintmax_t expect = static_cast<uintmax_t>(-1);
+ for (auto& TC : testCases) {
+ std::error_code ec;
+ TEST_CHECK(hard_link_count(TC, ec) == expect);
+ TEST_CHECK(ec);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool is_block_file(file_status s) noexcept
+// bool is_block_file(path const& p);
+// bool is_block_file(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_block_file_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_block_file(s));
+ ASSERT_NOEXCEPT(is_block_file(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_block_file(p));
+}
+
+TEST_CASE(is_block_file_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, true},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_block_file(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_block_file(p) == false);
+}
+
+TEST_CASE(test_is_block_file_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_block_file(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_block_file(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool is_character_file(file_status s) noexcept
+// bool is_character_file(path const& p);
+// bool is_character_file(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_character_file_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_character_file(s));
+ ASSERT_NOEXCEPT(is_character_file(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_character_file(p));
+}
+
+TEST_CASE(is_character_file_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, true},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_character_file(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_character_file(p) == false);
+}
+
+TEST_CASE(test_is_character_file_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_character_file(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_character_file(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool is_directory(file_status s) noexcept
+// bool is_directory(path const& p);
+// bool is_directory(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_directory_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_directory(s));
+ ASSERT_NOEXCEPT(is_directory(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_directory(p));
+}
+
+TEST_CASE(is_directory_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, true},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_directory(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_directory(p) == false);
+}
+
+TEST_CASE(static_env_test)
+{
+ TEST_CHECK(is_directory(StaticEnv::Dir));
+ TEST_CHECK(is_directory(StaticEnv::SymlinkToDir));
+ TEST_CHECK(!is_directory(StaticEnv::File));
+}
+
+TEST_CASE(test_is_directory_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir2 = env.create_dir("dir/dir2");
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_directory(dir2, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_directory(dir2));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool is_empty(path const& p);
+// bool is_empty(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_empty_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_empty(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_empty(p));
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ std::error_code ec;
+ TEST_CHECK(is_empty(p, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK_THROW(filesystem_error, is_empty(p));
+}
+
+TEST_CASE(test_is_empty_directory)
+{
+ TEST_CHECK(!is_empty(StaticEnv::Dir));
+ TEST_CHECK(!is_empty(StaticEnv::SymlinkToDir));
+}
+
+TEST_CASE(test_is_empty_directory_dynamic)
+{
+ scoped_test_env env;
+ TEST_CHECK(is_empty(env.test_root));
+ env.create_file("foo", 42);
+ TEST_CHECK(!is_empty(env.test_root));
+}
+
+TEST_CASE(test_is_empty_file)
+{
+ TEST_CHECK(is_empty(StaticEnv::EmptyFile));
+ TEST_CHECK(!is_empty(StaticEnv::NonEmptyFile));
+}
+
+TEST_CASE(test_is_empty_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir2 = env.create_dir("dir/dir2");
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_empty(dir2, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_empty(dir2));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool is_fifo(file_status s) noexcept
+// bool is_fifo(path const& p);
+// bool is_fifo(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_fifo_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_fifo(s));
+ ASSERT_NOEXCEPT(is_fifo(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_fifo(p));
+}
+
+TEST_CASE(is_fifo_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, true},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_fifo(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_fifo(p) == false);
+}
+
+TEST_CASE(test_is_fifo_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_fifo(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_fifo(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool is_other(file_status s) noexcept
+// bool is_other(path const& p);
+// bool is_other(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_other_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_other(s));
+ ASSERT_NOEXCEPT(is_other(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_other(p));
+}
+
+TEST_CASE(is_other_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, true},
+ {file_type::character, true},
+ {file_type::fifo, true},
+ {file_type::socket, true},
+ {file_type::unknown, true}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_other(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_other(p) == false);
+}
+
+TEST_CASE(test_is_other_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_other(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_other(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool is_regular_file(file_status s) noexcept
+// bool is_regular_file(path const& p);
+// bool is_regular_file(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_regular_file_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_regular_file(s));
+ ASSERT_NOEXCEPT(is_regular_file(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_regular_file(p));
+}
+
+TEST_CASE(is_regular_file_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, true},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_regular_file(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_regular_file(p) == false);
+ std::error_code ec;
+ TEST_CHECK(is_regular_file(p, ec) == false);
+ TEST_CHECK(ec);
+}
+
+TEST_CASE(test_is_regular_file_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_regular_file(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_regular_file(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool is_socket(file_status s) noexcept
+// bool is_socket(path const& p);
+// bool is_socket(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_socket_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_socket(s));
+ ASSERT_NOEXCEPT(is_socket(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_socket(p));
+}
+
+TEST_CASE(is_socket_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, true},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_socket(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_socket(p) == false);
+}
+
+TEST_CASE(test_is_socket_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_socket(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_socket(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,105 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool is_symlink(file_status s) noexcept
+// bool is_symlink(path const& p);
+// bool is_symlink(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_symlink_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_symlink(s));
+ ASSERT_NOEXCEPT(is_symlink(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_symlink(p));
+}
+
+TEST_CASE(is_symlink_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, true},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_symlink(s) == TC.expect);
+ }
+}
+
+TEST_CASE(static_env_test)
+{
+ struct TestCase {
+ path p;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {StaticEnv::File, false},
+ {StaticEnv::Dir, false},
+ {StaticEnv::SymlinkToFile, true},
+ {StaticEnv::SymlinkToDir, true},
+ {StaticEnv::BadSymlink, true}
+ };
+ for (auto& TC : testCases) {
+ TEST_CHECK(is_symlink(TC.p) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_symlink(p) == false);
+ std::error_code ec;
+ TEST_CHECK(is_symlink(p, ec) == false);
+ TEST_CHECK(ec);
+}
+
+TEST_CASE(test_is_symlink_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_symlink(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_symlink(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,297 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// file_time_type last_write_time(const path& p);
+// file_time_type last_write_time(const path& p, std::error_code& ec) noexcept;
+// void last_write_time(const path& p, file_time_type new_time);
+// void last_write_time(const path& p, file_time_type new_type,
+// std::error_code& ec) noexcept;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <fstream>
+#include <iostream>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+#include <sys/stat.h>
+
+using namespace std::experimental::filesystem;
+
+
+std::pair<std::time_t, std::time_t> GetTimes(path const& p) {
+ using Clock = file_time_type::clock;
+ struct ::stat st;
+ if (::stat(p.c_str(), &st) == -1) {
+ std::error_code ec(errno, std::generic_category());
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ throw ec;
+#else
+ std::cerr << ec.message() << std::endl;
+ std::exit(EXIT_FAILURE);
+#endif
+ }
+ return {st.st_atime, st.st_mtime};
+}
+
+std::time_t LastAccessTime(path const& p) {
+ return GetTimes(p).first;
+}
+
+std::time_t LastWriteTime(path const& p) {
+ return GetTimes(p).second;
+}
+
+std::pair<std::time_t, std::time_t> GetSymlinkTimes(path const& p) {
+ using Clock = file_time_type::clock;
+ struct ::stat st;
+ if (::lstat(p.c_str(), &st) == -1) {
+ std::error_code ec(errno, std::generic_category());
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ throw ec;
+#else
+ std::cerr << ec.message() << std::endl;
+ std::exit(EXIT_FAILURE);
+#endif
+ }
+ return {st.st_atime, st.st_mtime};
+}
+
+
+TEST_SUITE(exists_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const file_time_type t;
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(last_write_time(p)), file_time_type);
+ ASSERT_SAME_TYPE(decltype(last_write_time(p, ec)), file_time_type);
+ ASSERT_SAME_TYPE(decltype(last_write_time(p, t)), void);
+ ASSERT_SAME_TYPE(decltype(last_write_time(p, t, ec)), void);
+ ASSERT_NOT_NOEXCEPT(last_write_time(p));
+ ASSERT_NOT_NOEXCEPT(last_write_time(p, t));
+ ASSERT_NOEXCEPT(last_write_time(p, ec));
+ ASSERT_NOEXCEPT(last_write_time(p, t, ec));
+}
+
+TEST_CASE(read_last_write_time_static_env_test)
+{
+ using C = file_time_type::clock;
+ file_time_type min = file_time_type::min();
+ {
+ file_time_type ret = last_write_time(StaticEnv::File);
+ TEST_CHECK(ret != min);
+ TEST_CHECK(ret < C::now());
+ TEST_CHECK(C::to_time_t(ret) == LastWriteTime(StaticEnv::File));
+
+ file_time_type ret2 = last_write_time(StaticEnv::SymlinkToFile);
+ TEST_CHECK(ret == ret2);
+ TEST_CHECK(C::to_time_t(ret2) == LastWriteTime(StaticEnv::SymlinkToFile));
+ }
+ {
+ file_time_type ret = last_write_time(StaticEnv::Dir);
+ TEST_CHECK(ret != min);
+ TEST_CHECK(ret < C::now());
+ TEST_CHECK(C::to_time_t(ret) == LastWriteTime(StaticEnv::Dir));
+
+ file_time_type ret2 = last_write_time(StaticEnv::SymlinkToDir);
+ TEST_CHECK(ret == ret2);
+ TEST_CHECK(C::to_time_t(ret2) == LastWriteTime(StaticEnv::SymlinkToDir));
+ }
+}
+
+TEST_CASE(get_last_write_time_dynamic_env_test)
+{
+ using Clock = file_time_type::clock;
+ using Sec = std::chrono::seconds;
+ scoped_test_env env;
+
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+
+ const auto file_times = GetTimes(file);
+ const std::time_t file_access_time = file_times.first;
+ const std::time_t file_write_time = file_times.second;
+ const auto dir_times = GetTimes(dir);
+ const std::time_t dir_access_time = dir_times.first;
+ const std::time_t dir_write_time = dir_times.second;
+
+ file_time_type ftime = last_write_time(file);
+ TEST_CHECK(Clock::to_time_t(ftime) == file_write_time);
+
+ file_time_type dtime = last_write_time(dir);
+ TEST_CHECK(Clock::to_time_t(dtime) == dir_write_time);
+
+ std::this_thread::sleep_for(Sec(2));
+
+ // update file and add a file to the directory. Make sure the times increase.
+ std::ofstream of(file, std::ofstream::app);
+ of << "hello";
+ of.close();
+ env.create_file("dir/file1", 1);
+
+ file_time_type ftime2 = last_write_time(file);
+ file_time_type dtime2 = last_write_time(dir);
+
+ TEST_CHECK(ftime2 > ftime);
+ TEST_CHECK(dtime2 > dtime);
+ TEST_CHECK(LastAccessTime(file) == file_access_time);
+ TEST_CHECK(LastAccessTime(dir) == dir_access_time);
+}
+
+
+TEST_CASE(set_last_write_time_dynamic_env_test)
+{
+ using Clock = file_time_type::clock;
+ using Sec = std::chrono::seconds;
+ using Hours = std::chrono::hours;
+ using Minutes = std::chrono::minutes;
+
+ scoped_test_env env;
+
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+
+ const file_time_type future_time = Clock::now() + Hours(3);
+ const file_time_type past_time = Clock::now() - Minutes(3);
+
+ struct TestCase {
+ path p;
+ file_time_type new_time;
+ } cases[] = {
+ {file, future_time},
+ {dir, future_time},
+ {file, past_time},
+ {dir, past_time}
+ };
+ for (const auto& TC : cases) {
+ const auto old_times = GetTimes(TC.p);
+
+ std::error_code ec = GetTestEC();
+ last_write_time(TC.p, TC.new_time, ec);
+ TEST_CHECK(!ec);
+
+ const std::time_t new_time_t = Clock::to_time_t(TC.new_time);
+ file_time_type got_time = last_write_time(TC.p);
+ std::time_t got_time_t = Clock::to_time_t(got_time);
+
+ TEST_CHECK(got_time_t != old_times.second);
+ TEST_CHECK(got_time_t == new_time_t);
+ TEST_CHECK(LastAccessTime(TC.p) == old_times.first);
+ }
+}
+
+TEST_CASE(last_write_time_symlink_test)
+{
+ using Clock = file_time_type::clock;
+ using Sec = std::chrono::seconds;
+ using Hours = std::chrono::hours;
+ using Minutes = std::chrono::minutes;
+
+ scoped_test_env env;
+
+ const path file = env.create_file("file", 42);
+ const path sym = env.create_symlink("file", "sym");
+
+ const file_time_type new_time = Clock::now() + Hours(3);
+
+ const auto old_times = GetTimes(sym);
+ const auto old_sym_times = GetSymlinkTimes(sym);
+
+ std::error_code ec = GetTestEC();
+ last_write_time(sym, new_time, ec);
+ TEST_CHECK(!ec);
+
+ const std::time_t new_time_t = Clock::to_time_t(new_time);
+ file_time_type got_time = last_write_time(sym);
+ std::time_t got_time_t = Clock::to_time_t(got_time);
+
+ TEST_CHECK(got_time_t != old_times.second);
+ TEST_CHECK(got_time_t == new_time_t);
+ TEST_CHECK(LastWriteTime(file) == new_time_t);
+ TEST_CHECK(LastAccessTime(sym) == old_times.first);
+ TEST_CHECK(GetSymlinkTimes(sym) == old_sym_times);
+}
+
+TEST_CASE(test_write_min_max_time)
+{
+ using Clock = file_time_type::clock;
+ using Sec = std::chrono::seconds;
+ using Hours = std::chrono::hours;
+ scoped_test_env env;
+ const path p = env.create_file("file", 42);
+
+ file_time_type last_time = last_write_time(p);
+
+ file_time_type new_time = file_time_type::min();
+ std::error_code ec = GetTestEC();
+ last_write_time(p, new_time, ec);
+ file_time_type tt = last_write_time(p);
+ if (ec) {
+ TEST_CHECK(ec != GetTestEC());
+ TEST_CHECK(tt == last_time);
+ } else {
+ file_time_type max_allowed = new_time + Sec(1);
+ TEST_CHECK(tt >= new_time);
+ TEST_CHECK(tt < max_allowed);
+ }
+
+ last_time = tt;
+ new_time = file_time_type::max();
+ ec = GetTestEC();
+ last_write_time(p, new_time, ec);
+
+ tt = last_write_time(p);
+ if (ec) {
+ TEST_CHECK(ec != GetTestEC());
+ TEST_CHECK(tt == last_time);
+ } else {
+ file_time_type min_allowed = new_time - Sec(1);
+ TEST_CHECK(tt > min_allowed);
+ TEST_CHECK(tt <= new_time);
+ }
+}
+
+TEST_CASE(test_value_on_failure)
+{
+ const path p = StaticEnv::DNE;
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(last_write_time(p, ec) == file_time_type::min());
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+}
+
+TEST_CASE(test_exists_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(last_write_time(file, ec) == file_time_type::min());
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+
+ TEST_CHECK_THROW(filesystem_error, last_write_time(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// void permissions(const path& p, perms prms);
+// void permissions(const path& p, perms prms, std::error_code& ec) noexcept;
+
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+using PR = fs::perms;
+
+TEST_SUITE(filesystem_permissions_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ const perms opts{}; ((void)opts);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::permissions(p, opts));
+ // Not noexcept because of narrow contract
+ ASSERT_NOT_NOEXCEPT(fs::permissions(p, opts, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, fs::perms opts, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::permissions(f, opts);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path dne_sym = env.create_symlink(dne, "dne_sym");
+ { // !exists
+ std::error_code ec;
+ fs::permissions(dne, fs::perms{}, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(dne, fs::perms{}, ec));
+ }
+ {
+ std::error_code ec;
+ fs::permissions(dne_sym, perms::resolve_symlinks, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(dne_sym, perms::resolve_symlinks, ec));
+ }
+}
+
+TEST_CASE(basic_permissions_test)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path dir = env.create_dir("dir1");
+ const path file_for_sym = env.create_file("file2", 42);
+ const path sym = env.create_symlink(file_for_sym, "sym");
+ const perms AP = perms::add_perms;
+ const perms RP = perms::remove_perms;
+ const perms RS = perms::resolve_symlinks;
+ struct TestCase {
+ path p;
+ perms set_perms;
+ perms expected;
+ } cases[] = {
+ // test file
+ {file, perms::owner_all, perms::owner_all},
+ {file, perms::group_all | AP, perms::owner_all | perms::group_all},
+ {file, perms::group_all | RP, perms::owner_all},
+ {file, perms::none, perms::none},
+ // test directory
+ {dir, perms::owner_all, perms::owner_all},
+ {dir, perms::group_all | AP, perms::owner_all | perms::group_all},
+ {dir, perms::group_all | RP, perms::owner_all},
+ {dir, perms::none, perms::none},
+ // test symlink with resolve symlinks on symlink
+ {sym, perms::owner_all | RS, perms::owner_all},
+ {sym, perms::group_all | AP | RS, perms::owner_all | perms::group_all},
+ {sym, perms::group_all | RP | RS, perms::owner_all},
+ {sym, perms::none | RS, perms::none}
+ };
+ for (auto const& TC : cases) {
+ TEST_CHECK(status(TC.p).permissions() != TC.expected);
+ // Set the error code to ensure it's cleared.
+ std::error_code ec = std::make_error_code(std::errc::bad_address);
+ permissions(TC.p, TC.set_perms, ec);
+ TEST_CHECK(!ec);
+ auto pp = status(TC.p).permissions();
+ TEST_CHECK(status(TC.p).permissions() == TC.expected);
+ }
+}
+
+TEST_CASE(test_no_resolve_symlink_on_symlink)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path sym = env.create_symlink(file, "sym");
+ const auto file_perms = status(file).permissions();
+
+ struct TestCase {
+ perms set_perms;
+ perms expected; // only expected on platform that support symlink perms.
+ } cases[] = {
+ {perms::owner_all, perms::owner_all},
+ {perms::group_all | perms::add_perms, perms::owner_all | perms::group_all},
+ {perms::owner_all | perms::remove_perms, perms::group_all},
+ };
+ for (auto const& TC : cases) {
+#if defined(__APPLE__) || defined(__FreeBSD__)
+ // On OS X symlink permissions are supported. We should get an empty
+ // error code and the expected permissions.
+ const auto expected_link_perms = TC.expected;
+ std::error_code expected_ec;
+#else
+ // On linux symlink permissions are not supported. The error code should
+ // be 'operation_not_supported' and the sylink permissions should be
+ // unchanged.
+ const auto expected_link_perms = symlink_status(sym).permissions();
+ std::error_code expected_ec = std::make_error_code(std::errc::operation_not_supported);
+#endif
+ std::error_code ec = std::make_error_code(std::errc::bad_address);
+ permissions(sym, TC.set_perms, ec);
+ TEST_CHECK(ec == expected_ec);
+ TEST_CHECK(status(file).permissions() == file_perms);
+ TEST_CHECK(symlink_status(sym).permissions() == expected_link_perms);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// path read_symlink(const path& p);
+// path read_symlink(const path& p, error_code& ec);
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_read_symlink_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::read_symlink(p)), fs::path);
+ ASSERT_SAME_TYPE(decltype(fs::read_symlink(p, ec)), fs::path);
+
+ ASSERT_NOT_NOEXCEPT(fs::read_symlink(p));
+ // Not noexcept because of narrow contract
+ ASSERT_NOT_NOEXCEPT(fs::read_symlink(p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::read_symlink(f);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path cases[] = {
+ env.make_env_path("dne"),
+ env.create_file("file", 42),
+ env.create_dir("dir")
+ };
+ for (path const& p : cases) {
+ std::error_code ec;
+ const path ret = fs::read_symlink(p, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(ret == path{});
+ TEST_CHECK(checkThrow(p, ec));
+ }
+
+}
+
+TEST_CASE(basic_symlink_test)
+{
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+ const path link = env.create_symlink(dne, "link");
+ const path nested_link = env.make_env_path("nested_link");
+ create_symlink(link, nested_link);
+ struct TestCase {
+ path symlink;
+ path expected;
+ } testCases[] = {
+ {env.create_symlink(dne, "dne_link"), dne},
+ {env.create_symlink(file, "file_link"), file},
+ {env.create_symlink(dir, "dir_link"), dir},
+ {nested_link, link}
+ };
+ for (auto& TC : testCases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ const path ret = read_symlink(TC.symlink, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ret == TC.expected);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool remove(const path& p);
+// bool remove(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_remove_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::remove(p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::remove(p, ec)), bool);
+
+ ASSERT_NOT_NOEXCEPT(fs::remove(p));
+ ASSERT_NOEXCEPT(fs::remove(p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::remove(f);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ scoped_test_env env;
+ const path non_empty_dir = env.create_dir("dir");
+ env.create_file(non_empty_dir / "file1", 42);
+ const path bad_perms_dir = env.create_dir("bad_dir");
+ const path file_in_bad_dir = env.create_file(bad_perms_dir / "file", 42);
+ permissions(bad_perms_dir, perms::none);
+ const path testCases[] = {
+ "",
+ env.make_env_path("dne"),
+ non_empty_dir,
+ file_in_bad_dir,
+ };
+ for (auto& p : testCases) {
+ std::error_code ec;
+ TEST_CHECK(!fs::remove(p, ec));
+ TEST_CHECK(ec);
+ TEST_CHECK(checkThrow(p, ec));
+ }
+}
+
+TEST_CASE(basic_remove_test)
+{
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path link = env.create_symlink(dne, "link");
+ const path nested_link = env.make_env_path("nested_link");
+ create_symlink(link, nested_link);
+ const path testCases[] = {
+ env.create_file("file", 42),
+ env.create_dir("empty_dir"),
+ nested_link,
+ link
+ };
+ for (auto& p : testCases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ TEST_CHECK(remove(p, ec));
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(symlink_status(p)));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,141 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// uintmax_t remove_all(const path& p);
+// uintmax_t remove_all(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_remove_all_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::remove_all(p)), std::uintmax_t);
+ ASSERT_SAME_TYPE(decltype(fs::remove_all(p, ec)), std::uintmax_t);
+
+ ASSERT_NOT_NOEXCEPT(fs::remove_all(p));
+ ASSERT_NOEXCEPT(fs::remove_all(p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::remove_all(f);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ scoped_test_env env;
+ const path non_empty_dir = env.create_dir("dir");
+ env.create_file(non_empty_dir / "file1", 42);
+ const path bad_perms_dir = env.create_dir("bad_dir");
+ const path file_in_bad_dir = env.create_file(bad_perms_dir / "file", 42);
+ permissions(bad_perms_dir, perms::none);
+ const path bad_perms_file = env.create_file("file2", 42);
+ permissions(bad_perms_file, perms::none);
+
+ const path testCases[] = {
+ env.make_env_path("dne"),
+ file_in_bad_dir
+ };
+ const auto BadRet = static_cast<std::uintmax_t>(-1);
+ for (auto& p : testCases) {
+ std::error_code ec;
+ TEST_CHECK(fs::remove_all(p, ec) == BadRet);
+ TEST_CHECK(ec);
+ TEST_CHECK(checkThrow(p, ec));
+ }
+}
+
+TEST_CASE(basic_remove_all_test)
+{
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path link = env.create_symlink(dne, "link");
+ const path nested_link = env.make_env_path("nested_link");
+ create_symlink(link, nested_link);
+ const path testCases[] = {
+ env.create_file("file", 42),
+ env.create_dir("empty_dir"),
+ nested_link,
+ link
+ };
+ for (auto& p : testCases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ TEST_CHECK(remove(p, ec));
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(symlink_status(p)));
+ }
+}
+
+TEST_CASE(symlink_to_dir)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file(dir / "file", 42);
+ const path link = env.create_symlink(dir, "sym");
+
+ {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ TEST_CHECK(remove_all(link, ec) == 1);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(symlink_status(link)));
+ TEST_CHECK(exists(dir));
+ TEST_CHECK(exists(file));
+ }
+}
+
+
+TEST_CASE(nested_dir)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir1 = env.create_dir(dir / "dir1");
+ const path out_of_dir_file = env.create_file("file1", 42);
+ const path all_files[] = {
+ dir, dir1,
+ env.create_file(dir / "file1", 42),
+ env.create_symlink(out_of_dir_file, dir / "sym1"),
+ env.create_file(dir1 / "file2", 42),
+ env.create_symlink(dir, dir1 / "sym2")
+ };
+ const std::size_t expected_count = sizeof(all_files) / sizeof(all_files[0]);
+
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ TEST_CHECK(remove_all(dir, ec) == expected_count);
+ TEST_CHECK(!ec);
+ for (auto const& p : all_files) {
+ TEST_CHECK(!exists(symlink_status(p)));
+ }
+ TEST_CHECK(exists(out_of_dir_file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// void rename(const path& old_p, const path& new_p);
+// void rename(const path& old_p, const path& new_p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_rename_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::rename(p, p)), void);
+ ASSERT_SAME_TYPE(decltype(fs::rename(p, p, ec)), void);
+
+ ASSERT_NOT_NOEXCEPT(fs::rename(p, p));
+ ASSERT_NOEXCEPT(fs::rename(p, p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::rename(f, t);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == t
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path file = env.create_file("file1", 42);
+ const path dir = env.create_dir("dir1");
+ struct TestCase {
+ path from;
+ path to;
+ } cases[] = {
+ {dne, dne},
+ {file, dir},
+ {dir, file}
+ };
+ for (auto& TC : cases) {
+ auto from_before = status(TC.from);
+ auto to_before = status(TC.to);
+ std::error_code ec;
+ rename(TC.from, TC.to, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(from_before.type() == status(TC.from).type());
+ TEST_CHECK(to_before.type() == status(TC.to).type());
+ TEST_CHECK(checkThrow(TC.from, TC.to, ec));
+ }
+}
+
+TEST_CASE(basic_rename_test)
+{
+ scoped_test_env env;
+
+ const std::error_code set_ec = std::make_error_code(std::errc::address_in_use);
+ const path file = env.create_file("file1", 42);
+ { // same file
+ std::error_code ec = set_ec;
+ rename(file, file, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_regular_file(file));
+ TEST_CHECK(file_size(file) == 42);
+ }
+ const path sym = env.create_symlink(file, "sym");
+ { // file -> symlink
+ std::error_code ec = set_ec;
+ rename(file, sym, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(file));
+ TEST_CHECK(is_regular_file(symlink_status(sym)));
+ TEST_CHECK(file_size(sym) == 42);
+ }
+ const path file2 = env.create_file("file2", 42);
+ const path file3 = env.create_file("file3", 100);
+ { // file -> file
+ std::error_code ec = set_ec;
+ rename(file2, file3, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(file2));
+ TEST_CHECK(is_regular_file(file3));
+ TEST_CHECK(file_size(file3) == 42);
+ }
+ const path dne = env.make_env_path("dne");
+ const path bad_sym = env.create_symlink(dne, "bad_sym");
+ const path bad_sym_dest = env.make_env_path("bad_sym2");
+ { // bad-symlink
+ std::error_code ec = set_ec;
+ rename(bad_sym, bad_sym_dest, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(symlink_status(bad_sym)));
+ TEST_CHECK(is_symlink(bad_sym_dest));
+ TEST_CHECK(read_symlink(bad_sym_dest) == dne);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// void resize_file(const path& p, uintmax_t new_size);
+// void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_resize_file_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::uintmax_t i; ((void)i);
+ std::error_code ec; ((void)ec);
+
+ ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i)), void);
+ ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i, ec)), void);
+
+ ASSERT_NOT_NOEXCEPT(fs::resize_file(p, i));
+ ASSERT_NOEXCEPT(fs::resize_file(p, i, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, std::uintmax_t s, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::resize_file(f, s);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path bad_sym = env.create_symlink(dne, "sym");
+ const path dir = env.create_dir("dir1");
+ const path cases[] = {
+ dne, bad_sym, dir
+ };
+ for (auto& p : cases) {
+ std::error_code ec;
+ resize_file(p, 42, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(p, 42, ec));
+ }
+}
+
+TEST_CASE(basic_resize_file_test)
+{
+ scoped_test_env env;
+ const path file1 = env.create_file("file1", 42);
+ const auto set_ec = std::make_error_code(std::errc::address_in_use);
+ { // grow file
+ const std::uintmax_t new_s = 100;
+ std::error_code ec = set_ec;
+ resize_file(file1, new_s, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file1) == new_s);
+ }
+ { // shrink file
+ const std::uintmax_t new_s = 1;
+ std::error_code ec = set_ec;
+ resize_file(file1, new_s, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file1) == new_s);
+ }
+ { // shrink file to zero
+ const std::uintmax_t new_s = 0;
+ std::error_code ec = set_ec;
+ resize_file(file1, new_s, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file1) == new_s);
+ }
+ const path sym = env.create_symlink(file1, "sym");
+ { // grow file via symlink
+ const std::uintmax_t new_s = 1024;
+ std::error_code ec = set_ec;
+ resize_file(sym, new_s, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file1) == new_s);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// space_info space(const path& p);
+// space_info space(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <sys/statvfs.h>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+bool EqualDelta(std::uintmax_t x, std::uintmax_t y, std::uintmax_t delta) {
+ if (x >= y) {
+ return (x - y) <= delta;
+ } else {
+ return (y - x) <= delta;
+ }
+}
+
+TEST_SUITE(filesystem_space_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(space(p)), space_info);
+ ASSERT_SAME_TYPE(decltype(space(p, ec)), space_info);
+ ASSERT_NOT_NOEXCEPT(space(p));
+ ASSERT_NOEXCEPT(space(p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ space(f);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ const path cases[] = {
+ "",
+ StaticEnv::DNE,
+ StaticEnv::BadSymlink
+ };
+ for (auto& p : cases) {
+ const auto expect = static_cast<std::uintmax_t>(-1);
+ std::error_code ec;
+ space_info info = space(p, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(info.capacity == expect);
+ TEST_CHECK(info.free == expect);
+ TEST_CHECK(info.available == expect);
+ TEST_CHECK(checkThrow(p, ec));
+ }
+}
+
+TEST_CASE(basic_space_test)
+{
+ // All the test cases should reside on the same filesystem and therefore
+ // should have the same expected result. Compute this expected result
+ // one and check that it looks semi-sane.
+ struct statvfs expect;
+ TEST_REQUIRE(::statvfs(StaticEnv::Dir.c_str(), &expect) != -1);
+ TEST_CHECK(expect.f_bavail > 0);
+ TEST_CHECK(expect.f_bfree > 0);
+ TEST_CHECK(expect.f_bsize > 0);
+ TEST_CHECK(expect.f_blocks > 0);
+ const std::uintmax_t expect_cap = expect.f_blocks * expect.f_frsize;
+ // Other processes running on the operating system may have changed
+ // the amount of space available. Check that these are within tolerances.
+ // Currently 5% of capacity
+ const std::uintmax_t delta = expect_cap / 20;
+ const path cases[] = {
+ StaticEnv::File,
+ StaticEnv::Dir,
+ StaticEnv::Dir2,
+ StaticEnv::SymlinkToFile,
+ StaticEnv::SymlinkToDir
+ };
+ for (auto& p : cases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ space_info info = space(p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK((expect.f_blocks * expect.f_frsize) == info.capacity);
+ TEST_CHECK(EqualDelta((expect.f_bfree * expect.f_frsize), info.free, delta));
+ TEST_CHECK(EqualDelta((expect.f_bavail * expect.f_frsize), info.available, delta));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,159 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// file_status status(const path& p);
+// file_status status(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_status_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(status(p));
+ ASSERT_NOEXCEPT(status(p, ec));
+}
+
+TEST_CASE(test_status_not_found)
+{
+ const std::error_code expect_ec =
+ std::make_error_code(std::errc::no_such_file_or_directory);
+ const path cases[] {
+ StaticEnv::DNE,
+ StaticEnv::BadSymlink
+ };
+ for (auto& p : cases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ // test non-throwing overload.
+ file_status st = status(p, ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(st.type() == file_type::not_found);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ // test throwing overload. It should not throw even though it reports
+ // that the file was not found.
+ TEST_CHECK_NO_THROW(st = status(p));
+ TEST_CHECK(st.type() == file_type::not_found);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ }
+}
+
+TEST_CASE(test_status_cannot_resolve)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path sym = env.create_symlink("dir/file", "sym");
+ permissions(dir, perms::none);
+
+ const std::error_code set_ec =
+ std::make_error_code(std::errc::address_in_use);
+ const std::error_code expect_ec =
+ std::make_error_code(std::errc::permission_denied);
+
+ const path cases[] = {
+ file, sym
+ };
+ for (auto& p : cases)
+ {
+ { // test non-throwing case
+ std::error_code ec = set_ec;
+ file_status st = status(p, ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(st.type() == file_type::none);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ { // test throwing case
+ try {
+ status(p);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ TEST_CHECK(err.path2() == "");
+ TEST_CHECK(err.code() == expect_ec);
+ }
+ }
+#endif
+ }
+}
+
+TEST_CASE(status_file_types_test)
+{
+ scoped_test_env env;
+ struct TestCase {
+ path p;
+ file_type expect_type;
+ } cases[] = {
+ {StaticEnv::File, file_type::regular},
+ {StaticEnv::SymlinkToFile, file_type::regular},
+ {StaticEnv::Dir, file_type::directory},
+ {StaticEnv::SymlinkToDir, file_type::directory},
+ // Block files tested elsewhere
+ {StaticEnv::CharFile, file_type::character},
+#if !defined(__APPLE__) && !defined(__FreeBSD__) // No support for domain sockets
+ {env.create_socket("socket"), file_type::socket},
+#endif
+ {env.create_fifo("fifo"), file_type::fifo}
+ };
+ for (const auto& TC : cases) {
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = status(TC.p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == TC.expect_type);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = status(TC.p));
+ TEST_CHECK(st.type() == TC.expect_type);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+}
+
+TEST_CASE(test_block_file)
+{
+ const path possible_paths[] = {
+ "/dev/drive0", // Apple
+ "/dev/sda",
+ "/dev/loop0"
+ };
+ path p;
+ for (const path& possible_p : possible_paths) {
+ std::error_code ec;
+ if (exists(possible_p, ec)) {
+ p = possible_p;
+ break;
+ }
+ }
+ if (p == path{}) {
+ TEST_UNSUPPORTED();
+ }
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = status(p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == file_type::block);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = status(p));
+ TEST_CHECK(st.type() == file_type::block);
+ TEST_CHECK(st.permissions() != perms::unknown);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// bool status_known(file_status s) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(status_known_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ ASSERT_SAME_TYPE(decltype(status_known(s)), bool);
+ ASSERT_NOEXCEPT(status_known(s));
+}
+
+TEST_CASE(status_known_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, true},
+ {file_type::regular, true},
+ {file_type::directory, true},
+ {file_type::symlink, true},
+ {file_type::block, true},
+ {file_type::character, true},
+ {file_type::fifo, true},
+ {file_type::socket, true},
+ {file_type::unknown, true}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(status_known(s) == TC.expect);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,192 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// file_status symlink_status(const path& p);
+// file_status symlink_status(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_symlink_status_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(symlink_status(p));
+ ASSERT_NOEXCEPT(symlink_status(p, ec));
+}
+
+TEST_CASE(test_symlink_status_not_found)
+{
+ const std::error_code expect_ec =
+ std::make_error_code(std::errc::no_such_file_or_directory);
+ const path cases[] {
+ StaticEnv::DNE
+ };
+ for (auto& p : cases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ // test non-throwing overload.
+ file_status st = symlink_status(p, ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(st.type() == file_type::not_found);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ // test throwing overload. It should not throw even though it reports
+ // that the file was not found.
+ TEST_CHECK_NO_THROW(st = status(p));
+ TEST_CHECK(st.type() == file_type::not_found);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ }
+}
+
+TEST_CASE(test_symlink_status_cannot_resolve)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file_in_dir = env.create_file("dir/file", 42);
+ const path sym_in_dir = env.create_symlink("dir/file", "dir/bad_sym");
+ const path sym_points_in_dir = env.create_symlink("dir/file", "sym");
+ permissions(dir, perms::none);
+
+ const std::error_code set_ec =
+ std::make_error_code(std::errc::address_in_use);
+ const std::error_code expect_ec =
+ std::make_error_code(std::errc::permission_denied);
+
+ const path fail_cases[] = {
+ file_in_dir, sym_in_dir
+ };
+ for (auto& p : fail_cases)
+ {
+ { // test non-throwing case
+ std::error_code ec = set_ec;
+ file_status st = symlink_status(p, ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(st.type() == file_type::none);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ { // test throwing case
+ try {
+ symlink_status(p);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ TEST_CHECK(err.path2() == "");
+ TEST_CHECK(err.code() == expect_ec);
+ }
+ }
+#endif
+ }
+ // Test that a symlink that points into a directory without read perms
+ // can be stat-ed using symlink_status
+ {
+ std::error_code ec = set_ec;
+ file_status st = symlink_status(sym_points_in_dir, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == file_type::symlink);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test non-throwing version
+ TEST_REQUIRE_NO_THROW(st = symlink_status(sym_points_in_dir));
+ TEST_CHECK(st.type() == file_type::symlink);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+}
+
+
+TEST_CASE(symlink_status_file_types_test)
+{
+ scoped_test_env env;
+ struct TestCase {
+ path p;
+ file_type expect_type;
+ } cases[] = {
+ {StaticEnv::BadSymlink, file_type::symlink},
+ {StaticEnv::File, file_type::regular},
+ {StaticEnv::SymlinkToFile, file_type::symlink},
+ {StaticEnv::Dir, file_type::directory},
+ {StaticEnv::SymlinkToDir, file_type::symlink},
+ // Block files tested elsewhere
+ {StaticEnv::CharFile, file_type::character},
+#if !defined(__APPLE__) && !defined(__FreeBSD__) // No support for domain sockets
+ {env.create_socket("socket"), file_type::socket},
+#endif
+ {env.create_fifo("fifo"), file_type::fifo}
+ };
+ for (const auto& TC : cases) {
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = symlink_status(TC.p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == TC.expect_type);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = symlink_status(TC.p));
+ TEST_CHECK(st.type() == TC.expect_type);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+}
+
+TEST_CASE(test_block_file)
+{
+ const path possible_paths[] = {
+ "/dev/drive0", // Apple
+ "/dev/sda", // Linux
+ "/dev/loop0" // Linux
+ // No FreeBSD files known
+ };
+ path p;
+ for (const path& possible_p : possible_paths) {
+ std::error_code ec;
+ if (exists(possible_p, ec)) {
+ p = possible_p;
+ break;
+ }
+ }
+ if (p == path{}) {
+ TEST_UNSUPPORTED();
+ }
+ scoped_test_env env;
+ { // test block file
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = symlink_status(p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == file_type::block);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = symlink_status(p));
+ TEST_CHECK(st.type() == file_type::block);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+ const path sym = env.make_env_path("sym");
+ create_symlink(p, sym);
+ { // test symlink to block file
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = symlink_status(sym, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == file_type::symlink);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = symlink_status(sym));
+ TEST_CHECK(st.type() == file_type::symlink);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// path system_complete(const path& p);
+// path system_complete(const path& p, error_code& ec);
+
+// Note: For POSIX based operating systems, 'system_complete(p)' has the
+// same semantics as 'absolute(p, current_path())'.
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_system_complete_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(system_complete(p));
+ ASSERT_NOT_NOEXCEPT(system_complete(p, ec));
+}
+
+
+TEST_CASE(basic_system_complete_tests)
+{
+ const path testCases[] = {
+ "//net/foo", // has_root_name() && has_root_directory()
+ "/foo", // !has_root_name() && has_root_directory()
+ "//net", // has_root_name() && !has_root_directory()
+ "bar/baz" // !has_root_name() && !has_root_directory()
+ };
+ const path base = current_path();
+ for (auto& p : testCases) {
+ const path ret = system_complete(p);
+ const path expect = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == expect);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// path temp_directory_path();
+// path temp_directory_path(error_code& ec);
+
+#include <experimental/filesystem>
+#include <memory>
+#include <cstdlib>
+#include <cstring>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+void PutEnv(std::string var, std::string value) {
+ assert(::setenv(var.c_str(), value.c_str(), /* overwrite */ 1) == 0);
+}
+
+void UnsetEnv(std::string var) {
+ assert(::unsetenv(var.c_str()) == 0);
+}
+
+TEST_SUITE(filesystem_temp_directory_path_test_suite)
+
+TEST_CASE(signature_test)
+{
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(temp_directory_path());
+ ASSERT_NOT_NOEXCEPT(temp_directory_path(ec));
+}
+
+TEST_CASE(basic_tests)
+{
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path file = env.create_file("file", 42);
+ const path dir_perms = env.create_dir("bad_perms_dir");
+ const path nested_dir = env.create_dir("bad_perms_dir/nested");
+ permissions(dir_perms, perms::none);
+ const std::error_code set_ec = std::make_error_code(std::errc::address_in_use);
+ const std::error_code expect_ec = std::make_error_code(std::errc::not_a_directory);
+ struct TestCase {
+ std::string name;
+ path p;
+ } cases[] = {
+ {"TMPDIR", env.create_dir("dir1")},
+ {"TMP", env.create_dir("dir2")},
+ {"TEMP", env.create_dir("dir3")},
+ {"TEMPDIR", env.create_dir("dir4")}
+ };
+ for (auto& TC : cases) {
+ PutEnv(TC.name, TC.p);
+ }
+ for (auto& TC : cases) {
+ std::error_code ec = set_ec;
+ path ret = temp_directory_path(ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ret == TC.p);
+ TEST_CHECK(is_directory(ret));
+
+ // Set the env variable to a path that does not exist and check
+ // that it fails.
+ PutEnv(TC.name, dne);
+ ec = set_ec;
+ ret = temp_directory_path(ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(ret == "");
+
+ // Set the env variable to point to a file and check that it fails.
+ PutEnv(TC.name, file);
+ ec = set_ec;
+ ret = temp_directory_path(ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(ret == "");
+
+ // Set the env variable to point to a dir we can't access
+ PutEnv(TC.name, nested_dir);
+ ec = set_ec;
+ ret = temp_directory_path(ec);
+ TEST_CHECK(ec == std::make_error_code(std::errc::permission_denied));
+ TEST_CHECK(ret == "");
+
+ // Finally erase this env variable
+ UnsetEnv(TC.name);
+ }
+ // No env variables are defined
+ {
+ std::error_code ec = set_ec;
+ path ret = temp_directory_path(ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ret == "/tmp");
+ TEST_CHECK(is_directory(ret));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// #define __cpp_lib_experimental_filesystem 201406L
+
+#include <experimental/filesystem>
+
+#ifndef __cpp_lib_experimental_filesystem
+#error Filesystem feature test macro is not defined (__cpp_lib_experimental_filesystem)
+#elif __cpp_lib_experimental_filesystem != 201406L
+#error Filesystem feature test macro has an incorrect value (__cpp_lib_experimental_filesystem)
+#endif
+
+int main() { }
Added: libcxx/trunk/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/filesystem>
+
+// namespace std::experimental::filesystem::v1
+
+#include <experimental/filesystem>
+#include <type_traits>
+
+int main() {
+ static_assert(std::is_same<
+ std::experimental::filesystem::path,
+ std::experimental::filesystem::v1::path
+ >::value, "");
+}
Added: libcxx/trunk/test/std/experimental/filesystem/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/lit.local.cfg?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/lit.local.cfg (added)
+++ libcxx/trunk/test/std/experimental/filesystem/lit.local.cfg Fri Jun 17 14:46:40 2016
@@ -0,0 +1,3 @@
+# Disable all of the filesystem tests if the correct feature is not available.
+if 'c++filesystem' not in config.available_features:
+ config.unsupported = True
Modified: libcxx/trunk/test/support/count_new.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/count_new.hpp?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/test/support/count_new.hpp (original)
+++ libcxx/trunk/test/support/count_new.hpp Fri Jun 17 14:46:40 2016
@@ -130,6 +130,11 @@ public:
return disable_checking || n != new_called;
}
+ bool checkNewCalledGreaterThan(int n) const
+ {
+ return disable_checking || new_called > n;
+ }
+
bool checkDeleteCalledEq(int n) const
{
return disable_checking || n == delete_called;
@@ -253,4 +258,33 @@ private:
DisableAllocationGuard& operator=(DisableAllocationGuard const&);
};
+
+struct RequireAllocationGuard {
+ explicit RequireAllocationGuard(std::size_t RequireAtLeast = 1)
+ : m_req_alloc(RequireAtLeast),
+ m_new_count_on_init(globalMemCounter.new_called),
+ m_outstanding_new_on_init(globalMemCounter.outstanding_new),
+ m_exactly(false)
+ {
+ }
+
+ void requireAtLeast(std::size_t N) { m_req_alloc = N; m_exactly = false; }
+ void requireExactly(std::size_t N) { m_req_alloc = N; m_exactly = true; }
+
+ ~RequireAllocationGuard() {
+ assert(globalMemCounter.checkOutstandingNewEq(m_outstanding_new_on_init));
+ std::size_t Expect = m_new_count_on_init + m_req_alloc;
+ assert(globalMemCounter.checkNewCalledEq(Expect) ||
+ (!m_exactly && globalMemCounter.checkNewCalledGreaterThan(Expect)));
+ }
+
+private:
+ std::size_t m_req_alloc;
+ const std::size_t m_new_count_on_init;
+ const std::size_t m_outstanding_new_on_init;
+ bool m_exactly;
+ RequireAllocationGuard(RequireAllocationGuard const&);
+ RequireAllocationGuard& operator=(RequireAllocationGuard const&);
+};
+
#endif /* COUNT_NEW_HPP */
Added: libcxx/trunk/test/support/filesystem_dynamic_test_helper.py
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/filesystem_dynamic_test_helper.py?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/support/filesystem_dynamic_test_helper.py (added)
+++ libcxx/trunk/test/support/filesystem_dynamic_test_helper.py Fri Jun 17 14:46:40 2016
@@ -0,0 +1,85 @@
+import sys
+import os
+import stat
+
+# Ensure that this is being run on a specific platform
+assert sys.platform.startswith('linux') or sys.platform.startswith('darwin') \
+ or sys.platform.startswith('cygwin') or sys.platform.startswith('freebsd')
+
+def env_path():
+ ep = os.environ.get('LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT')
+ assert ep is not None
+ ep = os.path.realpath(ep)
+ assert os.path.isdir(ep)
+ return ep
+
+env_path_global = env_path()
+
+# Make sure we don't try and write outside of env_path.
+# All paths used should be sanitized
+def sanitize(p):
+ p = os.path.realpath(p)
+ if os.path.commonprefix([env_path_global, p]):
+ return p
+ assert False
+
+"""
+Some of the tests restrict permissions to induce failures.
+Before we delete the test enviroment, we have to walk it and re-raise the
+permissions.
+"""
+def clean_recursive(root_p):
+ if not os.path.islink(root_p):
+ os.chmod(root_p, 0o777)
+ for ent in os.listdir(root_p):
+ p = os.path.join(root_p, ent)
+ if os.path.islink(p) or not os.path.isdir(p):
+ os.remove(p)
+ else:
+ assert os.path.isdir(p)
+ clean_recursive(p)
+ os.rmdir(p)
+
+
+def init_test_directory(root_p):
+ root_p = sanitize(root_p)
+ assert not os.path.exists(root_p)
+ os.makedirs(root_p)
+
+
+def destroy_test_directory(root_p):
+ root_p = sanitize(root_p)
+ clean_recursive(root_p)
+ os.rmdir(root_p)
+
+
+def create_file(fname, size):
+ with open(sanitize(fname), 'w') as f:
+ f.write('c' * size)
+
+
+def create_dir(dname):
+ os.mkdir(sanitize(dname))
+
+
+def create_symlink(source, link):
+ os.symlink(sanitize(source), sanitize(link))
+
+
+def create_hardlink(source, link):
+ os.link(sanitize(source), sanitize(link))
+
+
+def create_fifo(source):
+ os.mkfifo(sanitize(source))
+
+
+def create_socket(source):
+ mode = 0600|stat.S_IFSOCK
+ os.mknod(sanitize(source), mode)
+
+
+if __name__ == '__main__':
+ command = " ".join(sys.argv[1:])
+ eval(command)
+ sys.exit(0)
Added: libcxx/trunk/test/support/filesystem_test_helper.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/filesystem_test_helper.hpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/support/filesystem_test_helper.hpp (added)
+++ libcxx/trunk/test/support/filesystem_test_helper.hpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,370 @@
+#ifndef FILESYSTEM_TEST_HELPER_HPP
+#define FILESYSTEM_TEST_HELPER_HPP
+
+#include <experimental/filesystem>
+#include <cassert>
+#include <cstdio> // for printf
+#include <string>
+#include <fstream>
+#include <random>
+
+namespace fs = std::experimental::filesystem;
+
+// static test helpers
+
+#ifndef LIBCXX_FILESYSTEM_STATIC_TEST_ROOT
+#warning "STATIC TESTS DISABLED"
+#else // LIBCXX_FILESYSTEM_STATIC_TEST_ROOT
+
+namespace StaticEnv {
+
+inline fs::path makePath(fs::path const& p) {
+ static const fs::path env_path = LIBCXX_FILESYSTEM_STATIC_TEST_ROOT;
+ return env_path / p;
+}
+
+static const fs::path Root = LIBCXX_FILESYSTEM_STATIC_TEST_ROOT;
+
+static const fs::path TestFileList[] = {
+ makePath("empty_file"),
+ makePath("non_empty_file"),
+ makePath("dir1/file1"),
+ makePath("dir1/file2")
+};
+const std::size_t TestFileListSize = sizeof(TestFileList) / sizeof(fs::path);
+
+static const fs::path TestDirList[] = {
+ makePath("dir1"),
+ makePath("dir1/dir2"),
+ makePath("dir1/dir2/dir3")
+};
+const std::size_t TestDirListSize = sizeof(TestDirList) / sizeof(fs::path);
+
+static const fs::path File = TestFileList[0];
+static const fs::path Dir = TestDirList[0];
+static const fs::path Dir2 = TestDirList[1];
+static const fs::path Dir3 = TestDirList[2];
+static const fs::path SymlinkToFile = makePath("symlink_to_empty_file");
+static const fs::path SymlinkToDir = makePath("symlink_to_dir");
+static const fs::path BadSymlink = makePath("bad_symlink");
+static const fs::path DNE = makePath("DNE");
+static const fs::path EmptyFile = TestFileList[0];
+static const fs::path NonEmptyFile = TestFileList[1];
+static const fs::path CharFile = "/dev/null"; // Hopefully this exists
+
+static const fs::path DirIterationList[] = {
+ makePath("dir1/dir2"),
+ makePath("dir1/file1"),
+ makePath("dir1/file2")
+};
+const std::size_t DirIterationListSize = sizeof(DirIterationList)
+ / sizeof(fs::path);
+
+static const fs::path DirIterationListDepth1[] = {
+ makePath("dir1/dir2/afile3"),
+ makePath("dir1/dir2/dir3"),
+ makePath("dir1/dir2/symlink_to_dir3"),
+ makePath("dir1/dir2/file4"),
+};
+
+static const fs::path RecDirIterationList[] = {
+ makePath("dir1/dir2"),
+ makePath("dir1/file1"),
+ makePath("dir1/file2"),
+ makePath("dir1/dir2/afile3"),
+ makePath("dir1/dir2/dir3"),
+ makePath("dir1/dir2/symlink_to_dir3"),
+ makePath("dir1/dir2/file4"),
+ makePath("dir1/dir2/dir3/file5")
+};
+
+static const fs::path RecDirFollowSymlinksIterationList[] = {
+ makePath("dir1/dir2"),
+ makePath("dir1/file1"),
+ makePath("dir1/file2"),
+ makePath("dir1/dir2/afile3"),
+ makePath("dir1/dir2/dir3"),
+ makePath("dir1/dir2/file4"),
+ makePath("dir1/dir2/dir3/file5"),
+ makePath("dir1/dir2/symlink_to_dir3"),
+ makePath("dir1/dir2/symlink_to_dir3/file5"),
+};
+
+} // namespace StaticEnv
+
+#endif // LIBCXX_FILESYSTEM_STATIC_TEST_ROOT
+
+#ifndef LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT
+#warning LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT must be defined
+#else // LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT
+
+#ifndef LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER
+#error LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER must be defined
+#endif
+
+struct scoped_test_env
+{
+ scoped_test_env() : test_root(random_env_path())
+ { fs_helper_run(fs_make_cmd("init_test_directory", test_root)); }
+
+ ~scoped_test_env()
+ { fs_helper_run(fs_make_cmd("destroy_test_directory", test_root)); }
+
+ scoped_test_env(scoped_test_env const &) = delete;
+ scoped_test_env & operator=(scoped_test_env const &) = delete;
+
+ fs::path make_env_path(std::string p) { return sanitize_path(p); }
+
+ std::string sanitize_path(std::string raw) {
+ assert(raw.find("..") == std::string::npos);
+ std::string const& root = test_root.native();
+ if (root.compare(0, root.size(), raw, 0, root.size()) != 0) {
+ assert(raw.front() != '\\');
+ fs::path tmp(test_root);
+ tmp /= raw;
+ return std::move(const_cast<std::string&>(tmp.native()));
+ }
+ return raw;
+ }
+
+ std::string create_file(std::string filename, std::size_t size = 0) {
+ filename = sanitize_path(std::move(filename));
+ std::string out_str(size, 'a');
+ {
+ std::ofstream out(filename.c_str());
+ out << out_str;
+ }
+ return filename;
+ }
+
+ std::string create_dir(std::string filename) {
+ filename = sanitize_path(std::move(filename));
+ fs_helper_run(fs_make_cmd("create_dir", filename));
+ return filename;
+ }
+
+ std::string create_symlink(std::string source, std::string to) {
+ source = sanitize_path(std::move(source));
+ to = sanitize_path(std::move(to));
+ fs_helper_run(fs_make_cmd("create_symlink", source, to));
+ return to;
+ }
+
+ std::string create_hardlink(std::string source, std::string to) {
+ source = sanitize_path(std::move(source));
+ to = sanitize_path(std::move(to));
+ fs_helper_run(fs_make_cmd("create_hardlink", source, to));
+ return to;
+ }
+
+ std::string create_fifo(std::string file) {
+ file = sanitize_path(std::move(file));
+ fs_helper_run(fs_make_cmd("create_fifo", file));
+ return file;
+ }
+
+ // OS X and FreeBSD doesn't support socket files so we shouldn't even
+ // allow tests to call this unguarded.
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
+ std::string create_socket(std::string file) {
+ file = sanitize_path(std::move(file));
+ fs_helper_run(fs_make_cmd("create_socket", file));
+ return file;
+ }
+#endif
+
+ fs::path const test_root;
+
+private:
+ static char to_hex(int ch) {
+ return ch < 10 ? static_cast<char>('0' + ch)
+ : static_cast<char>('a' + (ch - 10));
+ }
+
+ static char random_hex_char() {
+ static std::mt19937 rd { std::random_device{}() };
+ static std::uniform_int_distribution<int> mrand{0, 15};
+ return to_hex( mrand(rd) );
+ }
+
+ static std::string unique_path_suffix() {
+ std::string model = "test.%%%%%%";
+ for (auto & ch : model) {
+ if (ch == '%') ch = random_hex_char();
+ }
+ return model;
+ }
+
+ // This could potentially introduce a filesystem race with other tests
+ // running at the same time, but oh well, it's just test code.
+ static inline fs::path random_env_path() {
+ static const char* env_path = LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT;
+ fs::path p = fs::path(env_path) / unique_path_suffix();
+ assert(p.parent_path() == env_path);
+ return p;
+ }
+
+ static inline std::string make_arg(std::string const& arg) {
+ return "'" + arg + "'";
+ }
+
+ static inline std::string make_arg(std::size_t arg) {
+ return std::to_string(arg);
+ }
+
+ template <class T>
+ static inline std::string
+ fs_make_cmd(std::string const& cmd_name, T const& arg) {
+ return cmd_name + "(" + make_arg(arg) + ")";
+ }
+
+ template <class T, class U>
+ static inline std::string
+ fs_make_cmd(std::string const& cmd_name, T const& arg1, U const& arg2) {
+ return cmd_name + "(" + make_arg(arg1) + ", " + make_arg(arg2) + ")";
+ }
+
+ static inline void fs_helper_run(std::string const& raw_cmd) {
+ // check that the fs test root in the enviroment matches what we were
+ // compiled with.
+ static bool checked = checkDynamicTestRoot();
+ std::string cmd = LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER;
+ cmd += " \"" + raw_cmd + "\"";
+ int ret = std::system(cmd.c_str());
+ assert(ret == 0);
+ }
+
+ static bool checkDynamicTestRoot() {
+ char* fs_root = std::getenv("LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT");
+ if (!fs_root) {
+ std::printf("ERROR: LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT must be a defined "
+ "environment variable when running the test.\n");
+ std::abort();
+ }
+ if (std::string(fs_root) != LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT) {
+ std::printf("ERROR: LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT enviroment variable"
+ " must have the same value as when the test was compiled.\n");
+ std::printf(" Current Value: '%s'\n", fs_root);
+ std::printf(" Expected Value: '%s'\n", LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT);
+ std::abort();
+ }
+ return true;
+ }
+
+};
+
+#endif // LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT
+
+// Misc test types
+
+#define CONCAT2(LHS, RHS) LHS##RHS
+#define CONCAT(LHS, RHS) CONCAT2(LHS, RHS)
+#define MKSTR(Str) {Str, CONCAT(L, Str), CONCAT(u, Str), CONCAT(U, Str)}
+
+struct MultiStringType {
+ const char* s;
+ const wchar_t* w;
+ const char16_t* u16;
+ const char32_t* u32;
+
+ operator const char* () const { return s; }
+ operator const wchar_t* () const { return w; }
+ operator const char16_t* () const { return u16; }
+ operator const char32_t* () const { return u32; }
+};
+
+const MultiStringType PathList[] = {
+ MKSTR(""),
+ MKSTR(" "),
+ MKSTR("//"),
+ MKSTR("."),
+ MKSTR(".."),
+ MKSTR("foo"),
+ MKSTR("/"),
+ MKSTR("/foo"),
+ MKSTR("foo/"),
+ MKSTR("/foo/"),
+ MKSTR("foo/bar"),
+ MKSTR("/foo/bar"),
+ MKSTR("//net"),
+ MKSTR("//net/foo"),
+ MKSTR("///foo///"),
+ MKSTR("///foo///bar"),
+ MKSTR("/."),
+ MKSTR("./"),
+ MKSTR("/.."),
+ MKSTR("../"),
+ MKSTR("foo/."),
+ MKSTR("foo/.."),
+ MKSTR("foo/./"),
+ MKSTR("foo/./bar"),
+ MKSTR("foo/../"),
+ MKSTR("foo/../bar"),
+ MKSTR("c:"),
+ MKSTR("c:/"),
+ MKSTR("c:foo"),
+ MKSTR("c:/foo"),
+ MKSTR("c:foo/"),
+ MKSTR("c:/foo/"),
+ MKSTR("c:/foo/bar"),
+ MKSTR("prn:"),
+ MKSTR("c:\\"),
+ MKSTR("c:\\foo"),
+ MKSTR("c:foo\\"),
+ MKSTR("c:\\foo\\"),
+ MKSTR("c:\\foo/"),
+ MKSTR("c:/foo\\bar"),
+ MKSTR("//"),
+ MKSTR("/finally/we/need/one/really/really/really/really/really/really/really/long/string")
+};
+const unsigned PathListSize = sizeof(PathList) / sizeof(MultiStringType);
+
+template <class Iter>
+Iter IterEnd(Iter B) {
+ using VT = typename std::iterator_traits<Iter>::value_type;
+ for (; *B != VT{}; ++B)
+ ;
+ return B;
+}
+
+template <class CharT>
+const CharT* StrEnd(CharT const* P) {
+ return IterEnd(P);
+}
+
+template <class CharT>
+std::size_t StrLen(CharT const* P) {
+ return StrEnd(P) - P;
+}
+
+// Testing the allocation behavior of the code_cvt functions requires
+// *knowing* that the allocation was not done by "path::__str_".
+// This hack forces path to allocate enough memory.
+inline void PathReserve(fs::path& p, std::size_t N) {
+ auto const& native_ref = p.native();
+ const_cast<std::string&>(native_ref).reserve(N);
+}
+
+template <class Iter1, class Iter2>
+bool checkCollectionsEqual(
+ Iter1 start1, Iter1 const end1
+ , Iter2 start2, Iter2 const end2
+ )
+{
+ while (start1 != end1 && start2 != end2) {
+ if (*start1 != *start2) {
+ return false;
+ }
+ ++start1; ++start2;
+ }
+ return (start1 == end1 && start2 == end2);
+}
+
+// We often need to test that the error_code was cleared if no error occurs
+// this function returns a error_code which is set to an error that will
+// never be returned by the filesystem functions.
+inline std::error_code GetTestEC() {
+ return std::make_error_code(std::errc::address_family_not_supported);
+}
+
+#endif /* FILESYSTEM_TEST_HELPER_HPP */
Modified: libcxx/trunk/test/support/min_allocator.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/min_allocator.h?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/test/support/min_allocator.h (original)
+++ libcxx/trunk/test/support/min_allocator.h Fri Jun 17 14:46:40 2016
@@ -11,6 +11,9 @@
#define MIN_ALLOCATOR_H
#include <cstddef>
+#include <cstdlib>
+#include <cstddef>
+#include <cassert>
#include "test_macros.h"
@@ -39,6 +42,57 @@ public:
friend bool operator!=(bare_allocator x, bare_allocator y) {return !(x == y);}
};
+struct malloc_allocator_base {
+ static size_t alloc_count;
+ static size_t dealloc_count;
+ static bool disable_default_constructor;
+
+ static size_t outstanding_alloc() {
+ assert(alloc_count >= dealloc_count);
+ return (alloc_count - dealloc_count);
+ }
+
+ static void reset() {
+ assert(outstanding_alloc() == 0);
+ disable_default_constructor = false;
+ alloc_count = 0;
+ dealloc_count = 0;
+ }
+};
+
+
+size_t malloc_allocator_base::alloc_count = 0;
+size_t malloc_allocator_base::dealloc_count = 0;
+bool malloc_allocator_base::disable_default_constructor = false;
+
+
+template <class T>
+class malloc_allocator : public malloc_allocator_base
+{
+public:
+ typedef T value_type;
+
+ malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); }
+
+ template <class U>
+ malloc_allocator(malloc_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n)
+ {
+ ++alloc_count;
+ return static_cast<T*>(std::malloc(n*sizeof(T)));
+ }
+
+ void deallocate(T* p, std::size_t)
+ {
+ ++dealloc_count;
+ std::free(static_cast<void*>(p));
+ }
+
+ friend bool operator==(malloc_allocator, malloc_allocator) {return true;}
+ friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);}
+};
+
#if TEST_STD_VER >= 11
Added: libcxx/trunk/test/support/rapid-cxx-test.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/rapid-cxx-test.hpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/support/rapid-cxx-test.hpp (added)
+++ libcxx/trunk/test/support/rapid-cxx-test.hpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,847 @@
+#ifndef RAPID_CXX_TEST_HPP
+#define RAPID_CXX_TEST_HPP
+
+# include <cstddef>
+# include <cstdlib>
+# include <cstdio>
+# include <cstring>
+# include <cassert>
+
+#include "test_macros.h"
+
+#if !defined(RAPID_CXX_TEST_NO_SYSTEM_HEADER) || !defined(__GNUC__)
+#pragma GCC system_header
+#endif
+
+# define RAPID_CXX_TEST_PP_CAT(x, y) RAPID_CXX_TEST_PP_CAT_2(x, y)
+# define RAPID_CXX_TEST_PP_CAT_2(x, y) x##y
+
+# define RAPID_CXX_TEST_PP_STR(...) RAPID_CXX_TEST_PP_STR_2(__VA_ARGS__)
+# define RAPID_CXX_TEST_PP_STR_2(...) #__VA_ARGS__
+
+# if defined(__GNUC__)
+# define TEST_FUNC_NAME() __PRETTY_FUNCTION__
+# define RAPID_CXX_TEST_UNUSED __attribute__((unused))
+# else
+# define TEST_FUNC_NAME() __func__
+# define RAPID_CXX_TEST_UNUSED
+# endif
+
+////////////////////////////////////////////////////////////////////////////////
+// TEST_SUITE
+////////////////////////////////////////////////////////////////////////////////
+# define TEST_SUITE(Name) \
+namespace Name \
+{ \
+ inline ::rapid_cxx_test::test_suite & get_test_suite() \
+ { \
+ static ::rapid_cxx_test::test_suite m_suite(#Name); \
+ return m_suite; \
+ } \
+ \
+ inline int unit_test_main(int, char**) \
+ { \
+ ::rapid_cxx_test::test_runner runner(get_test_suite()); \
+ return runner.run(); \
+ } \
+} \
+int main(int argc, char **argv) \
+{ \
+ return Name::unit_test_main(argc, argv); \
+} \
+namespace Name \
+{ /* namespace closed in TEST_SUITE_END */
+#
+
+////////////////////////////////////////////////////////////////////////////////
+// TEST_SUITE_END
+////////////////////////////////////////////////////////////////////////////////
+# define TEST_SUITE_END() \
+} /* namespace opened in TEST_SUITE(...) */
+#
+
+////////////////////////////////////////////////////////////////////////////////
+// TEST_CASE
+////////////////////////////////////////////////////////////////////////////////
+
+# if !defined(__clang__)
+#
+# define TEST_CASE(Name) \
+ void Name(); \
+ static void RAPID_CXX_TEST_PP_CAT(Name, _invoker)() \
+ { \
+ Name(); \
+ } \
+ static ::rapid_cxx_test::registrar \
+ RAPID_CXX_TEST_PP_CAT(rapid_cxx_test_registrar_, Name)( \
+ get_test_suite() \
+ , ::rapid_cxx_test::test_case(__FILE__, #Name, __LINE__, & RAPID_CXX_TEST_PP_CAT(Name, _invoker)) \
+ ); \
+ void Name()
+#
+# else /* __clang__ */
+#
+# define TEST_CASE(Name) \
+ void Name(); \
+ static void RAPID_CXX_TEST_PP_CAT(Name, _invoker)() \
+ { \
+ Name(); \
+ } \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \
+ static ::rapid_cxx_test::registrar \
+ RAPID_CXX_TEST_PP_CAT(rapid_cxx_test_registrar_, Name)( \
+ get_test_suite() \
+ , ::rapid_cxx_test::test_case(__FILE__, #Name, __LINE__, & RAPID_CXX_TEST_PP_CAT(Name, _invoker)) \
+ ); \
+ _Pragma("clang diagnostic pop") \
+ void Name()
+#
+# endif /* !defined(__clang__) */
+
+
+# define TEST_SET_CHECKPOINT() ::rapid_cxx_test::set_checkpoint(__FILE__, TEST_FUNC_NAME(), __LINE__)
+
+#define RAPID_CXX_TEST_OUTCOME()
+
+////////////////////////////////////////////////////////////////////////////////
+// TEST_UNSUPPORTED
+////////////////////////////////////////////////////////////////////////////////
+# define TEST_UNSUPPORTED() \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::unsupported, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "", "" \
+ ); \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ return; \
+ } while (false)
+#
+
+
+////////////////////////////////////////////////////////////////////////////////
+// BASIC ASSERTIONS
+////////////////////////////////////////////////////////////////////////////////
+# define TEST_WARN(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_WARN(" #__VA_ARGS__ ")", "" \
+ ); \
+ if (not (__VA_ARGS__)) { \
+ m_f.type = ::rapid_cxx_test::failure_type::warn; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ } while (false)
+#
+
+# define TEST_CHECK(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_CHECK(" #__VA_ARGS__ ")", "" \
+ ); \
+ if (not (__VA_ARGS__)) { \
+ m_f.type = ::rapid_cxx_test::failure_type::check; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ } while (false)
+#
+
+# define TEST_REQUIRE(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_REQUIRE(" #__VA_ARGS__ ")", "" \
+ ); \
+ if (not (__VA_ARGS__)) { \
+ m_f.type = ::rapid_cxx_test::failure_type::require; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ if (m_f.type != ::rapid_cxx_test::failure_type::none) { \
+ return; \
+ } \
+ } while (false)
+#
+
+# define TEST_ASSERT(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_ASSERT(" #__VA_ARGS__ ")", "" \
+ ); \
+ if (not (__VA_ARGS__)) { \
+ m_f.type = ::rapid_cxx_test::failure_type::assert; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ if (m_f.type != ::rapid_cxx_test::failure_type::none) { \
+ std::abort(); \
+ } \
+ } while (false)
+#
+
+////////////////////////////////////////////////////////////////////////////////
+// TEST_CHECK_NO_THROW / TEST_CHECK_THROW
+////////////////////////////////////////////////////////////////////////////////
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+# define TEST_CHECK_NO_THROW(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_CHECK_NO_THROW(" #__VA_ARGS__ ")", "" \
+ ); \
+ try { \
+ (static_cast<void>(__VA_ARGS__)); \
+ } catch (...) { \
+ m_f.type = ::rapid_cxx_test::failure_type::check; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ } while (false)
+#
+
+# define TEST_CHECK_THROW(Except, ...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_CHECK_THROW(" #Except "," #__VA_ARGS__ ")", "" \
+ ); \
+ try { \
+ (static_cast<void>(__VA_ARGS__)); \
+ m_f.type = ::rapid_cxx_test::failure_type::check; \
+ } catch (Except const &) {} \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ } while (false)
+#
+
+#else // TEST_HAS_NO_EXCEPTIONS
+
+# define TEST_CHECK_NO_THROW(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_CHECK_NO_THROW(" #__VA_ARGS__ ")", "" \
+ ); \
+ (static_cast<void>(__VA_ARGS__)); \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ } while (false)
+#
+
+#define TEST_CHECK_THROW(Except, ...) ((void)0)
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+
+////////////////////////////////////////////////////////////////////////////////
+// TEST_REQUIRE_NO_THROW / TEST_REQUIRE_THROWs
+////////////////////////////////////////////////////////////////////////////////
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+# define TEST_REQUIRE_NO_THROW(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_REQUIRE_NO_THROW(" #__VA_ARGS__ ")", "" \
+ ); \
+ try { \
+ (static_cast<void>(__VA_ARGS__)); \
+ } catch (...) { \
+ m_f.type = ::rapid_cxx_test::failure_type::require; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ if (m_f.type != ::rapid_cxx_test::failure_type::none) { \
+ return; \
+ } \
+ } while (false)
+#
+
+# define TEST_REQUIRE_THROW(Except, ...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_REQUIRE_THROW(" #Except "," #__VA_ARGS__ ")", "" \
+ ); \
+ try { \
+ (static_cast<void>(__VA_ARGS__)); \
+ m_f.type = ::rapid_cxx_test::failure_type::require; \
+ } catch (Except const &) {} \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ if (m_f.type != ::rapid_cxx_test::failure_type::none) { \
+ return; \
+ } \
+ } while (false)
+#
+
+#else // TEST_HAS_NO_EXCEPTIONS
+
+# define TEST_REQUIRE_NO_THROW(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_REQUIRE_NO_THROW(" #__VA_ARGS__ ")", "" \
+ ); \
+ (static_cast<void>(__VA_ARGS__)); \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ } while (false)
+#
+
+#define TEST_REQUIRE_THROW(Except, ...) ((void)0)
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+////////////////////////////////////////////////////////////////////////////////
+// TEST_ASSERT_NO_THROW / TEST_ASSERT_THROW
+////////////////////////////////////////////////////////////////////////////////
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+# define TEST_ASSERT_NO_THROW(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_ASSERT_NO_THROW(" #__VA_ARGS__ ")", "" \
+ ); \
+ try { \
+ (static_cast<void>(__VA_ARGS__)); \
+ } catch (...) { \
+ m_f.type = ::rapid_cxx_test::failure_type::assert; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ if (m_f.type != ::rapid_cxx_test::failure_type::none) { \
+ std::abort(); \
+ } \
+ } while (false)
+#
+
+# define TEST_ASSERT_THROW(Except, ...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_ASSERT_THROW(" #Except "," #__VA_ARGS__ ")", "" \
+ ); \
+ try { \
+ (static_cast<void>(__VA_ARGS__)); \
+ m_f.type = ::rapid_cxx_test::failure_type::assert; \
+ } catch (Except const &) {} \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ if (m_f.type != ::rapid_cxx_test::failure_type::none) { \
+ std::abort(); \
+ } \
+ } while (false)
+#
+
+#else // TEST_HAS_NO_EXCEPTIONS
+
+# define TEST_ASSERT_NO_THROW(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_ASSERT_NO_THROW(" #__VA_ARGS__ ")", "" \
+ ); \
+ (static_cast<void>(__VA_ARGS__)); \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ } while (false)
+#
+
+#define TEST_ASSERT_THROW(Except, ...) ((void)0)
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+////////////////////////////////////////////////////////////////////////////////
+//
+////////////////////////////////////////////////////////////////////////////////
+
+# define TEST_WARN_EQUAL_COLLECTIONS(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_WARN_EQUAL_COLLECTIONS(" #__VA_ARGS__ ")", "" \
+ ); \
+ if (not ::rapid_cxx_test::detail::check_equal_collections_impl(__VA_ARGS__)) { \
+ m_f.type = ::rapid_cxx_test::failure_type::warn; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ } while (false)
+#
+
+# define TEST_CHECK_EQUAL_COLLECTIONS(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_CHECK_EQUAL_COLLECTIONS(" #__VA_ARGS__ ")", "" \
+ ); \
+ if (not ::rapid_cxx_test::detail::check_equal_collections_impl(__VA_ARGS__)) { \
+ m_f.type = ::rapid_cxx_test::failure_type::check; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ } while (false)
+#
+
+# define TEST_REQUIRE_EQUAL_COLLECTIONS(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_REQUIRE_EQUAL_COLLECTIONS(" #__VA_ARGS__ ")", "" \
+ ); \
+ if (not ::rapid_cxx_test::detail::check_equal_collections_impl(__VA_ARGS__)) { \
+ m_f.type = ::rapid_cxx_test::failure_type::require; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ if (m_f.type != ::rapid_cxx_test::failure_type::none) { \
+ return; \
+ } \
+ } while (false)
+#
+
+# define TEST_ASSERT_EQUAL_COLLECTIONS(...) \
+ do { \
+ TEST_SET_CHECKPOINT(); \
+ ::rapid_cxx_test::test_outcome m_f( \
+ ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \
+ , "TEST_ASSERT_EQUAL_COLLECTIONS(" #__VA_ARGS__ ")", "" \
+ ); \
+ if (not ::rapid_cxx_test::detail::check_equal_collections_impl(__VA_ARGS__)) { \
+ m_f.type = ::rapid_cxx_test::failure_type::assert; \
+ } \
+ ::rapid_cxx_test::get_reporter().report(m_f); \
+ if (m_f.type != ::rapid_cxx_test::failure_type::none) { \
+ ::std::abort(); \
+ } \
+ } while (false)
+#
+
+namespace rapid_cxx_test
+{
+ typedef void (*invoker_t)();
+
+ ////////////////////////////////////////////////////////////////////////////
+ struct test_case
+ {
+ test_case()
+ : file(""), func(""), line(0), invoke(NULL)
+ {}
+
+ test_case(const char* file1, const char* func1, std::size_t line1,
+ invoker_t invoke1)
+ : file(file1), func(func1), line(line1), invoke(invoke1)
+ {}
+
+ const char *file;
+ const char *func;
+ std::size_t line;
+ invoker_t invoke;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ struct failure_type
+ {
+ enum enum_type {
+ none,
+ unsupported,
+ warn,
+ check,
+ require,
+ assert,
+ uncaught_exception
+ };
+ };
+
+ typedef failure_type::enum_type failure_type_t;
+
+ ////////////////////////////////////////////////////////////////////////////
+ struct test_outcome
+ {
+ test_outcome()
+ : type(failure_type::none),
+ file(""), func(""), line(0),
+ expression(""), message("")
+ {}
+
+ test_outcome(failure_type_t type1, const char* file1, const char* func1,
+ std::size_t line1, const char* expression1,
+ const char* message1)
+ : type(type1), file(file1), func(func1), line(line1),
+ expression(expression1), message(message1)
+ {
+ trim_func_string();
+ }
+
+ failure_type_t type;
+ const char *file;
+ const char *func;
+ std::size_t line;
+ const char *expression;
+ const char *message;
+
+ private:
+ void trim_file_string() {
+ const char* f_start = file;
+ const char* prev_start = f_start;
+ const char* last_start = f_start;
+ char last;
+ while ((last = *f_start) != '\0') {
+ ++f_start;
+ if (last == '/' && *f_start) {
+ prev_start = last_start;
+ last_start = f_start;
+ }
+ }
+ file = prev_start;
+ }
+ void trim_func_string() {
+ const char* void_loc = ::strstr(func, "void ");
+ if (void_loc == func) {
+ func += strlen("void ");
+ }
+ const char* namespace_loc = ::strstr(func, "::");
+ if (namespace_loc) {
+ func = namespace_loc + 2;
+ }
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ struct checkpoint
+ {
+ const char *file;
+ const char *func;
+ std::size_t line;
+ };
+
+ namespace detail
+ {
+ inline checkpoint & global_checkpoint()
+ {
+ static checkpoint cp = {"", "", 0};
+ return cp;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ inline void set_checkpoint(const char* file, const char* func, std::size_t line)
+ {
+ checkpoint& cp = detail::global_checkpoint();
+ cp.file = file;
+ cp.func = func;
+ cp.line = line;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ inline checkpoint const & get_checkpoint()
+ {
+ return detail::global_checkpoint();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ class test_suite
+ {
+ public:
+ typedef test_case const* iterator;
+ typedef iterator const_iterator;
+
+ public:
+ test_suite(const char *xname)
+ : m_name(xname), m_tests(), m_size(0)
+ {
+ assert(xname);
+ }
+
+ public:
+ const char *name() const { return m_name; }
+
+ std::size_t size() const { return m_size; }
+
+ test_case const & operator[](std::size_t i) const
+ {
+ assert(i < m_size);
+ return m_tests[i];
+ }
+
+ const_iterator begin() const
+ { return m_tests; }
+
+ const_iterator end() const
+ {
+ return m_tests + m_size;
+ }
+
+ public:
+ std::size_t register_test(test_case tc)
+ {
+ static std::size_t test_case_max = sizeof(m_tests) / sizeof(test_case);
+ assert(m_size < test_case_max);
+ m_tests[m_size] = tc;
+ return m_size++;
+ }
+
+ private:
+ test_suite(test_suite const &);
+ test_suite & operator=(test_suite const &);
+
+ private:
+ const char* m_name;
+ // Since fast compile times in a priority, we use simple containers
+ // with hard limits.
+ test_case m_tests[256];
+ std::size_t m_size;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ class registrar
+ {
+ public:
+ registrar(test_suite & st, test_case tc)
+ {
+ st.register_test(tc);
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ class test_reporter
+ {
+ public:
+ test_reporter()
+ : m_testcases(0), m_testcase_failures(0), m_unsupported(0),
+ m_assertions(0), m_warning_failures(0), m_check_failures(0),
+ m_require_failures(0), m_uncaught_exceptions(0), m_failure()
+ {
+ }
+
+ void test_case_begin()
+ {
+ ++m_testcases;
+ clear_failure();
+ }
+
+ void test_case_end()
+ {
+ if (m_failure.type != failure_type::none
+ && m_failure.type != failure_type::unsupported) {
+ ++m_testcase_failures;
+ }
+ }
+
+# if defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wswitch-default"
+# endif
+ // Each assertion and failure is reported through this function.
+ void report(test_outcome o)
+ {
+ ++m_assertions;
+ switch (o.type)
+ {
+ case failure_type::none:
+ break;
+ case failure_type::unsupported:
+ ++m_unsupported;
+ m_failure = o;
+ break;
+ case failure_type::warn:
+ ++m_warning_failures;
+ report_error(o);
+ break;
+ case failure_type::check:
+ ++m_check_failures;
+ report_error(o);
+ m_failure = o;
+ break;
+ case failure_type::require:
+ ++m_require_failures;
+ report_error(o);
+ m_failure = o;
+ break;
+ case failure_type::assert:
+ report_error(o);
+ break;
+ case failure_type::uncaught_exception:
+ ++m_uncaught_exceptions;
+ std::fprintf(stderr
+ , "Test case FAILED with uncaught exception:\n"
+ " last checkpoint near %s::%lu %s\n\n"
+ , o.file, o.line, o.func
+ );
+ m_failure = o;
+ break;
+ }
+ }
+# if defined(__GNUC__)
+# pragma GCC diagnostic pop
+# endif
+
+ test_outcome current_failure() const
+ {
+ return m_failure;
+ }
+
+ void clear_failure()
+ {
+ m_failure.type = failure_type::none;
+ m_failure.file = "";
+ m_failure.func = "";
+ m_failure.line = 0;
+ m_failure.expression = "";
+ m_failure.message = "";
+ }
+
+ std::size_t test_case_count() const
+ { return m_testcases; }
+
+ std::size_t test_case_failure_count() const
+ { return m_testcase_failures; }
+
+ std::size_t unsupported_count() const
+ { return m_unsupported; }
+
+ std::size_t assertion_count() const
+ { return m_assertions; }
+
+ std::size_t warning_failure_count() const
+ { return m_warning_failures; }
+
+ std::size_t check_failure_count() const
+ { return m_check_failures; }
+
+ std::size_t require_failure_count() const
+ { return m_require_failures; }
+
+ std::size_t failure_count() const
+ { return m_check_failures + m_require_failures + m_uncaught_exceptions; }
+
+ // Print a summary of what was run and the outcome.
+ void print_summary(const char* suitename) const
+ {
+ FILE* out = failure_count() ? stderr : stdout;
+ std::size_t testcases_run = m_testcases - m_unsupported;
+ std::fprintf(out, "Summary for testsuite %s:\n", suitename);
+ std::fprintf(out, " %lu of %lu test cases passed.\n", testcases_run - m_testcase_failures, testcases_run);
+ std::fprintf(out, " %lu of %lu assertions passed.\n", m_assertions - (m_warning_failures + m_check_failures + m_require_failures), m_assertions);
+ std::fprintf(out, " %lu unsupported test case%s.\n", m_unsupported, (m_unsupported != 1 ? "s" : ""));
+ }
+
+ private:
+ test_reporter(test_reporter const &);
+ test_reporter const & operator=(test_reporter const &);
+
+ void report_error(test_outcome o) const
+ {
+ std::fprintf(stderr, "In %s:%lu Assertion %s failed.\n in file: %s\n %s\n"
+ , o.func, o.line, o.expression, o.file, o.message ? o.message : ""
+ );
+ }
+
+ private:
+ // counts of testcases, failed testcases, and unsupported testcases.
+ std::size_t m_testcases;
+ std::size_t m_testcase_failures;
+ std::size_t m_unsupported;
+
+ // counts of assertions and assertion failures.
+ std::size_t m_assertions;
+ std::size_t m_warning_failures;
+ std::size_t m_check_failures;
+ std::size_t m_require_failures;
+ std::size_t m_uncaught_exceptions;
+
+ // The last failure. This is cleared between testcases.
+ test_outcome m_failure;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ inline test_reporter & get_reporter()
+ {
+ static test_reporter o;
+ return o;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ class test_runner
+ {
+ public:
+ test_runner(test_suite & ts)
+ : m_ts(ts)
+ {}
+
+ public:
+ int run()
+ {
+ // for each testcase
+ for (test_suite::const_iterator b = m_ts.begin(), e = m_ts.end();
+ b != e; ++b)
+ {
+ test_case const& tc = *b;
+ set_checkpoint(tc.file, tc.func, tc.line);
+ get_reporter().test_case_begin();
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+#endif
+ tc.invoke();
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ } catch (...) {
+ test_outcome o;
+ o.type = failure_type::uncaught_exception;
+ o.file = get_checkpoint().file;
+ o.func = get_checkpoint().func;
+ o.line = get_checkpoint().line;
+ o.expression = "";
+ o.message = "";
+ get_reporter().report(o);
+ }
+#endif
+ get_reporter().test_case_end();
+ }
+ auto exit_code = get_reporter().failure_count() ? EXIT_FAILURE : EXIT_SUCCESS;
+ if (exit_code == EXIT_FAILURE)
+ get_reporter().print_summary(m_ts.name());
+ return exit_code;
+ }
+
+ private:
+ test_runner(test_runner const &);
+ test_runner operator=(test_runner const &);
+
+ test_suite & m_ts;
+ };
+
+ namespace detail
+ {
+ template <class Iter1, class Iter2>
+ bool check_equal_collections_impl(
+ Iter1 start1, Iter1 const end1
+ , Iter2 start2, Iter2 const end2
+ )
+ {
+ while (start1 != end1 && start2 != end2) {
+ if (*start1 != *start2) {
+ return false;
+ }
+ ++start1; ++start2;
+ }
+ return (start1 == end1 && start2 == end2);
+ }
+ } // namespace detail
+
+} // namespace rapid_cxx_test
+
+
+# if defined(__GNUC__)
+# pragma GCC diagnostic pop
+# endif
+
+#endif /* RAPID_CXX_TEST_HPP */
Added: libcxx/trunk/test/support/test_convertible.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/test_convertible.hpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/support/test_convertible.hpp (added)
+++ libcxx/trunk/test/support/test_convertible.hpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_TEST_CONVERTIBLE_HPP
+#define SUPPORT_TEST_CONVERTIBLE_HPP
+
+// "test_convertible<Tp, Args...>()" is a metafunction used to check if 'Tp'
+// is implicitly convertible from 'Args...' for any number of arguments,
+// Unlike 'std::is_convertible' which only allows checking for single argument
+// conversions.
+
+#include <type_traits>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER < 11
+#error test_convertible.hpp requires C++11 or newer
+#endif
+
+namespace detail {
+ template <class Tp> void eat_type(Tp);
+
+ template <class Tp, class ...Args>
+ constexpr auto test_convertible_imp(int)
+ -> decltype(eat_type<Tp>({std::declval<Args>()...}), true)
+ { return true; }
+
+ template <class Tp, class ...Args>
+ constexpr auto test_convertible_imp(long) -> bool { return false; }
+}
+
+template <class Tp, class ...Args>
+constexpr bool test_convertible()
+{ return detail::test_convertible_imp<Tp, Args...>(0); }
+
+#endif // SUPPORT_TEST_CONVERTIBLE_HPP
\ No newline at end of file
Added: libcxx/trunk/test/support/test_convertible_header.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/test_convertible_header.pass.cpp?rev=273034&view=auto
==============================================================================
--- libcxx/trunk/test/support/test_convertible_header.pass.cpp (added)
+++ libcxx/trunk/test/support/test_convertible_header.pass.cpp Fri Jun 17 14:46:40 2016
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// "support/test_convertible.hpp"
+
+#include "test_convertible.hpp"
+
+struct ImplicitDefault {
+ ImplicitDefault() {}
+};
+static_assert(test_convertible<ImplicitDefault>(), "Must be convertible");
+
+struct ExplicitDefault {
+ explicit ExplicitDefault() {}
+};
+static_assert(!test_convertible<ExplicitDefault>(), "Must not be convertible");
+
+struct ImplicitInt {
+ ImplicitInt(int) {}
+};
+static_assert(test_convertible<ImplicitInt, int>(), "Must be convertible");
+
+struct ExplicitInt {
+ explicit ExplicitInt(int) {}
+};
+static_assert(!test_convertible<ExplicitInt, int>(), "Must not be convertible");
+
+struct ImplicitCopy {
+ ImplicitCopy(ImplicitCopy const&) {}
+};
+static_assert(test_convertible<ImplicitCopy, ImplicitCopy>(), "Must be convertible");
+
+struct ExplicitCopy {
+ explicit ExplicitCopy(ExplicitCopy const&) {}
+};
+static_assert(!test_convertible<ExplicitCopy, ExplicitCopy>(), "Must not be convertible");
+
+struct ImplicitMove {
+ ImplicitMove(ImplicitMove&&) {}
+};
+static_assert(test_convertible<ImplicitMove, ImplicitMove>(), "Must be convertible");
+
+struct ExplicitMove {
+ explicit ExplicitMove(ExplicitMove&&) {}
+};
+static_assert(!test_convertible<ExplicitMove, ExplicitMove>(), "Must not be convertible");
+
+struct ImplicitArgs {
+ ImplicitArgs(int, int, int) {}
+};
+static_assert(test_convertible<ImplicitArgs, int, int, int>(), "Must be convertible");
+
+struct ExplicitArgs {
+ explicit ExplicitArgs(int, int, int) {}
+};
+static_assert(!test_convertible<ExplicitArgs, int, int, int>(), "Must not be convertible");
+
+int main() {
+ // Nothing to do
+}
Modified: libcxx/trunk/test/support/test_macros.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/test_macros.h?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/test/support/test_macros.h (original)
+++ libcxx/trunk/test/support/test_macros.h Fri Jun 17 14:46:40 2016
@@ -93,4 +93,21 @@
#define LIBCPP_STATIC_ASSERT(...) ((void)0)
#endif
+#define ASSERT_NOEXCEPT(...) \
+ static_assert(noexcept(__VA_ARGS__), "Operation must be noexcept")
+
+#define ASSERT_NOT_NOEXCEPT(...) \
+ static_assert(!noexcept(__VA_ARGS__), "Operation must NOT be noexcept")
+
+namespace test_macros_detail {
+template <class T, class U>
+struct is_same { enum { value = 0};} ;
+template <class T>
+struct is_same<T, T> { enum {value = 1}; };
+} // namespace test_macros_detail
+
+#define ASSERT_SAME_TYPE(...) \
+ static_assert(test_macros_detail::is_same<__VA_ARGS__>::value, \
+ "Types differ uexpectedly")
+
#endif // SUPPORT_TEST_MACROS_HPP
Modified: libcxx/trunk/www/ts1z_status.html
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/ts1z_status.html?rev=273034&r1=273033&r2=273034&view=diff
==============================================================================
--- libcxx/trunk/www/ts1z_status.html (original)
+++ libcxx/trunk/www/ts1z_status.html Fri Jun 17 14:46:40 2016
@@ -98,12 +98,12 @@
<h3>Features in Filesystem</h3>
<table id="Features" border="1">
- <tr><th>Feature Name</th><th>Status</th></tr>
- <tr><td>All features</td><td>In Review</td></tr>
+ <tr><th>Feature Name</th><th>Status</th><th>First released version</th></tr>
+ <tr><td>All features</td><td>Complete</td><td>3.9</td></tr>
</table>
- <p>Last Updated: 7-Dec-2015</p>
+ <p>Last Updated: 17-June-2016</p>
</div>
</body>
</html>
More information about the cfe-commits
mailing list