[libcxx-commits] [libcxx] r356505 - Revert "[libc++] Build <filesystem> support as part of the dylib"
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Mar 19 12:27:29 PDT 2019
Author: ldionne
Date: Tue Mar 19 12:27:29 2019
New Revision: 356505
URL: http://llvm.org/viewvc/llvm-project?rev=356505&view=rev
Log:
Revert "[libc++] Build <filesystem> support as part of the dylib"
When I applied r356500 (https://reviews.llvm.org/D59152), I somehow
deleted all of filesystem's tests. I will revert r356500 and re-apply
it properly.
Added:
libcxx/trunk/test/libcxx/input.output/filesystems/lit.local.cfg
libcxx/trunk/test/std/input.output/filesystems/
libcxx/trunk/test/std/input.output/filesystems/Inputs/
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink (with props)
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/afile3
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/dir3/
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/dir3/file5
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/file4
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 (with props)
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/file1
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/file2
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/empty_file
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/non_empty_file
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir (with props)
libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file (with props)
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy_assign.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default_const.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move_assign.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/refresh.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/replace_filename.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/comparisons.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/path.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/move.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/types.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.file_status/
libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.cons.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.mods.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.obs.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.filesystem_error/
libcxx/trunk/test/std/input.output/filesystems/class.filesystem_error/filesystem_error.members.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.itr/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.itr/iterator.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/braced_init.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/copy.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/copy.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/default.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/empty.fail.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/path.decompose.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/clear.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/make_preferred.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/remove_filename.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_extension.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_filename.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/swap.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/c_str.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/native.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/operator_string.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.query/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.factory.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.unicode_bug.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/swap.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.path/synop.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/
libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.enum/
libcxx/trunk/test/std/input.output/filesystems/fs.enum/check_bitmask_types.hpp
libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.copy_options.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.file_type.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.error.report/
libcxx/trunk/test/std/input.output/filesystems/fs.error.report/tested_elsewhere.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.filesystem.synopsis/
libcxx/trunk/test/std/input.output/filesystems/fs.filesystem.synopsis/file_time_type.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.absolute/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.absolute/absolute.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy/copy.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_large.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_symlink/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory_symlink/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_hard_link/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.current_path/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.current_path/current_path.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.hard_lk_ct/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_block_file/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_char_file/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_fifo/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_other/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_other/is_other.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_regular_file/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_socket/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.read_symlink/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove/remove.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.rename/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.rename/rename.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.resize_file/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status_known/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status_known/status_known.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/
libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.req.macros/
libcxx/trunk/test/std/input.output/filesystems/fs.req.macros/feature_macro.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/
libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.fail.cpp
libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.pass.cpp
libcxx/trunk/test/std/input.output/filesystems/lit.local.cfg
Modified:
libcxx/trunk/CMakeLists.txt
libcxx/trunk/benchmarks/CMakeLists.txt
libcxx/trunk/docs/BuildingLibcxx.rst
libcxx/trunk/docs/UsingLibcxx.rst
libcxx/trunk/lib/CMakeLists.txt
libcxx/trunk/lib/abi/CHANGELOG.TXT
libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist
libcxx/trunk/test/CMakeLists.txt
libcxx/trunk/test/lit.site.cfg.in
libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp
libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp
libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp
libcxx/trunk/utils/ci/macos-backdeployment.sh
libcxx/trunk/utils/libcxx/test/config.py
libcxx/trunk/utils/libcxx/test/target_info.py
Modified: libcxx/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/CMakeLists.txt?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/CMakeLists.txt (original)
+++ libcxx/trunk/CMakeLists.txt Tue Mar 19 12:27:29 2019
@@ -73,6 +73,12 @@ option(LIBCXX_ENABLE_ASSERTIONS "Enable
option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON)
option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ON)
+set(ENABLE_FILESYSTEM_DEFAULT ${LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY})
+if (WIN32)
+ set(ENABLE_FILESYSTEM_DEFAULT OFF)
+endif()
+option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of libc++fs.a"
+ ${ENABLE_FILESYSTEM_DEFAULT})
option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
# Benchmark options -----------------------------------------------------------
@@ -111,6 +117,9 @@ option(LIBCXX_INSTALL_SUPPORT_HEADERS "I
cmake_dependent_option(LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY
"Install libc++experimental.a" ON
"LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY;LIBCXX_INSTALL_LIBRARY" OFF)
+cmake_dependent_option(LIBCXX_INSTALL_FILESYSTEM_LIBRARY
+ "Install libc++fs.a" ON
+ "LIBCXX_ENABLE_FILESYSTEM;LIBCXX_INSTALL_LIBRARY" OFF)
set(LIBCXX_ABI_VERSION "1" CACHE STRING "ABI version of libc++. Can be either 1 or 2, where 2 is currently not stable. Defaults to 1.")
set(LIBCXX_ABI_NAMESPACE "" CACHE STRING "The inline ABI namespace used by libc++. It defaults to __n where `n` is the current ABI version.")
@@ -282,6 +291,11 @@ option(LIBCXX_HERMETIC_STATIC_LIBRARY
# 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)
@@ -777,6 +791,9 @@ set(LIBCXX_TEST_DEPS "")
if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
list(APPEND LIBCXX_TEST_DEPS cxx_experimental)
endif()
+if (LIBCXX_ENABLE_FILESYSTEM)
+ list(APPEND LIBCXX_TEST_DEPS cxx_filesystem)
+endif()
if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
list(APPEND LIBCXX_TEST_DEPS cxx_external_threads)
Modified: libcxx/trunk/benchmarks/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/CMakeLists.txt?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/benchmarks/CMakeLists.txt (original)
+++ libcxx/trunk/benchmarks/CMakeLists.txt Tue Mar 19 12:27:29 2019
@@ -146,6 +146,9 @@ function(add_benchmark_test name source_
if (TARGET cxx_experimental)
target_link_libraries(${libcxx_target} cxx_experimental)
endif()
+ if (TARGET cxx_filesystem)
+ target_link_libraries(${libcxx_target} cxx_filesystem)
+ endif()
target_link_libraries(${libcxx_target} -lbenchmark)
if (LLVM_USE_SANITIZER)
target_link_libraries(${libcxx_target} -ldl)
Modified: libcxx/trunk/docs/BuildingLibcxx.rst
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/docs/BuildingLibcxx.rst?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/docs/BuildingLibcxx.rst (original)
+++ libcxx/trunk/docs/BuildingLibcxx.rst Tue Mar 19 12:27:29 2019
@@ -224,6 +224,18 @@ libc++experimental Specific Options
Install libc++experimental.a alongside libc++.
+.. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL
+
+ **Default**: ``ON``
+
+ Build filesystem as a standalone library libc++fs.a.
+
+.. option:: LIBCXX_INSTALL_FILESYSTEM_LIBRARY:BOOL
+
+ **Default**: ``LIBCXX_ENABLE_FILESYSTEM AND LIBCXX_INSTALL_LIBRARY``
+
+ Install libc++fs.a alongside libc++.
+
.. _ABI Library Specific Options:
ABI Library Specific Options
Modified: libcxx/trunk/docs/UsingLibcxx.rst
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/docs/UsingLibcxx.rst?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/docs/UsingLibcxx.rst (original)
+++ libcxx/trunk/docs/UsingLibcxx.rst Tue Mar 19 12:27:29 2019
@@ -50,6 +50,23 @@ An example of using ``LD_LIBRARY_PATH``:
$ ./a.out # Searches for libc++ along LD_LIBRARY_PATH
+Using ``<filesystem>`` and libc++fs
+====================================
+
+Libc++ provides the implementation of the filesystem library in a separate
+library. Users of ``<filesystem>`` and ``<experimental/filesystem>`` are
+required to link ``-lc++fs``.
+
+.. note::
+ Prior to libc++ 7.0, users of ``<experimental/filesystem>`` were required
+ to link libc++experimental.
+
+.. warning::
+ The Filesystem library is still experimental in nature. As such normal
+ guarantees about ABI stability and backwards compatibility do not yet apply
+ to it. In the future, this restriction will be removed.
+
+
Using libc++experimental and ``<experimental/...>``
=====================================================
@@ -66,6 +83,9 @@ installed. For information on building l
:ref:`Building Libc++ <build instructions>` and
:ref:`libc++experimental CMake Options <libc++experimental options>`.
+Note that as of libc++ 7.0 using the ``<experimental/filesystem>`` requires linking
+libc++fs instead of libc++experimental.
+
Also see the `Experimental Library Implementation Status <http://libcxx.llvm.org/ts1z_status.html>`__
page.
Modified: libcxx/trunk/lib/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/CMakeLists.txt?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/lib/CMakeLists.txt (original)
+++ libcxx/trunk/lib/CMakeLists.txt Tue Mar 19 12:27:29 2019
@@ -3,8 +3,6 @@ set(LIBCXX_LIB_CMAKEFILES_DIR "${CMAKE_C
# Get sources
# FIXME: Don't use glob here
file(GLOB LIBCXX_SOURCES ../src/*.cpp)
-list(APPEND LIBCXX_SOURCES ../src/filesystem/operations.cpp
- ../src/filesystem/directory_iterator.cpp)
if(WIN32)
file(GLOB LIBCXX_WIN32_SOURCES ../src/support/win32/*.cpp)
list(APPEND LIBCXX_SOURCES ${LIBCXX_WIN32_SOURCES})
@@ -13,14 +11,6 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "
list(APPEND LIBCXX_SOURCES ${LIBCXX_SOLARIS_SOURCES})
endif()
-# Filesystem uses __int128_t, which requires a definition of __muloi4 when
-# compiled with UBSAN. This definition is not provided by libgcc_s, but is
-# provided by compiler-rt. So we need to disable it to avoid having multiple
-# definitions. See filesystem/int128_builtins.cpp.
-if (NOT LIBCXX_USE_COMPILER_RT)
- list(APPEND LIBCXX_SOURCES ../src/filesystem/int128_builtins.cpp)
-endif()
-
# Add all the headers to the project for IDEs.
if (LIBCXX_CONFIGURE_IDE)
file(GLOB_RECURSE LIBCXX_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/*)
@@ -288,6 +278,39 @@ endif()
# Add a meta-target for both libraries.
add_custom_target(cxx DEPENDS cxx-headers ${LIBCXX_BUILD_TARGETS})
+if (LIBCXX_ENABLE_FILESYSTEM)
+ set(LIBCXX_FILESYSTEM_SOURCES
+ ../src/filesystem/operations.cpp
+ ../src/filesystem/directory_iterator.cpp)
+
+ # Filesystem uses __int128_t, which requires a definition of __muloi4 when
+ # compiled with UBSAN. This definition is not provided by libgcc_s, but is
+ # provided by compiler-rt. So we need to disable it to avoid having multiple
+ # definitions. See filesystem/int128_builtins.cpp.
+ if (NOT LIBCXX_USE_COMPILER_RT)
+ list(APPEND LIBCXX_FILESYSTEM_SOURCES ../src/filesystem/int128_builtins.cpp)
+ endif()
+
+ add_library(cxx_filesystem STATIC ${LIBCXX_FILESYSTEM_SOURCES})
+ if (LIBCXX_ENABLE_SHARED)
+ target_link_libraries(cxx_filesystem cxx_shared)
+ else()
+ target_link_libraries(cxx_filesystem cxx_static)
+ endif()
+
+ set(filesystem_flags "${LIBCXX_COMPILE_FLAGS}")
+ check_flag_supported(-std=c++14)
+ if (NOT MSVC AND LIBCXX_SUPPORTS_STD_EQ_CXX14_FLAG AND LIBCXX_STANDARD_VER STREQUAL "c++11")
+ string(REPLACE "-std=c++11" "-std=c++14" filesystem_flags "${LIBCXX_COMPILE_FLAGS}")
+ endif()
+ set_target_properties(cxx_filesystem
+ PROPERTIES
+ COMPILE_FLAGS "${filesystem_flags}"
+ OUTPUT_NAME "c++fs"
+ )
+endif()
+
+
if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
file(GLOB LIBCXX_EXPERIMENTAL_SOURCES ../src/experimental/*.cpp)
add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES})
@@ -356,10 +379,13 @@ if (LIBCXX_ENABLE_SHARED AND LIBCXX_ENAB
endif()
if (LIBCXX_INSTALL_LIBRARY)
+ if (LIBCXX_INSTALL_FILESYSTEM_LIBRARY)
+ set(filesystem_lib cxx_filesystem)
+ endif()
if (LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY)
set(experimental_lib cxx_experimental)
endif()
- install(TARGETS ${LIBCXX_INSTALL_TARGETS} ${experimental_lib}
+ install(TARGETS ${LIBCXX_INSTALL_TARGETS} ${filesystem_lib} ${experimental_lib}
LIBRARY DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT cxx
ARCHIVE DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT cxx
)
@@ -379,6 +405,9 @@ if (NOT CMAKE_CONFIGURATION_TYPES AND (L
if(LIBCXX_INSTALL_LIBRARY)
set(lib_install_target cxx)
endif()
+ if (LIBCXX_INSTALL_FILESYSTEM_LIBRARY)
+ set(filesystem_lib_install_target cxx_filesystem)
+ endif()
if (LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY)
set(experimental_lib_install_target cxx_experimental)
endif()
@@ -388,6 +417,7 @@ if (NOT CMAKE_CONFIGURATION_TYPES AND (L
add_custom_target(install-cxx
DEPENDS ${lib_install_target}
${experimental_lib_install_target}
+ ${filesystem_lib_install_target}
${header_install_target}
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=cxx
@@ -395,6 +425,7 @@ if (NOT CMAKE_CONFIGURATION_TYPES AND (L
add_custom_target(install-cxx-stripped
DEPENDS ${lib_install_target}
${experimental_lib_install_target}
+ ${filesystem_lib_install_target}
${header_install_target}
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=cxx
Modified: libcxx/trunk/lib/abi/CHANGELOG.TXT
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/abi/CHANGELOG.TXT?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/lib/abi/CHANGELOG.TXT (original)
+++ libcxx/trunk/lib/abi/CHANGELOG.TXT Tue Mar 19 12:27:29 2019
@@ -16,130 +16,6 @@ New entries should be added directly bel
Version 9.0
-----------
-* rXXXXXX - Integrate <filesystem> support into the shared library
-
- This patch introduces support for <filesystem> into the shared library,
- instead of requiring users to manually link against a static archive. As
- such, new symbols required to implement <filesystem> are exported from
- the shared library.
-
- x86_64-unknown-linux-gnu
- ------------------------
- TODO
-
- x86_64-apple-apple-darwin
- -------------------------
- Symbol added: __ZNKSt3__14__fs10filesystem18directory_iterator13__dereferenceEv
- Symbol added: __ZNKSt3__14__fs10filesystem28recursive_directory_iterator13__dereferenceEv
- Symbol added: __ZNKSt3__14__fs10filesystem28recursive_directory_iterator5depthEv
- Symbol added: __ZNKSt3__14__fs10filesystem28recursive_directory_iterator7optionsEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path10__filenameEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path11__extensionEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path11__root_nameEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path13__parent_pathEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path15__relative_pathEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path15__root_path_rawEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path16__root_directoryEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path16lexically_normalEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path18lexically_relativeERKS2_
- Symbol added: __ZNKSt3__14__fs10filesystem4path3endEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path5beginEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path6__stemEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path9__compareENS_17basic_string_viewIcNS_11char_traitsIcEEEE
- Symbol added: __ZNSt3__14__fs10filesystem10__absoluteERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem10hash_valueERKNS1_4pathE
- Symbol added: __ZNSt3__14__fs10filesystem11__canonicalERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem11__copy_fileERKNS1_4pathES4_NS1_12copy_optionsEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem11__file_sizeERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem12__equivalentERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem12__remove_allERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem13__fs_is_emptyERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem13__permissionsERKNS1_4pathENS1_5permsENS1_12perm_optionsEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem13__resize_fileERKNS1_4pathEmPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem14__copy_symlinkERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem14__current_pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem14__current_pathERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem14__read_symlinkERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem15directory_entry12__do_refreshEv
- Symbol added: __ZNSt3__14__fs10filesystem16__create_symlinkERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem16__symlink_statusERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem16_FilesystemClock3nowEv
- Symbol added: __ZNSt3__14__fs10filesystem16filesystem_error13__create_whatEi
- Symbol added: __ZNSt3__14__fs10filesystem16filesystem_errorD0Ev
- Symbol added: __ZNSt3__14__fs10filesystem16filesystem_errorD1Ev
- Symbol added: __ZNSt3__14__fs10filesystem16filesystem_errorD2Ev
- Symbol added: __ZNSt3__14__fs10filesystem17__hard_link_countERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem17__last_write_timeERKNS1_4pathENS_6chrono10time_pointINS1_16_FilesystemClockENS5_8durationInNS_5ratioILl1ELl1000000000EEEEEEEPNS_10error_codeE
- Symbol added: __ZNKSt3__14__fs10filesystem28recursive_directory_iterator5depthEv
- Symbol added: __ZNKSt3__14__fs10filesystem28recursive_directory_iterator7optionsEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path10__filenameEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path11__extensionEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path11__root_nameEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path13__parent_pathEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path15__relative_pathEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path15__root_path_rawEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path16__root_directoryEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path16lexically_normalEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path18lexically_relativeERKS2_
- Symbol added: __ZNKSt3__14__fs10filesystem4path3endEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path5beginEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path6__stemEv
- Symbol added: __ZNKSt3__14__fs10filesystem4path9__compareENS_17basic_string_viewIcNS_11char_traitsIcEEEE
- Symbol added: __ZNSt3__14__fs10filesystem10__absoluteERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem10hash_valueERKNS1_4pathE
- Symbol added: __ZNSt3__14__fs10filesystem11__canonicalERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem11__copy_fileERKNS1_4pathES4_NS1_12copy_optionsEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem11__file_sizeERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem12__equivalentERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem12__remove_allERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem13__fs_is_emptyERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem13__permissionsERKNS1_4pathENS1_5permsENS1_12perm_optionsEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem13__resize_fileERKNS1_4pathEmPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem14__copy_symlinkERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem14__current_pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem14__current_pathERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem14__read_symlinkERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem15directory_entry12__do_refreshEv
- Symbol added: __ZNSt3__14__fs10filesystem16__create_symlinkERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem16__symlink_statusERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem16_FilesystemClock3nowEv
- Symbol added: __ZNSt3__14__fs10filesystem16filesystem_error13__create_whatEi
- Symbol added: __ZNSt3__14__fs10filesystem16filesystem_errorD0Ev
- Symbol added: __ZNSt3__14__fs10filesystem16filesystem_errorD1Ev
- Symbol added: __ZNSt3__14__fs10filesystem16filesystem_errorD2Ev
- Symbol added: __ZNSt3__14__fs10filesystem17__hard_link_countERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem17__last_write_timeERKNS1_4pathENS_6chrono10time_pointINS1_16_FilesystemClockENS5_8durationInNS_5ratioILl1ELl1000000000EEEEEEEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem17__last_write_timeERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem18__create_directoryERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem18__create_directoryERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem18__create_hard_linkERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem18__weakly_canonicalERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem18directory_iterator11__incrementEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem18directory_iteratorC1ERKNS1_4pathEPNS_10error_codeENS1_17directory_optionsE
- Symbol added: __ZNSt3__14__fs10filesystem18directory_iteratorC2ERKNS1_4pathEPNS_10error_codeENS1_17directory_optionsE
- Symbol added: __ZNSt3__14__fs10filesystem20__create_directoriesERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem21__temp_directory_pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem26__create_directory_symlinkERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem28recursive_directory_iterator11__incrementEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem28recursive_directory_iterator15__try_recursionEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem28recursive_directory_iterator5__popEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem28recursive_directory_iterator9__advanceEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem28recursive_directory_iteratorC1ERKNS1_4pathENS1_17directory_optionsEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem28recursive_directory_iteratorC2ERKNS1_4pathENS1_17directory_optionsEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem4path17replace_extensionERKS2_
- Symbol added: __ZNSt3__14__fs10filesystem4path8iterator11__decrementEv
- Symbol added: __ZNSt3__14__fs10filesystem4path8iterator11__incrementEv
- Symbol added: __ZNSt3__14__fs10filesystem6__copyERKNS1_4pathES4_NS1_12copy_optionsEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem7__spaceERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem8__removeERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem8__renameERKNS1_4pathES4_PNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE
- Symbol added: __ZNSt3__14__fs10filesystem16_FilesystemClock9is_steadyE
- Symbol added: __ZNSt3__14__fs10filesystem4path19preferred_separatorE
- Symbol added: __ZTINSt3__14__fs10filesystem16filesystem_errorE
- Symbol added: __ZTSNSt3__14__fs10filesystem16filesystem_errorE
- Symbol added: __ZTVNSt3__14__fs10filesystem16filesystem_errorE
-
* rTBD - Remove exception throwing debug mode handler support.
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
Modified: libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist (original)
+++ libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist Tue Mar 19 12:27:29 2019
@@ -2346,74 +2346,3 @@
{'is_defined': True, 'name': '___dynamic_cast', 'type': 'I'}
{'is_defined': False, 'name': '___gxx_personality_v0', 'type': 'U'}
{'is_defined': True, 'name': '___gxx_personality_v0', 'type': 'I'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem18directory_iterator13__dereferenceEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem28recursive_directory_iterator13__dereferenceEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem28recursive_directory_iterator5depthEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem28recursive_directory_iterator7optionsEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path10__filenameEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path11__extensionEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path11__root_nameEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path13__parent_pathEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path15__relative_pathEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path15__root_path_rawEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path16__root_directoryEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path16lexically_normalEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path18lexically_relativeERKS2_'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path3endEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path5beginEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path6__stemEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem4path9__compareENS_17basic_string_viewIcNS_11char_traitsIcEEEE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem10__absoluteERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem10hash_valueERKNS1_4pathE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem11__canonicalERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem11__copy_fileERKNS1_4pathES4_NS1_12copy_optionsEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem11__file_sizeERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem12__equivalentERKNS1_4pathES4_PNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem12__remove_allERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem13__fs_is_emptyERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem13__permissionsERKNS1_4pathENS1_5permsENS1_12perm_optionsEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem13__resize_fileERKNS1_4pathEmPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem14__copy_symlinkERKNS1_4pathES4_PNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem14__current_pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem14__current_pathERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem14__read_symlinkERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem15directory_entry12__do_refreshEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem16__create_symlinkERKNS1_4pathES4_PNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem16__symlink_statusERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem16_FilesystemClock3nowEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem16filesystem_error13__create_whatEi'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem16filesystem_errorD0Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem16filesystem_errorD1Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem16filesystem_errorD2Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem17__hard_link_countERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem17__last_write_timeERKNS1_4pathENS_6chrono10time_pointINS1_16_FilesystemClockENS5_8durationInNS_5ratioILl1ELl1000000000EEEEEEEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem17__last_write_timeERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem18__create_directoryERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem18__create_directoryERKNS1_4pathES4_PNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem18__create_hard_linkERKNS1_4pathES4_PNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem18__weakly_canonicalERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem18directory_iterator11__incrementEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem18directory_iteratorC1ERKNS1_4pathEPNS_10error_codeENS1_17directory_optionsE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem18directory_iteratorC2ERKNS1_4pathEPNS_10error_codeENS1_17directory_optionsE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem20__create_directoriesERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem21__temp_directory_pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem26__create_directory_symlinkERKNS1_4pathES4_PNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem28recursive_directory_iterator11__incrementEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem28recursive_directory_iterator15__try_recursionEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem28recursive_directory_iterator5__popEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem28recursive_directory_iterator9__advanceEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem28recursive_directory_iteratorC1ERKNS1_4pathENS1_17directory_optionsEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem28recursive_directory_iteratorC2ERKNS1_4pathENS1_17directory_optionsEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem4path17replace_extensionERKS2_'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem4path8iterator11__decrementEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem4path8iterator11__incrementEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem6__copyERKNS1_4pathES4_NS1_12copy_optionsEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem7__spaceERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem8__removeERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem8__renameERKNS1_4pathES4_PNS_10error_codeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE'}
-{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem16_FilesystemClock9is_steadyE', 'size': 0}
-{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem4path19preferred_separatorE', 'size': 0}
-{'type': 'OBJECT', 'is_defined': True, 'name': '__ZTINSt3__14__fs10filesystem16filesystem_errorE', 'size': 0}
-{'type': 'OBJECT', 'is_defined': True, 'name': '__ZTSNSt3__14__fs10filesystem16filesystem_errorE', 'size': 0}
-{'type': 'OBJECT', 'is_defined': True, 'name': '__ZTVNSt3__14__fs10filesystem16filesystem_errorE', 'size': 0}
Modified: libcxx/trunk/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/CMakeLists.txt?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/test/CMakeLists.txt (original)
+++ libcxx/trunk/test/CMakeLists.txt Tue Mar 19 12:27:29 2019
@@ -28,6 +28,7 @@ endif()
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/input.output/filesystems/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/input.output/filesystems/lit.local.cfg?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/input.output/filesystems/lit.local.cfg (added)
+++ libcxx/trunk/test/libcxx/input.output/filesystems/lit.local.cfg Tue Mar 19 12:27:29 2019
@@ -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/lit.site.cfg.in
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/lit.site.cfg.in?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/test/lit.site.cfg.in (original)
+++ libcxx/trunk/test/lit.site.cfg.in Tue Mar 19 12:27:29 2019
@@ -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/input.output/filesystems/Inputs/static_test_env/bad_symlink
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink (added)
+++ libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink Tue Mar 19 12:27:29 2019
@@ -0,0 +1 @@
+link dne
\ No newline at end of file
Propchange: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink
------------------------------------------------------------------------------
svn:special = *
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/afile3
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/afile3?rev=356505&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/dir3/file5
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/dir3/file5?rev=356505&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/file4
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/file4?rev=356505&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 (added)
+++ libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 Tue Mar 19 12:27:29 2019
@@ -0,0 +1 @@
+link dir3
\ No newline at end of file
Propchange: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3
------------------------------------------------------------------------------
svn:special = *
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/file1
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/file1?rev=356505&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/file2
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/file2?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/file2 (added)
+++ libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/dir1/file2 Tue Mar 19 12:27:29 2019
@@ -0,0 +1 @@
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
\ No newline at end of file
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/empty_file
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/empty_file?rev=356505&view=auto
==============================================================================
(empty)
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/non_empty_file
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/non_empty_file?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/non_empty_file (added)
+++ libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/non_empty_file Tue Mar 19 12:27:29 2019
@@ -0,0 +1 @@
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
\ No newline at end of file
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir (added)
+++ libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir Tue Mar 19 12:27:29 2019
@@ -0,0 +1 @@
+link dir1
\ No newline at end of file
Propchange: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir
------------------------------------------------------------------------------
svn:special = *
Added: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file (added)
+++ libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file Tue Mar 19 12:27:29 2019
@@ -0,0 +1 @@
+link empty_file
\ No newline at end of file
Propchange: libcxx/trunk/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file
------------------------------------------------------------------------------
svn:special = *
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// directory_entry(const directory_entry&) = default;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+#include "test_convertible.hpp"
+
+TEST_SUITE(directory_entry_path_ctor_suite)
+
+TEST_CASE(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);
+ }
+}
+
+TEST_CASE(copy_ctor_copies_cache) {
+ using namespace fs;
+ 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");
+
+ {
+ directory_entry ent(sym);
+
+ fs::remove(sym);
+
+ directory_entry ent_cp(ent);
+ TEST_CHECK(ent_cp.path() == sym);
+ TEST_CHECK(ent_cp.is_symlink());
+ }
+
+ {
+ directory_entry ent(file);
+
+ fs::remove(file);
+
+ directory_entry ent_cp(ent);
+ TEST_CHECK(ent_cp.path() == file);
+ TEST_CHECK(ent_cp.is_regular_file());
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy_assign.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/copy_assign.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+TEST_SUITE(directory_entry_ctor_suite)
+
+TEST_CASE(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);
+ }
+}
+
+TEST_CASE(copy_assign_copies_cache) {
+ using namespace fs;
+ 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");
+
+ {
+ directory_entry ent(sym);
+
+ fs::remove(sym);
+
+ directory_entry ent_cp;
+ ent_cp = ent;
+ TEST_CHECK(ent_cp.path() == sym);
+ TEST_CHECK(ent_cp.is_symlink());
+ }
+
+ {
+ directory_entry ent(file);
+
+ fs::remove(file);
+
+ directory_entry ent_cp;
+ ent_cp = ent;
+ TEST_CHECK(ent_cp.path() == file);
+ TEST_CHECK(ent_cp.is_regular_file());
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// directory_entry() noexcept = default;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+int main(int, char**) {
+ 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());
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default_const.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default_const.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default_const.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/default_const.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+// XFAIL: apple-clang-7, clang-3.7, clang-3.8
+
+// <filesystem>
+
+// class directory_entry
+
+// directory_entry() noexcept = default;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+int main(int, char**) {
+ using namespace fs;
+ // Default
+ {
+ static_assert(std::is_nothrow_default_constructible<directory_entry>::value,
+ "directory_entry must have a nothrow default constructor");
+ const directory_entry e;
+ assert(e.path() == path());
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// directory_entry(directory_entry&&) noexcept = default;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+#include "test_convertible.hpp"
+
+TEST_SUITE(directory_entry_path_ctor_suite)
+
+TEST_CASE(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.
+ }
+}
+
+TEST_CASE(move_ctor_copies_cache) {
+ using namespace fs;
+ 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");
+
+ {
+ directory_entry ent(sym);
+
+ fs::remove(sym);
+
+ directory_entry ent_cp(std::move(ent));
+ TEST_CHECK(ent_cp.path() == sym);
+ TEST_CHECK(ent_cp.is_symlink());
+ }
+
+ {
+ directory_entry ent(file);
+
+ fs::remove(file);
+
+ directory_entry ent_cp(std::move(ent));
+ TEST_CHECK(ent_cp.path() == file);
+ TEST_CHECK(ent_cp.is_regular_file());
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move_assign.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/move_assign.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+TEST_SUITE(directory_entry_ctor_suite)
+
+TEST_CASE(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
+ }
+}
+
+TEST_CASE(move_assign_copies_cache) {
+ using namespace fs;
+ 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");
+
+ {
+ directory_entry ent(sym);
+
+ fs::remove(sym);
+
+ directory_entry ent_cp;
+ ent_cp = std::move(ent);
+ TEST_CHECK(ent_cp.path() == sym);
+ TEST_CHECK(ent_cp.is_symlink());
+ }
+
+ {
+ directory_entry ent(file);
+
+ fs::remove(file);
+
+ directory_entry ent_cp;
+ ent_cp = std::move(ent);
+ TEST_CHECK(ent_cp.path() == file);
+ TEST_CHECK(ent_cp.is_regular_file());
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,181 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// explicit directory_entry(const path);
+// directory_entry(const path&, error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+#include "test_convertible.hpp"
+
+TEST_SUITE(directory_entry_path_ctor_suite)
+
+TEST_CASE(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);
+ TEST_CHECK(e.path() == p);
+ }
+}
+
+TEST_CASE(path_ec_ctor) {
+ using namespace fs;
+ {
+ static_assert(
+ std::is_constructible<directory_entry, const path&,
+ std::error_code&>::value,
+ "directory_entry must be constructible from path and error_code");
+ static_assert(!std::is_nothrow_constructible<directory_entry, const path&,
+ std::error_code&>::value,
+ "directory_entry constructor should not be noexcept");
+ static_assert(
+ test_convertible<directory_entry, const path&, std::error_code&>(),
+ "directory_entry constructor should not be explicit");
+ }
+ {
+ std::error_code ec = GetTestEC();
+ const directory_entry e(StaticEnv::File, ec);
+ TEST_CHECK(e.path() == StaticEnv::File);
+ TEST_CHECK(!ec);
+ }
+ {
+ const path p("foo/bar/baz");
+ std::error_code ec = GetTestEC();
+ const directory_entry e(p, ec);
+ TEST_CHECK(e.path() == p);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+ }
+}
+
+TEST_CASE(path_ctor_calls_refresh) {
+ using namespace fs;
+ 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");
+
+ {
+ directory_entry ent(file);
+ std::error_code ec = GetTestEC();
+ directory_entry ent_ec(file, ec);
+ TEST_CHECK(!ec);
+
+ LIBCPP_ONLY(remove(file));
+
+ TEST_CHECK(ent.exists());
+ TEST_CHECK(ent_ec.exists());
+
+ TEST_CHECK(ent.file_size() == 42);
+ TEST_CHECK(ent_ec.file_size() == 42);
+ }
+
+ env.create_file("dir/file", 101);
+
+ {
+ directory_entry ent(sym);
+ std::error_code ec = GetTestEC();
+ directory_entry ent_ec(sym, ec);
+ TEST_CHECK(!ec);
+
+ LIBCPP_ONLY(remove(file));
+ LIBCPP_ONLY(remove(sym));
+
+ TEST_CHECK(ent.is_symlink());
+ TEST_CHECK(ent_ec.is_symlink());
+
+ TEST_CHECK(ent.is_regular_file());
+ TEST_CHECK(ent_ec.is_regular_file());
+
+ TEST_CHECK(ent.file_size() == 101);
+ TEST_CHECK(ent_ec.file_size() == 101);
+ }
+}
+
+TEST_CASE(path_ctor_dne) {
+ using namespace fs;
+
+ {
+ std::error_code ec = GetTestEC();
+ directory_entry ent(StaticEnv::DNE, ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+ TEST_CHECK(ent.path() == StaticEnv::DNE);
+ }
+ // don't report dead symlinks as an error.
+ {
+ std::error_code ec = GetTestEC();
+ directory_entry ent(StaticEnv::BadSymlink, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ent.path() == StaticEnv::BadSymlink);
+ }
+ // DNE does not cause the constructor to throw
+ {
+ directory_entry ent(StaticEnv::DNE);
+ TEST_CHECK(ent.path() == StaticEnv::DNE);
+
+ directory_entry ent_two(StaticEnv::BadSymlink);
+ TEST_CHECK(ent_two.path() == StaticEnv::BadSymlink);
+ }
+}
+
+TEST_CASE(path_ctor_cannot_resolve) {
+ using namespace fs;
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path file_out_of_dir = env.create_file("file1", 101);
+ const path sym_out_of_dir = env.create_symlink("dir/file", "sym");
+ const path sym_in_dir = env.create_symlink("dir/file1", "dir/sym2");
+ permissions(dir, perms::none);
+
+ {
+ std::error_code ec = GetTestEC();
+ directory_entry ent(file, ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ TEST_CHECK(ent.path() == file);
+ }
+ {
+ std::error_code ec = GetTestEC();
+ directory_entry ent(sym_in_dir, ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ TEST_CHECK(ent.path() == sym_in_dir);
+ }
+ {
+ std::error_code ec = GetTestEC();
+ directory_entry ent(sym_out_of_dir, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ent.path() == sym_out_of_dir);
+ }
+ {
+ TEST_CHECK_NO_THROW(directory_entry(file));
+ TEST_CHECK_NO_THROW(directory_entry(sym_in_dir));
+ TEST_CHECK_NO_THROW(directory_entry(sym_out_of_dir));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,131 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+TEST_SUITE(directory_entry_mods_suite)
+
+TEST_CASE(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");
+ }
+ {
+ TEST_CHECK(e.path() == p);
+ e.assign(p2);
+ TEST_CHECK(e.path() == p2 && e.path() != p);
+ e.assign(p);
+ TEST_CHECK(e.path() == p && e.path() != p2);
+ }
+}
+
+TEST_CASE(test_path_assign_ec_method) {
+ using namespace fs;
+ const path p("foo/bar/baz");
+ const path p2("abc");
+ {
+ std::error_code ec;
+ directory_entry e(p);
+ static_assert(std::is_same<decltype(e.assign(p, ec)), void>::value,
+ "return type should be void");
+ static_assert(noexcept(e.assign(p, ec)) == false,
+ "operation must not be noexcept");
+ }
+ {
+ directory_entry ent(p);
+ std::error_code ec = GetTestEC();
+ ent.assign(p2, ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+ TEST_CHECK(ent.path() == p2);
+ }
+}
+
+TEST_CASE(test_assign_calls_refresh) {
+ using namespace fs;
+ 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");
+
+ {
+ directory_entry ent;
+ ent.assign(file);
+
+ // removing the file demonstrates that the values where cached previously.
+ LIBCPP_ONLY(remove(file));
+
+ TEST_CHECK(ent.is_regular_file());
+ }
+ env.create_file("dir/file", 101);
+ {
+ directory_entry ent;
+ ent.assign(sym);
+
+ LIBCPP_ONLY(remove(file));
+ LIBCPP_ONLY(remove(sym));
+
+ TEST_CHECK(ent.is_symlink());
+ TEST_CHECK(ent.is_regular_file());
+ }
+}
+
+TEST_CASE(test_assign_propagates_error) {
+ using namespace fs;
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path sym_out_of_dir = env.create_symlink("dir/file", "sym");
+ const path file_out_of_dir = env.create_file("file1");
+ const path sym_in_dir = env.create_symlink("file1", "dir/sym1");
+
+ permissions(dir, perms::none);
+
+ {
+ directory_entry ent;
+ std::error_code ec = GetTestEC();
+ ent.assign(file, ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ }
+ {
+ directory_entry ent;
+ std::error_code ec = GetTestEC();
+ ent.assign(sym_in_dir, ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ }
+ {
+ directory_entry ent;
+ std::error_code ec = GetTestEC();
+ ent.assign(sym_out_of_dir, ec);
+ TEST_CHECK(!ec);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/refresh.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/refresh.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/refresh.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/refresh.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,340 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+TEST_SUITE(directory_entry_mods_suite)
+
+TEST_CASE(test_refresh_method) {
+ using namespace fs;
+ {
+ directory_entry e;
+ static_assert(noexcept(e.refresh()) == false,
+ "operation cannot be noexcept");
+ static_assert(std::is_same<decltype(e.refresh()), void>::value,
+ "operation must return void");
+ }
+ {
+ directory_entry e;
+ e.refresh();
+ TEST_CHECK(!e.exists());
+ }
+}
+
+TEST_CASE(test_refresh_ec_method) {
+ using namespace fs;
+ {
+ directory_entry e;
+ std::error_code ec;
+ static_assert(noexcept(e.refresh(ec)), "operation should be noexcept");
+ static_assert(std::is_same<decltype(e.refresh(ec)), void>::value,
+ "operation must return void");
+ }
+ {
+ directory_entry e;
+ std::error_code ec = GetTestEC();
+ e.refresh(ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+ }
+}
+
+TEST_CASE(refresh_on_file_dne) {
+ using namespace fs;
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+
+ const perms old_perms = status(dir).permissions();
+
+ // test file doesn't exist
+ {
+ directory_entry ent(file);
+ remove(file);
+ TEST_CHECK(ent.exists());
+
+ ent.refresh();
+
+ permissions(dir, perms::none);
+ TEST_CHECK(!ent.exists());
+ }
+ permissions(dir, old_perms);
+ env.create_file("dir/file", 101);
+ {
+ directory_entry ent(file);
+ remove(file);
+ TEST_CHECK(ent.exists());
+
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ permissions(dir, perms::none);
+ TEST_CHECK(!ent.exists());
+ }
+}
+
+void remove_if_exists(const fs::path& p) {
+ std::error_code ec;
+ remove(p, ec);
+}
+
+TEST_CASE(refresh_on_bad_symlink) {
+ using namespace fs;
+ 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");
+
+ const perms old_perms = status(dir).permissions();
+
+ // test file doesn't exist
+ {
+ directory_entry ent(sym);
+ LIBCPP_ONLY(remove(file));
+ TEST_CHECK(ent.is_symlink());
+ TEST_CHECK(ent.is_regular_file());
+ TEST_CHECK(ent.exists());
+
+ remove_if_exists(file);
+ ent.refresh();
+
+ LIBCPP_ONLY(permissions(dir, perms::none));
+ TEST_CHECK(ent.is_symlink());
+ TEST_CHECK(!ent.is_regular_file());
+ TEST_CHECK(!ent.exists());
+ }
+ permissions(dir, old_perms);
+ env.create_file("dir/file", 101);
+ {
+ directory_entry ent(sym);
+ LIBCPP_ONLY(remove(file));
+ TEST_CHECK(ent.is_symlink());
+ TEST_CHECK(ent.is_regular_file());
+ TEST_CHECK(ent.exists());
+
+ remove_if_exists(file);
+
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+ TEST_CHECK(!ec); // we don't report bad symlinks as an error.
+
+ LIBCPP_ONLY(permissions(dir, perms::none));
+ TEST_CHECK(!ent.exists());
+ }
+}
+
+TEST_CASE(refresh_cannot_resolve) {
+ using namespace fs;
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path file_out_of_dir = env.create_file("file1", 99);
+ const path sym_out_of_dir = env.create_symlink("dir/file", "sym");
+ const path sym_in_dir = env.create_symlink("file1", "dir/sym1");
+ perms old_perms = status(dir).permissions();
+
+ {
+ directory_entry ent(file);
+ permissions(dir, perms::none);
+
+ TEST_CHECK(ent.is_regular_file());
+
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ TEST_CHECK(ent.path() == file);
+
+ ExceptionChecker Checker(file, std::errc::permission_denied,
+ "directory_entry::refresh");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.refresh());
+ }
+ permissions(dir, old_perms);
+ {
+ directory_entry ent(sym_in_dir);
+ permissions(dir, perms::none);
+ TEST_CHECK(ent.is_symlink());
+
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ TEST_CHECK(ent.path() == sym_in_dir);
+
+ ExceptionChecker Checker(sym_in_dir, std::errc::permission_denied,
+ "directory_entry::refresh");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.refresh());
+ }
+ permissions(dir, old_perms);
+ {
+ directory_entry ent(sym_out_of_dir);
+ permissions(dir, perms::none);
+ TEST_CHECK(ent.is_symlink());
+
+ // Failure to resolve the linked entity due to permissions is not
+ // reported as an error.
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ent.is_symlink());
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.exists(ec) == false);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ TEST_CHECK(ent.path() == sym_out_of_dir);
+ }
+ permissions(dir, old_perms);
+ {
+ directory_entry ent_file(file);
+ directory_entry ent_sym(sym_in_dir);
+ directory_entry ent_sym2(sym_out_of_dir);
+ permissions(dir, perms::none);
+ ((void)ent_file);
+ ((void)ent_sym);
+
+ TEST_CHECK_THROW(filesystem_error, ent_file.refresh());
+ TEST_CHECK_THROW(filesystem_error, ent_sym.refresh());
+ TEST_CHECK_NO_THROW(ent_sym2);
+ }
+}
+
+TEST_CASE(refresh_doesnt_throw_on_dne_but_reports_it) {
+ using namespace fs;
+ scoped_test_env env;
+
+ const path file = env.create_file("file1", 42);
+ const path sym = env.create_symlink("file1", "sym");
+
+ {
+ directory_entry ent(file);
+ TEST_CHECK(ent.file_size() == 42);
+
+ remove(file);
+
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+ TEST_CHECK_NO_THROW(ent.refresh());
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ // doesn't throw!
+ TEST_CHECK_THROW(filesystem_error, ent.file_size());
+ }
+ env.create_file("file1", 99);
+ {
+ directory_entry ent(sym);
+ TEST_CHECK(ent.is_symlink());
+ TEST_CHECK(ent.is_regular_file());
+ TEST_CHECK(ent.file_size() == 99);
+
+ remove(file);
+
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+ TEST_CHECK(!ec);
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ TEST_CHECK_THROW(filesystem_error, ent.file_size());
+ }
+}
+
+TEST_CASE(access_cache_after_refresh_fails) {
+ using namespace fs;
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path file_out_of_dir = env.create_file("file1", 101);
+ const path sym = env.create_symlink("dir/file", "sym");
+ const path sym_in_dir = env.create_symlink("dir/file", "dir/sym2");
+
+ const perms old_perms = status(dir).permissions();
+
+#define CHECK_ACCESS(func, expect) \
+ ec = GetTestEC(); \
+ TEST_CHECK(ent.func(ec) == expect); \
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied))
+
+ // test file doesn't exist
+ {
+ directory_entry ent(file);
+
+ TEST_CHECK(!ent.is_symlink());
+ TEST_CHECK(ent.is_regular_file());
+ TEST_CHECK(ent.exists());
+
+ permissions(dir, perms::none);
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ CHECK_ACCESS(exists, false);
+ CHECK_ACCESS(is_symlink, false);
+ CHECK_ACCESS(last_write_time, file_time_type::min());
+ CHECK_ACCESS(hard_link_count, uintmax_t(-1));
+ }
+ permissions(dir, old_perms);
+ {
+ directory_entry ent(sym_in_dir);
+ TEST_CHECK(ent.is_symlink());
+ TEST_CHECK(ent.is_regular_file());
+ TEST_CHECK(ent.exists());
+
+ permissions(dir, perms::none);
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ CHECK_ACCESS(exists, false);
+ CHECK_ACCESS(is_symlink, false);
+ CHECK_ACCESS(last_write_time, file_time_type::min());
+ CHECK_ACCESS(hard_link_count, uintmax_t(-1));
+ }
+ permissions(dir, old_perms);
+ {
+ directory_entry ent(sym);
+ TEST_CHECK(ent.is_symlink());
+ TEST_CHECK(ent.is_regular_file());
+ TEST_CHECK(ent.exists());
+
+ permissions(dir, perms::none);
+ std::error_code ec = GetTestEC();
+ ent.refresh(ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ent.is_symlink());
+
+ CHECK_ACCESS(exists, false);
+ CHECK_ACCESS(is_regular_file, false);
+ CHECK_ACCESS(last_write_time, file_time_type::min());
+ CHECK_ACCESS(hard_link_count, uintmax_t(-1));
+ }
+#undef CHECK_ACCESS
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/replace_filename.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/replace_filename.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/replace_filename.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/replace_filename.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,168 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+TEST_SUITE(directory_entry_mods_suite)
+
+TEST_CASE(test_replace_filename_method) {
+ using namespace fs;
+
+ {
+ directory_entry e;
+ path replace;
+ 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");
+ }
+ {
+ const path p("/path/to/foo.exe");
+ const path replace("bar.out");
+ const path expect("/path/to/bar.out");
+ directory_entry e(p);
+ TEST_CHECK(e.path() == p);
+ e.replace_filename(replace);
+ TEST_CHECK(e.path() == expect);
+ }
+}
+
+TEST_CASE(test_replace_filename_ec_method) {
+ using namespace fs;
+
+ {
+ directory_entry e;
+ path replace;
+ std::error_code ec;
+ static_assert(noexcept(e.replace_filename(replace, ec)) == false,
+ "operation cannot be noexcept");
+ static_assert(
+ std::is_same<decltype(e.replace_filename(replace, ec)), void>::value,
+ "operation must return void");
+ }
+ {
+ const path p("/path/to/foo.exe");
+ const path replace("bar.out");
+ const path expect("/path/to/bar.out");
+ directory_entry e(p);
+ TEST_CHECK(e.path() == p);
+ std::error_code ec = GetTestEC();
+ e.replace_filename(replace, ec);
+ TEST_CHECK(e.path() == expect);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+ }
+ {
+ const path p = StaticEnv::EmptyFile;
+ const path expect = StaticEnv::NonEmptyFile;
+ const path replace = StaticEnv::NonEmptyFile.filename();
+ TEST_REQUIRE(expect.parent_path() == p.parent_path());
+ directory_entry e(p);
+ TEST_CHECK(e.path() == p);
+ std::error_code ec = GetTestEC();
+ e.replace_filename(replace, ec);
+ TEST_CHECK(e.path() == expect);
+ TEST_CHECK(!ec);
+ }
+}
+
+TEST_CASE(test_replace_filename_calls_refresh) {
+ using namespace fs;
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path file_two = env.create_file("dir/file_two", 101);
+ const path sym = env.create_symlink("dir/file", "sym");
+ const path sym_two = env.create_symlink("dir/file_two", "sym_two");
+
+ {
+ directory_entry ent(file);
+ ent.replace_filename(file_two.filename());
+ TEST_REQUIRE(ent.path() == file_two);
+
+ // removing the file demonstrates that the values where cached previously.
+ LIBCPP_ONLY(remove(file_two));
+
+ TEST_CHECK(ent.file_size() == 101);
+ }
+ env.create_file("dir/file_two", 99);
+ {
+ directory_entry ent(sym);
+ ent.replace_filename(sym_two.filename());
+ TEST_REQUIRE(ent.path() == sym_two);
+
+ LIBCPP_ONLY(remove(file_two));
+ LIBCPP_ONLY(remove(sym_two));
+
+ TEST_CHECK(ent.is_symlink());
+ TEST_CHECK(ent.is_regular_file());
+ TEST_CHECK(ent.file_size() == 99);
+ }
+}
+
+TEST_CASE(test_replace_filename_propagates_error) {
+ using namespace fs;
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path file_two = env.create_file("dir/file_two", 99);
+ const path file_out_of_dir = env.create_file("file_three", 101);
+ const path sym_out_of_dir = env.create_symlink("dir/file", "sym");
+ const path sym_out_of_dir_two = env.create_symlink("dir/file", "sym_two");
+ const path sym_in_dir = env.create_symlink("file_two", "dir/sym_three");
+ const path sym_in_dir_two = env.create_symlink("file_two", "dir/sym_four");
+
+ const perms old_perms = status(dir).permissions();
+
+ {
+ directory_entry ent(file);
+ permissions(dir, perms::none);
+ std::error_code ec = GetTestEC();
+ ent.replace_filename(file_two.filename(), ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ }
+ permissions(dir, old_perms);
+ {
+ directory_entry ent(sym_in_dir);
+ permissions(dir, perms::none);
+ std::error_code ec = GetTestEC();
+ ent.replace_filename(sym_in_dir_two.filename(), ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ }
+ permissions(dir, old_perms);
+ {
+ directory_entry ent(sym_out_of_dir);
+ permissions(dir, perms::none);
+ std::error_code ec = GetTestEC();
+ ent.replace_filename(sym_out_of_dir_two.filename(), ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ent.is_symlink());
+ ec = GetTestEC();
+ TEST_CHECK(!ent.exists(ec));
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/comparisons.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/comparisons.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/comparisons.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/comparisons.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+
+#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(int, char**) {
+ test_comparison_signatures();
+ test_comparisons_simple();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,241 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// uintmax_t file_size() const;
+// uintmax_t file_size(error_code const&) const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "filesystem_test_helper.hpp"
+#include "rapid-cxx-test.hpp"
+
+#include <iostream>
+
+TEST_SUITE(directory_entry_obs_testsuite)
+
+TEST_CASE(signatures) {
+ using namespace fs;
+ {
+ const fs::directory_entry e = {};
+ std::error_code ec;
+ static_assert(std::is_same<decltype(e.file_size()), uintmax_t>::value, "");
+ static_assert(std::is_same<decltype(e.file_size(ec)), uintmax_t>::value,
+ "");
+ static_assert(noexcept(e.file_size()) == false, "");
+ static_assert(noexcept(e.file_size(ec)) == true, "");
+ }
+}
+
+TEST_CASE(basic) {
+ using namespace fs;
+
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+ const path sym = env.create_symlink("file", "sym");
+
+ {
+ directory_entry ent(file);
+ uintmax_t expect = file_size(ent);
+ TEST_CHECK(expect == 42);
+
+ // Remove the file to show that the results were already in the cache.
+ LIBCPP_ONLY(remove(file));
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == expect);
+ TEST_CHECK(!ec);
+ }
+ env.create_file("file", 99);
+ {
+ directory_entry ent(sym);
+
+ uintmax_t expect = file_size(ent);
+ TEST_CHECK(expect == 99);
+
+ LIBCPP_ONLY(remove(ent));
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == 99);
+ TEST_CHECK(!ec);
+ }
+}
+
+TEST_CASE(not_regular_file) {
+ using namespace fs;
+
+ scoped_test_env env;
+ struct {
+ const path p;
+ std::errc expected_err;
+ } TestCases[] = {
+ {env.create_dir("dir"), std::errc::is_a_directory},
+ {env.create_fifo("fifo"), std::errc::not_supported},
+ {env.create_symlink("dir", "sym"), std::errc::is_a_directory}};
+
+ for (auto const& TC : TestCases) {
+ const path& p = TC.p;
+ directory_entry ent(p);
+ TEST_CHECK(ent.path() == p);
+ std::error_code ec = GetTestEC(0);
+
+ std::error_code other_ec = GetTestEC(1);
+ uintmax_t expect = file_size(p, other_ec);
+
+ uintmax_t got = ent.file_size(ec);
+ TEST_CHECK(got == expect);
+ TEST_CHECK(got == uintmax_t(-1));
+ TEST_CHECK(ec == other_ec);
+ TEST_CHECK(ErrorIs(ec, TC.expected_err));
+
+ ExceptionChecker Checker(p, TC.expected_err, "directory_entry::file_size");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.file_size());
+ }
+}
+
+TEST_CASE(error_reporting) {
+ using namespace fs;
+
+ scoped_test_env env;
+
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path file_out_of_dir = env.create_file("file2", 101);
+ const path sym_out_of_dir = env.create_symlink("dir/file", "sym");
+ const path sym_in_dir = env.create_symlink("file2", "dir/sym2");
+
+ const perms old_perms = status(dir).permissions();
+
+ // test a file which doesn't exist
+ {
+ directory_entry ent;
+
+ std::error_code ec = GetTestEC();
+ ent.assign(StaticEnv::DNE, ec);
+ TEST_REQUIRE(ent.path() == StaticEnv::DNE);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ExceptionChecker Checker(StaticEnv::DNE,
+ std::errc::no_such_file_or_directory,
+ "directory_entry::file_size");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.file_size());
+ }
+ // test a dead symlink
+ {
+ directory_entry ent;
+
+ std::error_code ec = GetTestEC();
+ uintmax_t expect_bad = file_size(StaticEnv::BadSymlink, ec);
+ TEST_CHECK(expect_bad == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ec = GetTestEC();
+ ent.assign(StaticEnv::BadSymlink, ec);
+ TEST_REQUIRE(ent.path() == StaticEnv::BadSymlink);
+ TEST_CHECK(!ec);
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == expect_bad);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ExceptionChecker Checker(StaticEnv::BadSymlink,
+ std::errc::no_such_file_or_directory,
+ "directory_entry::file_size");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.file_size());
+ }
+ // test a file w/o appropriate permissions.
+ {
+ directory_entry ent;
+ uintmax_t expect_good = file_size(file);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ ent.assign(file, ec);
+ TEST_REQUIRE(ent.path() == file);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(file, std::errc::permission_denied, "file_size");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.file_size());
+
+ permissions(dir, old_perms);
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == expect_good);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.file_size());
+ }
+ permissions(dir, old_perms);
+ // test a symlink w/o appropriate permissions.
+ {
+ directory_entry ent;
+ uintmax_t expect_good = file_size(sym_in_dir);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ ent.assign(sym_in_dir, ec);
+ TEST_REQUIRE(ent.path() == sym_in_dir);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(sym_in_dir, std::errc::permission_denied,
+ "file_size");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.file_size());
+
+ permissions(dir, old_perms);
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == expect_good);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.file_size());
+ }
+ permissions(dir, old_perms);
+ // test a symlink to a file w/o appropriate permissions
+ {
+ directory_entry ent;
+ uintmax_t expect_good = file_size(sym_out_of_dir);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ ent.assign(sym_out_of_dir, ec);
+ TEST_REQUIRE(ent.path() == sym_out_of_dir);
+ TEST_CHECK(!ec);
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(sym_out_of_dir, std::errc::permission_denied,
+ "file_size");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.file_size());
+
+ permissions(dir, old_perms);
+ ec = GetTestEC();
+ TEST_CHECK(ent.file_size(ec) == expect_good);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.file_size());
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,257 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// file_status status() const;
+// file_status status(error_code const&) const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "filesystem_test_helper.hpp"
+#include "rapid-cxx-test.hpp"
+
+TEST_SUITE(directory_entry_obs_testsuite)
+
+TEST_CASE(file_dne) {
+ using namespace fs;
+ directory_entry p("dne");
+}
+
+TEST_CASE(signatures) {
+ using namespace fs;
+ const directory_entry e = {};
+ std::error_code ec;
+#define TEST_FUNC(name) \
+ static_assert(std::is_same<decltype(e.name()), bool>::value, \
+ "wrong return type"); \
+ static_assert(noexcept(e.name()) == false, "should not be noexcept"); \
+ static_assert(std::is_same<decltype(e.name(ec)), bool>::value, \
+ "wrong return type"); \
+ static_assert(noexcept(e.name(ec)) == true, "should be noexcept")
+
+ TEST_FUNC(exists);
+ TEST_FUNC(is_block_file);
+ TEST_FUNC(is_character_file);
+ TEST_FUNC(is_directory);
+ TEST_FUNC(is_fifo);
+ TEST_FUNC(is_other);
+ TEST_FUNC(is_regular_file);
+ TEST_FUNC(is_socket);
+ TEST_FUNC(is_symlink);
+
+#undef TEST_FUNC
+}
+
+TEST_CASE(test_without_ec) {
+ using namespace fs;
+ using fs::directory_entry;
+ using fs::file_status;
+ using fs::path;
+
+ scoped_test_env env;
+ path f = env.create_file("foo", 42);
+ path d = env.create_dir("dir");
+ path fifo = env.create_fifo("fifo");
+ path hl = env.create_hardlink("foo", "hl");
+ for (auto p : {hl, f, d, fifo}) {
+ directory_entry e(p);
+ file_status st = status(p);
+ file_status sym_st = symlink_status(p);
+ fs::remove(p);
+ TEST_REQUIRE(e.exists());
+ TEST_REQUIRE(!exists(p));
+ TEST_CHECK(e.exists() == exists(st));
+ TEST_CHECK(e.is_block_file() == is_block_file(st));
+ TEST_CHECK(e.is_character_file() == is_character_file(st));
+ TEST_CHECK(e.is_directory() == is_directory(st));
+ TEST_CHECK(e.is_fifo() == is_fifo(st));
+ TEST_CHECK(e.is_other() == is_other(st));
+ TEST_CHECK(e.is_regular_file() == is_regular_file(st));
+ TEST_CHECK(e.is_socket() == is_socket(st));
+ TEST_CHECK(e.is_symlink() == is_symlink(sym_st));
+ }
+}
+
+TEST_CASE(test_with_ec) {
+ using namespace fs;
+ using fs::directory_entry;
+ using fs::file_status;
+ using fs::path;
+
+ scoped_test_env env;
+ path f = env.create_file("foo", 42);
+ path d = env.create_dir("dir");
+ path fifo = env.create_fifo("fifo");
+ path hl = env.create_hardlink("foo", "hl");
+ for (auto p : {hl, f, d, fifo}) {
+ directory_entry e(p);
+ std::error_code status_ec = GetTestEC();
+ std::error_code sym_status_ec = GetTestEC(1);
+ file_status st = status(p, status_ec);
+ file_status sym_st = symlink_status(p, sym_status_ec);
+ fs::remove(p);
+ std::error_code ec = GetTestEC(2);
+ auto CheckEC = [&](std::error_code const& other_ec) {
+ bool res = ec == other_ec;
+ ec = GetTestEC(2);
+ return res;
+ };
+
+ TEST_REQUIRE(e.exists(ec));
+ TEST_CHECK(CheckEC(status_ec));
+ TEST_REQUIRE(!exists(p));
+
+ TEST_CHECK(e.exists(ec) == exists(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_block_file(ec) == is_block_file(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_character_file(ec) == is_character_file(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_directory(ec) == is_directory(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_fifo(ec) == is_fifo(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_other(ec) == is_other(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_regular_file(ec) == is_regular_file(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_socket(ec) == is_socket(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_symlink(ec) == is_symlink(sym_st));
+ TEST_CHECK(CheckEC(sym_status_ec));
+ }
+}
+
+TEST_CASE(test_with_ec_dne) {
+ using namespace fs;
+ using fs::directory_entry;
+ using fs::file_status;
+ using fs::path;
+
+ for (auto p : {StaticEnv::DNE, StaticEnv::BadSymlink}) {
+
+ directory_entry e(p);
+ std::error_code status_ec = GetTestEC();
+ std::error_code sym_status_ec = GetTestEC(1);
+ file_status st = status(p, status_ec);
+ file_status sym_st = symlink_status(p, sym_status_ec);
+ std::error_code ec = GetTestEC(2);
+ auto CheckEC = [&](std::error_code const& other_ec) {
+ bool res = ec == other_ec;
+ ec = GetTestEC(2);
+ return res;
+ };
+
+ TEST_CHECK(e.exists(ec) == exists(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_block_file(ec) == is_block_file(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_character_file(ec) == is_character_file(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_directory(ec) == is_directory(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_fifo(ec) == is_fifo(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_other(ec) == is_other(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_regular_file(ec) == is_regular_file(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_socket(ec) == is_socket(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_symlink(ec) == is_symlink(sym_st));
+ TEST_CHECK(CheckEC(sym_status_ec));
+ }
+}
+
+TEST_CASE(test_with_ec_cannot_resolve) {
+ using namespace fs;
+ using fs::directory_entry;
+ using fs::file_status;
+ using fs::path;
+
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path file_out_of_dir = env.create_file("file2", 99);
+ const path sym = env.create_symlink("file2", "dir/sym");
+
+ perms old_perms = fs::status(dir).permissions();
+
+ for (auto p : {file, sym}) {
+ permissions(dir, old_perms);
+ directory_entry e(p);
+
+ permissions(dir, perms::none);
+ std::error_code dummy_ec;
+ e.refresh(dummy_ec);
+ TEST_REQUIRE(dummy_ec);
+
+ std::error_code status_ec = GetTestEC();
+ std::error_code sym_status_ec = GetTestEC(1);
+ file_status st = status(p, status_ec);
+ file_status sym_st = symlink_status(p, sym_status_ec);
+ std::error_code ec = GetTestEC(2);
+ auto CheckEC = [&](std::error_code const& other_ec) {
+ bool res = ec == other_ec;
+ ec = GetTestEC(2);
+ return res;
+ };
+
+ TEST_CHECK(e.exists(ec) == exists(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_block_file(ec) == is_block_file(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_character_file(ec) == is_character_file(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_directory(ec) == is_directory(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_fifo(ec) == is_fifo(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_other(ec) == is_other(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_regular_file(ec) == is_regular_file(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_socket(ec) == is_socket(st));
+ TEST_CHECK(CheckEC(status_ec));
+
+ TEST_CHECK(e.is_symlink(ec) == is_symlink(sym_st));
+ TEST_CHECK(CheckEC(sym_status_ec));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,241 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// uintmax_t hard_link_count() const;
+// uintmax_t hard_link_count(error_code const&) const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "filesystem_test_helper.hpp"
+#include "rapid-cxx-test.hpp"
+
+TEST_SUITE(directory_entry_obs_testsuite)
+
+TEST_CASE(signatures) {
+ using namespace fs;
+ {
+ const directory_entry e = {};
+ std::error_code ec;
+ static_assert(std::is_same<decltype(e.hard_link_count()), uintmax_t>::value, "");
+ static_assert(std::is_same<decltype(e.hard_link_count(ec)), uintmax_t>::value,
+ "");
+ static_assert(noexcept(e.hard_link_count()) == false, "");
+ static_assert(noexcept(e.hard_link_count(ec)) == true, "");
+ }
+}
+
+TEST_CASE(basic) {
+ using namespace fs;
+
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+ const path sym = env.create_symlink("file", "sym");
+
+ {
+ directory_entry ent(file);
+ uintmax_t expect = hard_link_count(ent);
+
+ // Remove the file to show that the results were already in the cache.
+ LIBCPP_ONLY(remove(file));
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == expect);
+ TEST_CHECK(!ec);
+ }
+ {
+ directory_entry ent(dir);
+ uintmax_t expect = hard_link_count(ent);
+
+ LIBCPP_ONLY(remove(dir));
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == expect);
+ TEST_CHECK(!ec);
+ }
+ env.create_file("file", 99);
+ env.create_hardlink("file", "hl");
+ {
+ directory_entry ent(sym);
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == 2);
+ TEST_CHECK(!ec);
+ }
+}
+
+TEST_CASE(not_regular_file) {
+ using namespace fs;
+
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir2 = env.create_dir("dir/dir2");
+ const path fifo = env.create_fifo("dir/fifo");
+ const path sym_to_fifo = env.create_symlink("dir/fifo", "dir/sym");
+
+ const perms old_perms = status(dir).permissions();
+
+ for (auto p : {dir2, fifo, sym_to_fifo}) {
+ permissions(dir, old_perms);
+ std::error_code dummy_ec = GetTestEC();
+ directory_entry ent(p, dummy_ec);
+ TEST_CHECK(!dummy_ec);
+
+ uintmax_t expect = hard_link_count(p);
+
+ LIBCPP_ONLY(permissions(dir, perms::none));
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == expect);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.hard_link_count());
+ }
+}
+
+TEST_CASE(error_reporting) {
+ using namespace fs;
+
+ scoped_test_env env;
+
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path file_out_of_dir = env.create_file("file2", 101);
+ const path sym_out_of_dir = env.create_symlink("dir/file", "sym");
+ const path sym_in_dir = env.create_symlink("file2", "dir/sym2");
+
+ const perms old_perms = status(dir).permissions();
+
+ // test a file which doesn't exist
+ {
+ directory_entry ent;
+
+ std::error_code ec = GetTestEC();
+ ent.assign(StaticEnv::DNE, ec);
+ TEST_CHECK(ec);
+ TEST_REQUIRE(ent.path() == StaticEnv::DNE);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ExceptionChecker Checker(StaticEnv::DNE,
+ std::errc::no_such_file_or_directory,
+ "directory_entry::hard_link_count");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.hard_link_count());
+ }
+ // test a dead symlink
+ {
+ directory_entry ent;
+
+ std::error_code ec = GetTestEC();
+ uintmax_t expect_bad = hard_link_count(StaticEnv::BadSymlink, ec);
+ TEST_CHECK(expect_bad == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ec = GetTestEC();
+ ent.assign(StaticEnv::BadSymlink, ec);
+ TEST_REQUIRE(ent.path() == StaticEnv::BadSymlink);
+ TEST_CHECK(!ec);
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == expect_bad);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ExceptionChecker Checker(StaticEnv::BadSymlink,
+ std::errc::no_such_file_or_directory,
+ "directory_entry::hard_link_count");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.hard_link_count());
+ }
+ // test a file w/o appropriate permissions.
+ {
+ directory_entry ent;
+ uintmax_t expect_good = hard_link_count(file);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ ent.assign(file, ec);
+ TEST_REQUIRE(ent.path() == file);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(file, std::errc::permission_denied,
+ "hard_link_count");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.hard_link_count());
+
+ permissions(dir, old_perms);
+ ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == expect_good);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.hard_link_count());
+ }
+ permissions(dir, old_perms);
+ // test a symlink w/o appropriate permissions.
+ {
+ directory_entry ent;
+ uintmax_t expect_good = hard_link_count(sym_in_dir);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ ent.assign(sym_in_dir, ec);
+ TEST_REQUIRE(ent.path() == sym_in_dir);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(sym_in_dir, std::errc::permission_denied,
+ "hard_link_count");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.hard_link_count());
+
+ permissions(dir, old_perms);
+ ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == expect_good);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.hard_link_count());
+ }
+ permissions(dir, old_perms);
+ // test a symlink to a file w/o appropriate permissions
+ {
+ directory_entry ent;
+ uintmax_t expect_good = hard_link_count(sym_out_of_dir);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ ent.assign(sym_out_of_dir, ec);
+ TEST_REQUIRE(ent.path() == sym_out_of_dir);
+ TEST_CHECK(!ec);
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == uintmax_t(-1));
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(sym_out_of_dir, std::errc::permission_denied,
+ "hard_link_count");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.hard_link_count());
+
+ permissions(dir, old_perms);
+ ec = GetTestEC();
+ TEST_CHECK(ent.hard_link_count(ec) == expect_good);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.hard_link_count());
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,214 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// file_time_type last_write_time() const;
+// file_time_type last_write_time(error_code const&) const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "filesystem_test_helper.hpp"
+#include "rapid-cxx-test.hpp"
+
+TEST_SUITE(directory_entry_obs_testsuite)
+
+TEST_CASE(signatures) {
+ using namespace fs;
+ {
+ const fs::directory_entry e = {};
+ std::error_code ec;
+ static_assert(std::is_same<decltype(e.last_write_time()), file_time_type>::value,
+ "");
+ static_assert(std::is_same<decltype(e.last_write_time(ec)), file_time_type>::value,
+ "");
+ static_assert(noexcept(e.last_write_time()) == false, "");
+ static_assert(noexcept(e.last_write_time(ec)) == true, "");
+ }
+}
+
+TEST_CASE(basic) {
+ using namespace fs;
+
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+ const path sym = env.create_symlink("file", "sym");
+
+ {
+ directory_entry ent(file);
+ file_time_type expect = last_write_time(ent);
+
+ // Remove the file to show that the results were already in the cache.
+ LIBCPP_ONLY(remove(file));
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == expect);
+ TEST_CHECK(!ec);
+ }
+ {
+ directory_entry ent(dir);
+ file_time_type expect = last_write_time(ent);
+
+ LIBCPP_ONLY(remove(dir));
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == expect);
+ TEST_CHECK(!ec);
+ }
+ env.create_file("file", 99);
+ {
+ directory_entry ent(sym);
+ file_time_type expect = last_write_time(sym);
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == expect);
+ TEST_CHECK(!ec);
+ }
+}
+
+TEST_CASE(error_reporting) {
+ using namespace fs;
+
+ scoped_test_env env;
+
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path file_out_of_dir = env.create_file("file2", 101);
+ const path sym_out_of_dir = env.create_symlink("dir/file", "sym");
+ const path sym_in_dir = env.create_symlink("file2", "dir/sym2");
+
+ const perms old_perms = status(dir).permissions();
+
+ // test a file which doesn't exist
+ {
+ directory_entry ent;
+
+ std::error_code ec = GetTestEC();
+ ent.assign(StaticEnv::DNE, ec);
+ TEST_REQUIRE(ent.path() == StaticEnv::DNE);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == file_time_type::min());
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ExceptionChecker Checker(StaticEnv::DNE,
+ std::errc::no_such_file_or_directory,
+ "directory_entry::last_write_time");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.last_write_time());
+ }
+ // test a dead symlink
+ {
+ directory_entry ent;
+
+ std::error_code ec = GetTestEC();
+ file_time_type expect_bad = last_write_time(StaticEnv::BadSymlink, ec);
+ TEST_CHECK(expect_bad == file_time_type::min());
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ec = GetTestEC();
+ ent.assign(StaticEnv::BadSymlink, ec);
+ TEST_REQUIRE(ent.path() == StaticEnv::BadSymlink);
+ TEST_CHECK(!ec);
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == expect_bad);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+
+ ExceptionChecker Checker(StaticEnv::BadSymlink,
+ std::errc::no_such_file_or_directory,
+ "directory_entry::last_write_time");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.last_write_time());
+ }
+ // test a file w/o appropriate permissions.
+ {
+ directory_entry ent;
+ file_time_type expect_good = last_write_time(file);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ ent.assign(file, ec);
+ TEST_REQUIRE(ent.path() == file);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == file_time_type::min());
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(file, std::errc::permission_denied,
+ "last_write_time");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.last_write_time());
+
+ permissions(dir, old_perms);
+ ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == expect_good);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.last_write_time());
+ }
+ permissions(dir, old_perms);
+ // test a symlink w/o appropriate permissions.
+ {
+ directory_entry ent;
+ file_time_type expect_good = last_write_time(sym_in_dir);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ ent.assign(sym_in_dir, ec);
+ TEST_REQUIRE(ent.path() == sym_in_dir);
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == file_time_type::min());
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(sym_in_dir, std::errc::permission_denied,
+ "last_write_time");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.last_write_time());
+
+ permissions(dir, old_perms);
+ ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == expect_good);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.last_write_time());
+ }
+ permissions(dir, old_perms);
+ // test a symlink to a file w/o appropriate permissions
+ {
+ directory_entry ent;
+ file_time_type expect_good = last_write_time(sym_out_of_dir);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ ent.assign(sym_out_of_dir, ec);
+ TEST_REQUIRE(ent.path() == sym_out_of_dir);
+ TEST_CHECK(!ec);
+
+ ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == file_time_type::min());
+ TEST_CHECK(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(sym_out_of_dir, std::errc::permission_denied,
+ "last_write_time");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.last_write_time());
+
+ permissions(dir, old_perms);
+ ec = GetTestEC();
+ TEST_CHECK(ent.last_write_time(ec) == expect_good);
+ TEST_CHECK(!ec);
+ TEST_CHECK_NO_THROW(ent.last_write_time());
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/path.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/path.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/path.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/path.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// const path& path() const noexcept;
+// operator const path&() const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+
+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(int, char**) {
+ test_path_method();
+ test_path_conversion();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// file_status status() const;
+// file_status status(error_code const&) const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "filesystem_test_helper.hpp"
+#include "rapid-cxx-test.hpp"
+
+TEST_SUITE(directory_entry_status_testsuite)
+
+TEST_CASE(test_basic) {
+ using namespace fs;
+ {
+ const fs::directory_entry e("foo");
+ std::error_code ec;
+ static_assert(std::is_same<decltype(e.status()), fs::file_status>::value, "");
+ static_assert(std::is_same<decltype(e.status(ec)), fs::file_status>::value, "");
+ static_assert(noexcept(e.status()) == false, "");
+ static_assert(noexcept(e.status(ec)) == true, "");
+ }
+ path TestCases[] = {StaticEnv::File, StaticEnv::Dir, StaticEnv::SymlinkToFile,
+ StaticEnv::DNE};
+ for (const auto& p : TestCases) {
+ const directory_entry e(p);
+ std::error_code pec = GetTestEC(), eec = GetTestEC(1);
+ file_status ps = fs::status(p, pec);
+ file_status es = e.status(eec);
+ TEST_CHECK(ps.type() == es.type());
+ TEST_CHECK(ps.permissions() == es.permissions());
+ TEST_CHECK(pec == eec);
+ }
+ for (const auto& p : TestCases) {
+ const directory_entry e(p);
+ file_status ps = fs::status(p);
+ file_status es = e.status();
+ TEST_CHECK(ps.type() == es.type());
+ TEST_CHECK(ps.permissions() == es.permissions());
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_entry
+
+// file_status symlink_status() const;
+// file_status symlink_status(error_code&) const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "filesystem_test_helper.hpp"
+#include "rapid-cxx-test.hpp"
+
+TEST_SUITE(directory_entry_obs_suite)
+
+TEST_CASE(test_signature) {
+ 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, "");
+ }
+ path TestCases[] = {StaticEnv::File, StaticEnv::Dir, StaticEnv::SymlinkToFile,
+ StaticEnv::DNE};
+ for (const auto& p : TestCases) {
+ const directory_entry e(p);
+ std::error_code pec = GetTestEC(), eec = GetTestEC(1);
+ file_status ps = fs::symlink_status(p, pec);
+ file_status es = e.symlink_status(eec);
+ TEST_CHECK(ps.type() == es.type());
+ TEST_CHECK(ps.permissions() == es.permissions());
+ TEST_CHECK(pec == eec);
+ }
+ for (const auto& p : TestCases) {
+ const directory_entry e(p);
+ file_status ps = fs::symlink_status(p);
+ file_status es = e.symlink_status();
+ TEST_CHECK(ps.type() == es.type());
+ TEST_CHECK(ps.permissions() == es.permissions());
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_iterator
+
+// directory_iterator(directory_iterator const&);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_iterator
+
+// directory_iterator& operator=(directory_iterator const&);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,253 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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);
+// directory_iterator(const path& p, directory_options options, error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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&)
+ static_assert(std::is_constructible<D, path,
+ std::error_code&>::value, "");
+ 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&)
+ static_assert(std::is_constructible<D, path, directory_options,
+ std::error_code&>::value, "");
+ 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 fs;
+ 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 fs;
+ 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/input.output/filesystems/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_iterator
+
+// directory_iterator::directory_iterator() noexcept
+
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+
+int main(int, char**) {
+ {
+ static_assert(std::is_nothrow_default_constructible<fs::directory_iterator>::value, "");
+ }
+ {
+ fs::directory_iterator d1;
+ const fs::directory_iterator d2;
+ assert(d1 == d2);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_iterator
+
+// directory_iterator& operator++();
+// directory_iterator& increment(error_code& ec);
+
+#include "filesystem_include.hpp"
+#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 fs;
+
+TEST_SUITE(directory_iterator_increment_tests)
+
+TEST_CASE(test_increment_signatures)
+{
+ 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_NOT_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/input.output/filesystems/class.directory_iterator/directory_iterator.members/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/move.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/move.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/move.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_iterator
+
+// directory_iterator(directory_iterator&&) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_iterator
+
+// directory_iterator& operator=(directory_iterator const&);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+// The filesystem specification explicitly allows for self-move on
+// the directory iterators. Turn off this warning so we can test it.
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wself-move"
+#endif
+
+using namespace fs;
+
+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/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_iterator
+
+// directory_iterator begin(directory_iterator iter) noexcept;
+// directory_iterator end(directory_iterator iter) noexcept;
+
+#include "filesystem_include.hpp"
+#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 fs;
+
+TEST_SUITE(directory_iterator_begin_end_tests)
+
+TEST_CASE(test_function_signatures)
+{
+ 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/input.output/filesystems/class.directory_iterator/types.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/types.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/types.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.directory_iterator/types.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class directory_iterator
+
+// typedef ... value_type;
+// typedef ... difference_type;
+// typedef ... pointer;
+// typedef ... reference;
+// typedef ... iterator_category
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+
+int main(int, char**) {
+ 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);
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.cons.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.cons.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.cons.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.cons.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class file_status
+
+// explicit file_status() noexcept;
+// explicit file_status(file_type, perms prms = perms::unknown) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_convertible.hpp"
+
+
+int main(int, char**) {
+ 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 not 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.mods.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.mods.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.mods.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.mods.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class file_status
+
+// void type(file_type) noexcept;
+// void permissions(perms) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+
+int main(int, char**) {
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.obs.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.obs.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.obs.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.file_status/file_status.obs.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class file_status
+
+// file_type type() const noexcept;
+// perms permissions(p) const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+
+int main(int, char**) {
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.filesystem_error/filesystem_error.members.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.filesystem_error/filesystem_error.members.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.filesystem_error/filesystem_error.members.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.filesystem_error/filesystem_error.members.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+
+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(int, char**) {
+ static_assert(std::is_base_of<std::system_error, fs::filesystem_error>::value, "");
+ test_constructors();
+ test_signatures();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.itr/iterator.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.itr/iterator.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.itr/iterator.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.itr/iterator.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// template <class Source>
+// path(const Source& source);
+// template <class InputIterator>
+// path(InputIterator first, InputIterator last);
+
+
+#include "filesystem_include.hpp"
+#include <iterator>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+
+
+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(checkCollectionsEqualBackwards(p.begin(), p.end(), std::begin(expect), std::end(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(checkCollectionsEqualBackwards(p.begin(), p.end(), std::begin(expect), std::end(expect)));
+
+ }
+
+}
+
+int main(int, char**) {
+ using namespace fs;
+ checkIteratorConcepts();
+ checkBeginEndBasic(); // See path.decompose.pass.cpp for more tests.
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,340 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <string_view>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+#include "verbose_assert.h"
+
+
+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("/p2")}
+ , {S("p1/"), S("/p2"), S("/p2")}
+ , {S("p1"), S("\\p2"), S("p1/\\p2")}
+ , {S("p1\\"), S("p2"), S("p1\\/p2")}
+ , {S("p1\\"), S("\\p2"), S("p1\\/\\p2")}
+ , {S(""), S("p2"), S("p2")}
+ , {S("/p1"), S("p2"), S("/p1/p2")}
+ , {S("/p1"), S("/p2"), S("/p2")}
+ , {S("/p1/p3"), S("p2"), S("/p1/p3/p2")}
+ , {S("/p1/p3/"), S("p2"), S("/p1/p3/p2")}
+ , {S("/p1/"), S("p2"), S("/p1/p2")}
+ , {S("/p1/p3/"), S("/p2/p4"), S("/p2/p4")}
+ , {S("/"), S(""), S("/")}
+ , {S("/p1"), S("/p2/"), S("/p2/")}
+ , {S("p1"), S(""), S("p1/")}
+ , {S("p1/"), S(""), S("p1/")}
+ };
+
+
+const AppendOperatorTestcase LongLHSCases[] =
+ {
+ {S("p1"), S("p2"), S("p1/p2")}
+ , {S("p1/"), S("p2"), S("p1/p2")}
+ , {S("p1"), S("/p2"), S("/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 StrView = std::basic_string_view<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_PRED(PathEq, LHS , E);
+ }
+ // basic_string_view
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ StrView RHS(R);
+ {
+ DisableAllocationGuard g;
+ LHS /= RHS;
+ }
+ assert(PathEq(LHS, E));
+ }
+ // CharT*
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ Ptr RHS(R);
+ {
+ DisableAllocationGuard g;
+ LHS /= RHS;
+ }
+ assert(PathEq(LHS, E));
+ }
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ Ptr RHS(R);
+ {
+ DisableAllocationGuard g;
+ LHS.append(RHS, StrEnd(RHS));
+ }
+ assert(PathEq(LHS, E));
+ }
+ // input iterator - For non-native char types, appends needs to copy the
+ // iterator range into a contiguous 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(PathEq(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(PathEq(LHS, E));
+ }
+}
+
+template <class CharT>
+void doAppendSourceTest(AppendOperatorTestcase const& TC)
+{
+ using namespace fs;
+ using Ptr = CharT const*;
+ using Str = std::basic_string<CharT>;
+ using StrView = std::basic_string_view<CharT>;
+ using InputIter = input_iterator<Ptr>;
+ const Ptr L = TC.lhs;
+ const Ptr R = TC.rhs;
+ const Ptr E = TC.expect;
+ // basic_string
+ {
+ path Result(L);
+ Str RHS(R);
+ path& Ref = (Result /= RHS);
+ ASSERT_EQ(Result, E)
+ << DISPLAY(L) << DISPLAY(R);
+ assert(&Ref == &Result);
+ }
+ {
+ path LHS(L);
+ Str RHS(R);
+ path& Ref = LHS.append(RHS);
+ assert(PathEq(LHS, E));
+ assert(&Ref == &LHS);
+ }
+ // basic_string_view
+ {
+ path LHS(L);
+ StrView RHS(R);
+ path& Ref = (LHS /= RHS);
+ assert(PathEq(LHS, E));
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ StrView RHS(R);
+ path& Ref = LHS.append(RHS);
+ assert(PathEq(LHS, E));
+ assert(&Ref == &LHS);
+ }
+ // Char*
+ {
+ path LHS(L);
+ Str RHS(R);
+ path& Ref = (LHS /= RHS);
+ assert(PathEq(LHS, E));
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ Ptr RHS(R);
+ path& Ref = LHS.append(RHS);
+ assert(PathEq(LHS, E));
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ Ptr RHS(R);
+ path& Ref = LHS.append(RHS, StrEnd(RHS));
+ ASSERT_PRED(PathEq, LHS, E)
+ << DISPLAY(L) << DISPLAY(R);
+ assert(&Ref == &LHS);
+ }
+ // iterators
+ {
+ path LHS(L);
+ InputIter RHS(R);
+ path& Ref = (LHS /= RHS);
+ assert(PathEq(LHS, E));
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L); InputIter RHS(R);
+ path& Ref = LHS.append(RHS);
+ assert(PathEq(LHS, E));
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ InputIter RHS(R);
+ InputIter REnd(StrEnd(R));
+ path& Ref = LHS.append(RHS, REnd);
+ assert(PathEq(LHS, E));
+ assert(&Ref == &LHS);
+ }
+}
+
+
+
+template <class It, class = decltype(fs::path{}.append(std::declval<It>()))>
+constexpr bool has_append(int) { return true; }
+template <class It>
+constexpr bool has_append(long) { return false; }
+
+template <class It, class = decltype(fs::path{}.operator/=(std::declval<It>()))>
+constexpr bool has_append_op(int) { return true; }
+template <class It>
+constexpr bool has_append_op(long) { return false; }
+
+template <class It>
+constexpr bool has_append() {
+ static_assert(has_append<It>(0) == has_append_op<It>(0), "must be same");
+ return has_append<It>(0) && has_append_op<It>(0);
+}
+
+void test_sfinae()
+{
+ using namespace fs;
+ {
+ using It = const char* const;
+ static_assert(has_append<It>(), "");
+ }
+ {
+ using It = input_iterator<const char*>;
+ static_assert(has_append<It>(), "");
+ }
+ {
+ struct Traits {
+ using iterator_category = std::input_iterator_tag;
+ using value_type = const char;
+ using pointer = const char*;
+ using reference = const char&;
+ using difference_type = std::ptrdiff_t;
+ };
+ using It = input_iterator<const char*, Traits>;
+ static_assert(has_append<It>(), "");
+ }
+ {
+ using It = output_iterator<const char*>;
+ static_assert(!has_append<It>(), "");
+
+ }
+ {
+ static_assert(!has_append<int*>(), "");
+ }
+ {
+ static_assert(!has_append<char>(), "");
+ static_assert(!has_append<const char>(), "");
+ }
+}
+
+int main(int, char**)
+{
+ using namespace fs;
+ for (auto const & TC : Cases) {
+ {
+ const char* LHS_In = TC.lhs;
+ const char* RHS_In = TC.rhs;
+ path LHS(LHS_In);
+ path RHS(RHS_In);
+ path& Res = (LHS /= RHS);
+ ASSERT_PRED(PathEq, Res, (const char*)TC.expect)
+ << DISPLAY(LHS_In) << DISPLAY(RHS_In);
+ assert(&Res == &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);
+ }
+ test_sfinae();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/braced_init.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/braced_init.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/braced_init.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/braced_init.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path& operator=(path const&);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+
+
+int main(int, char**) {
+ using namespace fs;
+ path p("abc");
+ p = {};
+ assert(p.native() == "");
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/copy.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/copy.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path& operator=(path const&);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+
+int main(int, char**) {
+ 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);
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path& operator=(path&&) noexcept
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+
+
+int main(int, char**) {
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,242 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// template <class Source>
+// path& operator=(Source const&);
+// path& operator=(string_type&&);
+// template <class Source>
+// path& assign(Source const&);
+// template <class InputIterator>
+// path& assign(InputIterator first, InputIterator last);
+
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <string_view>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+#include <iostream>
+
+
+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 contiguous 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);
+ }
+ // basic_string<Char, Traits, Alloc>
+ {
+ const std::basic_string_view<CharT> S(TestPath);
+ path p; PathReserve(p, S.length() + 1);
+ {
+ // string provides a contiguous 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_view<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 contiguous 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);
+ }
+}
+
+template <class It, class = decltype(fs::path{}.assign(std::declval<It>()))>
+constexpr bool has_assign(int) { return true; }
+template <class It>
+constexpr bool has_assign(long) { return false; }
+template <class It>
+constexpr bool has_assign() { return has_assign<It>(0); }
+
+void test_sfinae() {
+ using namespace fs;
+ {
+ using It = const char* const;
+ static_assert(std::is_assignable<path, It>::value, "");
+ static_assert(has_assign<It>(), "");
+ }
+ {
+ using It = input_iterator<const char*>;
+ static_assert(std::is_assignable<path, It>::value, "");
+ static_assert(has_assign<It>(), "");
+ }
+ {
+ struct Traits {
+ using iterator_category = std::input_iterator_tag;
+ using value_type = const char;
+ using pointer = const char*;
+ using reference = const char&;
+ using difference_type = std::ptrdiff_t;
+ };
+ using It = input_iterator<const char*, Traits>;
+ static_assert(std::is_assignable<path, It>::value, "");
+ static_assert(has_assign<It>(), "");
+ }
+ {
+ using It = output_iterator<const char*>;
+ static_assert(!std::is_assignable<path, It>::value, "");
+ static_assert(!has_assign<It>(), "");
+
+ }
+ {
+ static_assert(!std::is_assignable<path, int*>::value, "");
+ static_assert(!has_assign<int*>(), "");
+ }
+}
+
+void RunStringMoveTest(const char* Expect) {
+ using namespace fs;
+ std::string ss(Expect);
+ path p;
+ {
+ DisableAllocationGuard g; ((void)g);
+ path& pr = (p = std::move(ss));
+ assert(&pr == &p);
+ }
+ assert(p == Expect);
+ {
+ // Signature test
+ ASSERT_NOEXCEPT(p = std::move(ss));
+ }
+}
+
+int main(int, char**) {
+ for (auto const& MS : PathList) {
+ RunTestCase<char>(MS);
+ RunTestCase<wchar_t>(MS);
+ RunTestCase<char16_t>(MS);
+ RunTestCase<char32_t>(MS);
+ RunStringMoveTest(MS);
+ }
+ test_sfinae();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,192 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+#include "verbose_assert.h"
+
+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/.", -1},
+ {"a/b/", "a/b", 1},
+ {"a/b//////", "a/b/////.", -1},
+ {"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
+ {"foo", "/foo", -1}, // if !this->has_root_directory() and p.has_root_directory(), a value less than 0.
+ {"/foo", "foo", 1}, // if this->has_root_directory() and !p.has_root_directory(), a value greater than 0.
+ {"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0},
+ { LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1}
+
+};
+#undef LONGA
+#undef LONGB
+#undef LONGC
+#undef LONGD
+
+static inline int normalize_ret(int ret)
+{
+ return ret < 0 ? -1 : (ret > 0 ? 1 : 0);
+}
+
+void test_compare_basic()
+{
+ 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 std::string_view RV(TC.RHS);
+ const int E = TC.expect;
+ { // compare(...) functions
+ DisableAllocationGuard g; // none of these operations should allocate
+
+ // check runtime results
+ int ret1 = normalize_ret(p1.compare(p2));
+ int ret2 = normalize_ret(p1.compare(R));
+ int ret3 = normalize_ret(p1.compare(TC.RHS));
+ int ret4 = normalize_ret(p1.compare(RV));
+
+ g.release();
+ ASSERT_EQ(ret1, ret2);
+ ASSERT_EQ(ret1, ret3);
+ ASSERT_EQ(ret1, ret4);
+ ASSERT_EQ(ret1, E)
+ << DISPLAY(TC.LHS) << DISPLAY(TC.RHS);
+
+ // 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));
+ }
+ }
+}
+
+int CompareElements(std::vector<std::string> const& LHS, std::vector<std::string> const& RHS) {
+ bool IsLess = std::lexicographical_compare(LHS.begin(), LHS.end(), RHS.begin(), RHS.end());
+ if (IsLess)
+ return -1;
+
+ bool IsGreater = std::lexicographical_compare(RHS.begin(), RHS.end(), LHS.begin(), LHS.end());
+ if (IsGreater)
+ return 1;
+
+ return 0;
+}
+
+void test_compare_elements() {
+ struct {
+ std::vector<std::string> LHSElements;
+ std::vector<std::string> RHSElements;
+ int Expect;
+ } TestCases[] = {
+ {{"a"}, {"a"}, 0},
+ {{"a"}, {"b"}, -1},
+ {{"b"}, {"a"}, 1},
+ {{"a", "b", "c"}, {"a", "b", "c"}, 0},
+ {{"a", "b", "c"}, {"a", "b", "d"}, -1},
+ {{"a", "b", "d"}, {"a", "b", "c"}, 1},
+ {{"a", "b"}, {"a", "b", "c"}, -1},
+ {{"a", "b", "c"}, {"a", "b"}, 1},
+
+ };
+
+ auto BuildPath = [](std::vector<std::string> const& Elems) {
+ fs::path p;
+ for (auto &E : Elems)
+ p /= E;
+ return p;
+ };
+
+ for (auto &TC : TestCases) {
+ fs::path LHS = BuildPath(TC.LHSElements);
+ fs::path RHS = BuildPath(TC.RHSElements);
+ const int ExpectCmp = CompareElements(TC.LHSElements, TC.RHSElements);
+ assert(ExpectCmp == TC.Expect);
+ const int GotCmp = normalize_ret(LHS.compare(RHS));
+ assert(GotCmp == TC.Expect);
+ }
+}
+
+int main(int, char**) {
+ test_compare_basic();
+ test_compare_elements();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,389 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path& operator+=(const path& x);
+// path& operator+=(const string_type& x);
+// path& operator+=(string_view x);
+// path& operator+=(const value_type* x);
+// 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 "filesystem_include.hpp"
+#include <type_traits>
+#include <string>
+#include <string_view>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+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 StrView = std::basic_string_view<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);
+ }
+ // basic_string_view
+ {
+ path LHS(L); PathReserve(LHS, ReserveSize);
+ StrView 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 contiguous 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 StrView = std::basic_string_view<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);
+ }
+ // basic_string_view
+ {
+ path LHS(L);
+ StrView RHS(R);
+ path& Ref = (LHS += RHS);
+ assert(LHS == E);
+ assert(&Ref == &LHS);
+ }
+ {
+ path LHS(L);
+ StrView 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);
+ }
+}
+
+
+template <class It, class = decltype(fs::path{}.concat(std::declval<It>()))>
+constexpr bool has_concat(int) { return true; }
+template <class It>
+constexpr bool has_concat(long) { return false; }
+
+template <class It, class = decltype(fs::path{}.operator+=(std::declval<It>()))>
+constexpr bool has_concat_op(int) { return true; }
+template <class It>
+constexpr bool has_concat_op(long) { return false; }
+template <class It>
+constexpr bool has_concat_op() { return has_concat_op<It>(0); }
+
+template <class It>
+constexpr bool has_concat() {
+ static_assert(has_concat<It>(0) == has_concat_op<It>(0), "must be same");
+ return has_concat<It>(0) && has_concat_op<It>(0);
+}
+
+void test_sfinae() {
+ using namespace fs;
+ {
+ static_assert(has_concat_op<char>(), "");
+ static_assert(has_concat_op<const char>(), "");
+ static_assert(has_concat_op<char16_t>(), "");
+ static_assert(has_concat_op<const char16_t>(), "");
+ }
+ {
+ using It = const char* const;
+ static_assert(has_concat<It>(), "");
+ }
+ {
+ using It = input_iterator<const char*>;
+ static_assert(has_concat<It>(), "");
+ }
+ {
+ struct Traits {
+ using iterator_category = std::input_iterator_tag;
+ using value_type = const char;
+ using pointer = const char*;
+ using reference = const char&;
+ using difference_type = std::ptrdiff_t;
+ };
+ using It = input_iterator<const char*, Traits>;
+ static_assert(has_concat<It>(), "");
+ }
+ {
+ using It = output_iterator<const char*>;
+ static_assert(!has_concat<It>(), "");
+ }
+ {
+ static_assert(!has_concat<int>(0), "");
+ // operator+=(int) is well formed since it converts to operator+=(value_type)
+ // but concat(int) isn't valid because there is no concat(value_type).
+ // This should probably be addressed by a LWG issue.
+ static_assert(has_concat_op<int>(), "");
+ }
+ {
+ static_assert(!has_concat<int*>(), "");
+ }
+}
+
+int main(int, char**)
+{
+ 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);
+ }
+ {
+ path LHS((const char*)TC.lhs);
+ std::string_view 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);
+ }
+ {
+ path LHS((const char*)TC.lhs);
+ std::string_view 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);
+ }
+ test_sfinae();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/copy.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/copy.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path(path const&)
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+
+int main(int, char**) {
+ 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);
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/default.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/default.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/default.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path() noexcept
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+
+int main(int, char**) {
+ using namespace fs;
+ static_assert(std::is_nothrow_default_constructible<path>::value, "");
+ const path p;
+ assert(p.empty());
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path(path&&) noexcept
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+
+
+int main(int, char**) {
+ 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
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,130 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// template <class Source>
+// path(const Source& source);
+// template <class InputIterator>
+// path(InputIterator first, InputIterator last);
+
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+
+template <class CharT, class ...Args>
+void RunTestCaseImpl(MultiStringType const& MS, Args... args) {
+ 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, args...);
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ assert(p.string<CharT>() == S);
+ }
+ {
+ const std::basic_string_view<CharT> S(TestPath);
+ path p(S, args...);
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ assert(p.string<CharT>() == S);
+ }
+ // Char* pointers
+ {
+ path p(TestPath, args...);
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ {
+ path p(TestPath, TestPathEnd, args...);
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ // Iterators
+ {
+ using It = input_iterator<const CharT*>;
+ path p(It{TestPath}, args...);
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+ {
+ using It = input_iterator<const CharT*>;
+ path p(It{TestPath}, It{TestPathEnd}, args...);
+ assert(p.native() == Expect);
+ assert(p.string<CharT>() == TestPath);
+ }
+}
+
+template <class CharT, class ...Args>
+void RunTestCase(MultiStringType const& MS) {
+ RunTestCaseImpl<CharT>(MS);
+ RunTestCaseImpl<CharT>(MS, fs::path::format::auto_format);
+ RunTestCaseImpl<CharT>(MS, fs::path::format::native_format);
+ RunTestCaseImpl<CharT>(MS, fs::path::format::generic_format);
+}
+
+void test_sfinae() {
+ using namespace fs;
+ {
+ using It = const char* const;
+ static_assert(std::is_constructible<path, It>::value, "");
+ }
+ {
+ using It = input_iterator<const char*>;
+ static_assert(std::is_constructible<path, It>::value, "");
+ }
+ {
+ struct Traits {
+ using iterator_category = std::input_iterator_tag;
+ using value_type = const char;
+ using pointer = const char*;
+ using reference = const char&;
+ using difference_type = std::ptrdiff_t;
+ };
+ using It = input_iterator<const char*, Traits>;
+ static_assert(std::is_constructible<path, It>::value, "");
+ }
+ {
+ using It = output_iterator<const char*>;
+ static_assert(!std::is_constructible<path, It>::value, "");
+
+ }
+ {
+ static_assert(!std::is_constructible<path, int*>::value, "");
+ }
+}
+
+int main(int, char**) {
+ for (auto const& MS : PathList) {
+ RunTestCase<char>(MS);
+ RunTestCase<wchar_t>(MS);
+ RunTestCase<char16_t>(MS);
+ RunTestCase<char32_t>(MS);
+ }
+ test_sfinae();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/empty.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/empty.fail.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/empty.fail.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/empty.fail.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,29 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <filesystem>
+
+// class path
+
+// bool empty() const noexcept;
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8
+
+#include "filesystem_include.hpp"
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ fs::path c;
+ c.empty(); // expected-error {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/path.decompose.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/path.decompose.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/path.decompose.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.decompose/path.decompose.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,217 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+#include "assert_checkpoint.h"
+#include "verbose_assert.h"
+
+struct ComparePathExact {
+ bool operator()(std::string const& LHS, std::string const& RHS) const {
+ return LHS == RHS;
+ }
+};
+
+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/foo", {"/", "net", "foo"}, "/", "", "/", "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) {
+ CHECKPOINT(TC.raw.c_str());
+ fs::path p(TC.raw);
+ ASSERT(p == TC.raw);
+
+ ASSERT_EQ(p.root_path(), TC.root_path);
+ ASSERT_NEQ(p.has_root_path(), TC.root_path.empty());
+
+ ASSERT(p.root_name().native().empty())
+ << DISPLAY(p.root_name());
+ ASSERT_EQ(p.root_name(),TC.root_name);
+ ASSERT_NEQ(p.has_root_name(), TC.root_name.empty());
+
+ ASSERT_EQ(p.root_directory(), TC.root_directory);
+ ASSERT_NEQ(p.has_root_directory(), TC.root_directory.empty());
+
+ ASSERT_EQ(p.relative_path(), TC.relative_path);
+ ASSERT_NEQ(p.has_relative_path(), TC.relative_path.empty());
+
+ ASSERT_EQ(p.parent_path(), TC.parent_path);
+ ASSERT_NEQ(p.has_parent_path(), TC.parent_path.empty());
+
+ ASSERT_EQ(p.filename(), TC.filename);
+ ASSERT_NEQ(p.has_filename(), TC.filename.empty());
+
+ ASSERT_EQ(p.is_absolute(), p.has_root_directory());
+ ASSERT_NEQ(p.is_relative(), p.is_absolute());
+ if (p.empty())
+ ASSERT(p.is_relative());
+
+ ASSERT_COLLECTION_EQ_COMP(
+ p.begin(), p.end(),
+ TC.elements.begin(), TC.elements.end(),
+ ComparePathExact()
+ );
+ // check backwards
+
+ std::vector<fs::path> Parts;
+ for (auto it = p.end(); it != p.begin(); )
+ Parts.push_back(*--it);
+ ASSERT_COLLECTION_EQ_COMP(Parts.begin(), Parts.end(),
+ TC.elements.rbegin(), TC.elements.rend(),
+ ComparePathExact());
+ }
+}
+
+
+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"}
+ , {".profile", ".profile", ".profile", ""}
+ , {".profile.txt", ".profile.txt", ".profile", ".txt"}
+};
+
+
+void decompFilenameTest()
+{
+ using namespace fs;
+ for (auto const & TC : FilenameTestCases) {
+ CHECKPOINT(TC.raw.c_str());
+ fs::path p(TC.raw);
+ ASSERT_EQ(p, TC.raw);
+ ASSERT_NOEXCEPT(p.empty());
+
+ ASSERT_EQ(p.filename(), TC.filename);
+ ASSERT_NEQ(p.has_filename(), TC.filename.empty());
+
+ ASSERT_EQ(p.stem(), TC.stem);
+ ASSERT_NEQ(p.has_stem(), TC.stem.empty());
+
+ ASSERT_EQ(p.extension(), TC.extension);
+ ASSERT_NEQ(p.has_extension(), TC.extension.empty());
+ }
+}
+
+int main(int, char**)
+{
+ decompPathTest();
+ decompFilenameTest();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,141 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path lexically_normal() const;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <vector>
+#include <iostream>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+int main(int, char**) {
+ // clang-format off
+ struct {
+ std::string input;
+ std::string expect;
+ } TestCases[] = {
+ {"", ""},
+ {"/a/b/c", "/a/b/c"},
+ {"/a/b//c", "/a/b/c"},
+ {"foo/./bar/..", "foo/"},
+ {"foo/.///bar/../", "foo/"},
+ {"/a/b/", "/a/b/"},
+ {"a/b", "a/b"},
+ {"a/b/.", "a/b/"},
+ {"a/b/./", "a/b/"},
+ {"a/..", "."},
+ {".", "."},
+ {"./", "."},
+ {"./.", "."},
+ {"./..", ".."},
+ {"..", ".."},
+ {"../..", "../.."},
+ {"/../", "/"},
+ {"/../..", "/"},
+ {"/../../", "/"},
+ {"..", ".."},
+ {"../", ".."},
+ {"/a/b/c/../", "/a/b/"},
+ {"/a/b/./", "/a/b/"},
+ {"/a/b/c/../d", "/a/b/d"},
+ {"/a/b/c/../d/", "/a/b/d/"},
+ {"//a/", "/a/"},
+ {"//a/b/", "/a/b/"},
+ {"//a/b/.", "/a/b/"},
+ {"//a/..", "/"},
+ ///===---------------------------------------------------------------===//
+ /// Tests specifically for the clauses under [fs.path.generic]p6
+ ///===---------------------------------------------------------------===//
+ // p1: If the path is empty, stop.
+ {"", ""},
+ // p2: Replace each slash character in the root-name with a preferred
+ // separator.
+ {"NO_ROOT_NAME_ON_LINUX", "NO_ROOT_NAME_ON_LINUX"},
+ // p3: Replace each directory-separator with a preferred-separator.
+ // [ Note: The generic pathname grammar ([fs.path.generic]) defines
+ // directory-separator as one or more slashes and preferred-separators.
+ // — end note ]
+ {"/", "/"},
+ {"//", "/"},
+ {"///", "/"},
+ {"a/b", "a/b"},
+ {"a//b", "a/b"},
+ {"a///b", "a/b"},
+ {"a/b/", "a/b/"},
+ {"a/b//", "a/b/"},
+ {"a/b///", "a/b/"},
+ {"///a////b//////", "/a/b/"},
+ // p4: Remove each dot filename and any immediately following directory
+ // separators
+ {"foo/.", "foo/"},
+ {"foo/./bar/.", "foo/bar/"},
+ {"./foo/././bar/./", "foo/bar/"},
+ {".///foo//.////./bar/.///", "foo/bar/"},
+ // p5: As long as any appear, remove a non-dot-dot filename immediately
+ // followed by a directory-separator and a dot-dot filename, along with
+ // any immediately following directory separator.
+ {"foo/..", "."},
+ {"foo/../", "."},
+ {"foo/bar/..", "foo/"},
+ {"foo/bar/../", "foo/"},
+ {"foo/bar/../..", "."},
+ {"foo/bar/../../", "."},
+ {"foo/bar/baz/../..", "foo/"},
+ {"foo/bar/baz/../../", "foo/"},
+ {"foo/bar/./..", "foo/"},
+ {"foo/bar/./../", "foo/"},
+ // p6: If there is a root-directory, remove all dot-dot filenames and any
+ // directory-separators immediately following them. [ Note: These dot-dot
+ // filenames attempt to refer to nonexistent parent directories. — end note ]
+ {"/..", "/"},
+ {"/../", "/"},
+ {"/foo/../..", "/"},
+ {"/../foo", "/foo"},
+ {"/../foo/../..", "/"},
+ // p7: If the last filename is dot-dot, remove any trailing
+ // directory-separator.
+ {"../", ".."},
+ {"../../", "../.."},
+ {"foo/../bar/../..///", ".."},
+ {"foo/../bar/..//..///../", "../.."},
+ // p8: If the path is empty, add a dot
+ {".", "."},
+ {"./", "."},
+ {"foo/..", "."}
+ };
+ // clang-format on
+ int ID = 0;
+ bool Failed = false;
+ for (auto& TC : TestCases) {
+ ++ID;
+ fs::path p(TC.input);
+ const fs::path output = p.lexically_normal();
+ if (!PathEq(output, TC.expect)) {
+ Failed = true;
+ std::cerr << "TEST CASE #" << ID << " FAILED: \n";
+ std::cerr << " Input: '" << TC.input << "'\n";
+ std::cerr << " Expected: '" << TC.expect << "'\n";
+ std::cerr << " Output: '" << output.native() << "'";
+ std::cerr << std::endl;
+ }
+ }
+ return Failed;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path lexically_relative(const path& p) const;
+// path lexically_proximate(const path& p) const;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <vector>
+#include <iostream>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+int main(int, char**) {
+ // clang-format off
+ struct {
+ std::string input;
+ std::string base;
+ std::string expect;
+ } TestCases[] = {
+ {"", "", "."},
+ {"/", "a", ""},
+ {"a", "/", ""},
+ {"//net", "a", ""},
+ {"a", "//net", ""},
+ {"//net/", "//net", "."},
+ {"//net", "//net/", "."},
+ {"//base", "a", ""},
+ {"a", "a", "."},
+ {"a/b", "a/b", "."},
+ {"a/b/c/", "a/b/c/", "."},
+ {"//net", "//net", "."},
+ {"//net/", "//net/", "."},
+ {"//net/a/b", "//net/a/b", "."},
+ {"/a/d", "/a/b/c", "../../d"},
+ {"/a/b/c", "/a/d", "../b/c"},
+ {"a/b/c", "a", "b/c"},
+ {"a/b/c", "a/b/c/x/y", "../.."},
+ {"a/b/c", "a/b/c", "."},
+ {"a/b", "c/d", "../../a/b"}
+ };
+ // clang-format on
+ int ID = 0;
+ bool Failed = false;
+ for (auto& TC : TestCases) {
+ ++ID;
+ const fs::path p(TC.input);
+ const fs::path output = p.lexically_relative(TC.base);
+ auto ReportErr = [&](const char* Testing, fs::path const& Output,
+ fs::path const& Expected) {
+ Failed = true;
+ std::cerr << "TEST CASE #" << ID << " FAILED: \n";
+ std::cerr << " Testing: " << Testing << "\n";
+ std::cerr << " Input: '" << TC.input << "'\n";
+ std::cerr << " Base: '" << TC.base << "'\n";
+ std::cerr << " Expected: '" << Expected << "'\n";
+ std::cerr << " Output: '" << Output.native() << "'";
+ std::cerr << std::endl;
+ };
+ if (!PathEq(output, TC.expect))
+ ReportErr("path::lexically_relative", output, TC.expect);
+ const fs::path proximate_output = p.lexically_proximate(TC.base);
+ // [path.gen] lexically_proximate
+ // Returns: If the value of lexically_relative(base) is not an empty path,
+ // return it.Otherwise return *this.
+ const fs::path proximate_expected = output.native().empty() ? p
+ : output;
+ if (!PathEq(proximate_expected, proximate_output))
+ ReportErr("path::lexically_proximate", proximate_output, proximate_expected);
+ }
+ return Failed;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#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"
+
+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(int, char**)
+{
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#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"
+
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+int main(int, char**)
+{
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/clear.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/clear.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/clear.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/clear.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// void clear() noexcept
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+int main(int, char**) {
+ using namespace fs;
+ {
+ path p;
+ ASSERT_NOEXCEPT(p.clear());
+ ASSERT_SAME_TYPE(void, decltype(p.clear()));
+ p.clear();
+ assert(p.empty());
+ }
+ {
+ const path p("/foo/bar/baz");
+ path p2(p);
+ assert(p == p2);
+ p2.clear();
+ assert(p2.empty());
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/make_preferred.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/make_preferred.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/make_preferred.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/make_preferred.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path& make_preferred()
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+struct MakePreferredTestcase {
+ const char* value;
+};
+
+const MakePreferredTestcase TestCases[] =
+ {
+ {""}
+ , {"hello_world"}
+ , {"/"}
+ , {"/foo/bar/baz/"}
+ , {"\\"}
+ , {"\\foo\\bar\\baz\\"}
+ , {"\\foo\\/bar\\/baz\\"}
+ };
+
+int main(int, char**)
+{
+ // 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/remove_filename.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/remove_filename.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/remove_filename.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/remove_filename.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path& remove_filename()
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+#include "verbose_assert.h"
+
+struct RemoveFilenameTestcase {
+ const char* value;
+ const char* expect;
+};
+
+const RemoveFilenameTestcase TestCases[] =
+ {
+ {"", ""}
+ , {"/", "/"}
+ , {"//", "//"}
+ , {"///", "///"}
+ , {"\\", ""}
+ , {".", ""}
+ , {"..", ""}
+ , {"/foo", "/"}
+ , {"foo/bar", "foo/"}
+ , {"foo/", "foo/"}
+ , {"//foo", "//"}
+ , {"//foo/", "//foo/"}
+ , {"//foo///", "//foo///"}
+ , {"///foo", "///"}
+ , {"///foo/", "///foo/"}
+ , {"/foo/", "/foo/"}
+ , {"/foo/.", "/foo/"}
+ , {"/foo/..", "/foo/"}
+ , {"/foo/////", "/foo/////"}
+ , {"/foo\\\\", "/"}
+ , {"/foo//\\/", "/foo//\\/"}
+ , {"///foo", "///"}
+ , {"file.txt", ""}
+ , {"bar/../baz/./file.txt", "bar/../baz/./"}
+ };
+
+int main(int, char**)
+{
+ 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_EQ(p, TC.expect) << DISPLAY(p_orig);
+ assert(&Ref == &p);
+ assert(!p.has_filename());
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_extension.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_extension.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_extension.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_extension.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path& replace_extension(path const& p = path())
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+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(int, char**)
+{
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_filename.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_filename.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_filename.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/replace_filename.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// path& replace_filename()
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+#include "assert_checkpoint.h"
+#include "verbose_assert.h"
+
+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(int, char**)
+{
+ using namespace fs;
+ for (auto const & TC : TestCases) {
+ path p(TC.value);
+ ASSERT_EQ(p, TC.value);
+ path& Ref = (p.replace_filename(TC.filename));
+ ASSERT_EQ(p, TC.expect)
+ << DISPLAY(TC.value)
+ << DISPLAY(TC.filename);
+ 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_EQ(p, p2);
+ }
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/swap.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/swap.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.modifiers/swap.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// void swap(path& rhs) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+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(int, char**)
+{
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/c_str.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/c_str.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/c_str.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/c_str.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,43 @@
+
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// const value_type* c_str() const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+
+int main(int, char**)
+{
+ using namespace fs;
+ const char* const value = "hello world";
+ const std::string str_value = value;
+ { // Check signature
+ path p(value);
+ 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());
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// std::string string() const;
+// std::wstring wstring() const;
+// std::u8string u8string() const;
+// std::u16string u16string() const;
+// std::u32string u32string() const;
+
+
+#include "filesystem_include.hpp"
+#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"
+
+
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+int main(int, char**)
+{
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/native.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/native.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/native.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/native.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// const string_type& native() const noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+
+int main(int, char**)
+{
+ using namespace fs;
+ const char* const value = "hello world";
+ { // Check signature
+ path p(value);
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/operator_string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/operator_string.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/operator_string.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/operator_string.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,47 @@
+
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// operator string_type() const;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+
+int main(int, char**)
+{
+ using namespace fs;
+ using string_type = path::string_type;
+ const char* const value = "hello world";
+ { // Check signature
+ path p(value);
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,138 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#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"
+
+
+// the SSO is always triggered for strings of size 2.
+MultiStringType shortString = MKSTR("a");
+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;
+ Str s = p.string<CharT>();
+ assert(s == value);
+ Str s2 = p.string<CharT>(Alloc{});
+ assert(s2 == value);
+ }
+ using MAlloc = malloc_allocator<CharT>;
+ MAlloc::reset();
+ {
+ 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() == 0);
+ }
+ 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() == 0);
+ }
+ MAlloc::reset();
+}
+
+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>;
+ 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(int, char**)
+{
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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(int, char**) {
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+#include "filesystem_include.hpp"
+
+using namespace fs;
+
+struct ConvToPath {
+ operator fs::path() const {
+ return "";
+ }
+};
+
+int main(int, char**) {
+ ConvToPath LHS, RHS;
+ (void)(LHS / RHS); // expected-error {{invalid operands to binary expression}}
+
+ return 0;
+}
\ No newline at end of file
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// path operator/(path const&, path const&);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+// This is mainly tested via the member append functions.
+int main(int, char**)
+{
+ using namespace fs;
+ path p1("abc");
+ path p2("def");
+ path p3 = p1 / p2;
+ assert(p3 == "abc/def");
+
+ path p4 = p1 / "def";
+ assert(p4 == "abc/def");
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+
+#include "filesystem_include.hpp"
+
+using namespace fs;
+
+struct ConvToPath {
+ operator fs::path() const {
+ return "";
+ }
+};
+
+int main(int, char**) {
+ ConvToPath LHS, RHS;
+ (void)(LHS == RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS != RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS < RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS <= RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS > RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS >= RHS); // expected-error {{invalid operands to binary expression}}
+
+ return 0;
+}
\ No newline at end of file
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// The comparison operators are tested as part of [path.compare]
+// in class.path/path.members/path.compare.pass.cpp
+int main(int, char**) {
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++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(int, char**) {
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.factory.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.factory.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.factory.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.factory.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// template <class Source>
+// path u8path(Source const&);
+// template <class InputIter>
+// path u8path(InputIter, InputIter);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+int main(int, char**)
+{
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <sstream>
+#include <cassert>
+#include <iostream>
+
+#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 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);
+ }
+}
+
+namespace impl {
+using namespace fs;
+
+template <class Stream, class Tp, class = decltype(std::declval<Stream&>() << std::declval<Tp&>())>
+std::true_type is_ostreamable_imp(int);
+
+template <class Stream, class Tp>
+std::false_type is_ostreamable_imp(long);
+
+template <class Stream, class Tp, class = decltype(std::declval<Stream&>() >> std::declval<Tp&>())>
+std::true_type is_istreamable_imp(int);
+
+template <class Stream, class Tp>
+std::false_type is_istreamable_imp(long);
+
+
+} // namespace impl
+
+template <class Stream, class Tp>
+struct is_ostreamable : decltype(impl::is_ostreamable_imp<Stream, Tp>(0)) {};
+template <class Stream, class Tp>
+struct is_istreamable : decltype(impl::is_istreamable_imp<Stream, Tp>(0)) {};
+
+void test_LWG2989() {
+ static_assert(!is_ostreamable<decltype(std::cout), std::wstring>::value, "");
+ static_assert(!is_ostreamable<decltype(std::wcout), std::string>::value, "");
+ static_assert(!is_istreamable<decltype(std::cin), std::wstring>::value, "");
+ static_assert(!is_istreamable<decltype(std::wcin), std::string>::value, "");
+}
+
+int main(int, char**) {
+ doIOTest<char>();
+ doIOTest<wchar_t>();
+ //doIOTest<char16_t>();
+ //doIOTest<char32_t>();
+ test_LWG2989();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.unicode_bug.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.unicode_bug.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.unicode_bug.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/path.io.unicode_bug.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#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(int, char**) {
+ doIOTest<char16_t>();
+ doIOTest<char32_t>();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/swap.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/swap.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/path.nonmember/swap.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// void swap(path& lhs, path& rhs) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+// NOTE: this is tested in path.members/path.modifiers via the member swap.
+int main(int, char**)
+{
+ 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);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.path/synop.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.path/synop.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.path/synop.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.path/synop.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path
+
+// typedef ... value_type;
+// typedef basic_string<value_type> string_type;
+// static constexpr value_type preferred_separator = ...;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+
+int main(int, char**) {
+ 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 its address.
+ const char* dummy = &path::preferred_separator;
+ ((void)dummy);
+ }
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_recursive_directory_iterator(recursive_recursive_directory_iterator const&);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,157 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator& operator=(recursive_directory_iterator const&);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,245 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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);
+// recursive_directory_iterator(const path& p, directory_options options, error_code& ec);
+
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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&)
+ static_assert(std::is_constructible<D, path,
+ std::error_code&>::value, "");
+ 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&)
+ static_assert(std::is_constructible<D, path, directory_options, std::error_code&>::value, "");
+ 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 fs;
+ 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 fs;
+ 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/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// int depth() const
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// void disable_recursion_pending();
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,494 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator& operator++();
+// recursive_directory_iterator& increment(error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+TEST_SUITE(recursive_directory_iterator_increment_tests)
+
+TEST_CASE(test_increment_signatures)
+{
+ 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_NOT_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 fs;
+ 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];
+ auto SkipEPerm = directory_options::skip_permission_denied;
+
+ // 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 = GetTestEC();
+ recursive_directory_iterator it(startDir, ec);
+ TEST_REQUIRE(ec != GetTestEC());
+ TEST_REQUIRE(!ec);
+ while (it != endIt && it->path() != permDeniedDir)
+ ++it;
+ TEST_REQUIRE(it != endIt);
+ TEST_REQUIRE(*it == permDeniedDir);
+
+ it.increment(ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(it == endIt);
+ }
+ // Same as above but test operator++().
+ {
+ std::error_code ec = GetTestEC();
+ recursive_directory_iterator it(startDir, ec);
+ TEST_REQUIRE(!ec);
+ while (it != endIt && it->path() != permDeniedDir)
+ ++it;
+ TEST_REQUIRE(it != endIt);
+ TEST_REQUIRE(*it == 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 = GetTestEC();
+ recursive_directory_iterator it(startDir, SkipEPerm, ec);
+ TEST_REQUIRE(!ec);
+ TEST_REQUIRE(it != endIt);
+
+ bool seenOtherFile = false;
+ if (*it == otherFile) {
+ ++it;
+ seenOtherFile = true;
+ TEST_REQUIRE (it != endIt);
+ }
+ TEST_REQUIRE(*it == permDeniedDir);
+
+ ec = GetTestEC();
+ it.increment(ec);
+ TEST_REQUIRE(!ec);
+
+ if (seenOtherFile) {
+ TEST_CHECK(it == endIt);
+ } else {
+ TEST_CHECK(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 above 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 = GetTestEC();
+ recursive_directory_iterator it(permDeniedDir, SkipEPerm, ec);
+ TEST_REQUIRE(!ec);
+ TEST_REQUIRE(it == endIt);
+ }
+}
+
+// See llvm.org/PR35078
+TEST_CASE(test_PR35078)
+{
+ using namespace fs;
+ scoped_test_env env;
+ const path testFiles[] = {
+ env.create_dir("dir1"),
+ env.create_dir("dir1/dir2"),
+ env.create_dir("dir1/dir2/dir3"),
+ env.create_file("dir1/file1"),
+ env.create_file("dir1/dir2/dir3/file2")
+ };
+ const path startDir = testFiles[0];
+ const path permDeniedDir = testFiles[1];
+ const path nestedDir = testFiles[2];
+ const path nestedFile = testFiles[3];
+
+ // Change the permissions so we can no longer iterate
+ permissions(permDeniedDir,
+ perms::group_exec|perms::owner_exec|perms::others_exec,
+ perm_options::remove);
+
+ const std::error_code eacess_ec =
+ std::make_error_code(std::errc::permission_denied);
+ std::error_code ec = GetTestEC();
+
+ const recursive_directory_iterator endIt;
+
+ auto SetupState = [&](bool AllowEAccess, bool& SeenFile3) {
+ SeenFile3 = false;
+ auto Opts = AllowEAccess ? directory_options::skip_permission_denied
+ : directory_options::none;
+ recursive_directory_iterator it(startDir, Opts, ec);
+ while (!ec && it != endIt && *it != nestedDir) {
+ if (*it == nestedFile)
+ SeenFile3 = true;
+ it.increment(ec);
+ }
+ return it;
+ };
+
+ {
+ bool SeenNestedFile = false;
+ recursive_directory_iterator it = SetupState(false, SeenNestedFile);
+ TEST_REQUIRE(it != endIt);
+ TEST_REQUIRE(*it == nestedDir);
+ ec = GetTestEC();
+ it.increment(ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec == eacess_ec);
+ TEST_CHECK(it == endIt);
+ }
+ {
+ bool SeenNestedFile = false;
+ recursive_directory_iterator it = SetupState(true, SeenNestedFile);
+ TEST_REQUIRE(it != endIt);
+ TEST_REQUIRE(*it == nestedDir);
+ ec = GetTestEC();
+ it.increment(ec);
+ TEST_CHECK(!ec);
+ if (SeenNestedFile) {
+ TEST_CHECK(it == endIt);
+ } else {
+ TEST_REQUIRE(it != endIt);
+ TEST_CHECK(*it == nestedFile);
+ }
+ }
+ {
+ bool SeenNestedFile = false;
+ recursive_directory_iterator it = SetupState(false, SeenNestedFile);
+ TEST_REQUIRE(it != endIt);
+ TEST_REQUIRE(*it == nestedDir);
+
+ ExceptionChecker Checker(std::errc::permission_denied,
+ "recursive_directory_iterator::operator++()",
+ format_string("attempting recursion into \"%s\"",
+ nestedDir.native()));
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ++it);
+ }
+}
+
+
+// See llvm.org/PR35078
+TEST_CASE(test_PR35078_with_symlink)
+{
+ using namespace fs;
+ scoped_test_env env;
+ const path testFiles[] = {
+ env.create_dir("dir1"),
+ env.create_file("dir1/file1"),
+ env.create_dir("sym_dir"),
+ env.create_dir("sym_dir/nested_sym_dir"),
+ env.create_symlink("sym_dir/nested_sym_dir", "dir1/dir2"),
+ env.create_dir("sym_dir/dir1"),
+ env.create_dir("sym_dir/dir1/dir2"),
+
+ };
+ // const unsigned TestFilesSize = sizeof(testFiles) / sizeof(testFiles[0]);
+ const path startDir = testFiles[0];
+ const path nestedFile = testFiles[1];
+ const path permDeniedDir = testFiles[2];
+ const path symDir = testFiles[4];
+
+ // Change the permissions so we can no longer iterate
+ permissions(permDeniedDir,
+ perms::group_exec|perms::owner_exec|perms::others_exec,
+ perm_options::remove);
+
+ const std::error_code eacess_ec =
+ std::make_error_code(std::errc::permission_denied);
+ std::error_code ec = GetTestEC();
+
+ const recursive_directory_iterator endIt;
+
+ auto SetupState = [&](bool AllowEAccess, bool FollowSym, bool& SeenFile3) {
+ SeenFile3 = false;
+ auto Opts = AllowEAccess ? directory_options::skip_permission_denied
+ : directory_options::none;
+ if (FollowSym)
+ Opts |= directory_options::follow_directory_symlink;
+ recursive_directory_iterator it(startDir, Opts, ec);
+ while (!ec && it != endIt && *it != symDir) {
+ if (*it == nestedFile)
+ SeenFile3 = true;
+ it.increment(ec);
+ }
+ return it;
+ };
+
+ struct {
+ bool SkipPermDenied;
+ bool FollowSymlinks;
+ bool ExpectSuccess;
+ } TestCases[] = {
+ // Passing cases
+ {false, false, true}, {true, true, true}, {true, false, true},
+ // Failing cases
+ {false, true, false}
+ };
+ for (auto TC : TestCases) {
+ bool SeenNestedFile = false;
+ recursive_directory_iterator it = SetupState(TC.SkipPermDenied,
+ TC.FollowSymlinks,
+ SeenNestedFile);
+ TEST_REQUIRE(!ec);
+ TEST_REQUIRE(it != endIt);
+ TEST_REQUIRE(*it == symDir);
+ ec = GetTestEC();
+ it.increment(ec);
+ if (TC.ExpectSuccess) {
+ TEST_CHECK(!ec);
+ if (SeenNestedFile) {
+ TEST_CHECK(it == endIt);
+ } else {
+ TEST_REQUIRE(it != endIt);
+ TEST_CHECK(*it == nestedFile);
+ }
+ } else {
+ TEST_CHECK(ec);
+ TEST_CHECK(ec == eacess_ec);
+ TEST_CHECK(it == endIt);
+ }
+ }
+}
+
+
+// See llvm.org/PR35078
+TEST_CASE(test_PR35078_with_symlink_file)
+{
+ using namespace fs;
+ scoped_test_env env;
+ const path testFiles[] = {
+ env.create_dir("dir1"),
+ env.create_dir("dir1/dir2"),
+ env.create_file("dir1/file2"),
+ env.create_dir("sym_dir"),
+ env.create_dir("sym_dir/sdir1"),
+ env.create_file("sym_dir/sdir1/sfile1"),
+ env.create_symlink("sym_dir/sdir1/sfile1", "dir1/dir2/file1")
+ };
+ const unsigned TestFilesSize = sizeof(testFiles) / sizeof(testFiles[0]);
+ const path startDir = testFiles[0];
+ const path nestedDir = testFiles[1];
+ const path nestedFile = testFiles[2];
+ const path permDeniedDir = testFiles[3];
+ const path symFile = testFiles[TestFilesSize - 1];
+
+ // Change the permissions so we can no longer iterate
+ permissions(permDeniedDir,
+ perms::group_exec|perms::owner_exec|perms::others_exec,
+ perm_options::remove);
+
+ const std::error_code eacess_ec =
+ std::make_error_code(std::errc::permission_denied);
+ std::error_code ec = GetTestEC();
+
+ const recursive_directory_iterator EndIt;
+
+ auto SetupState = [&](bool AllowEAccess, bool FollowSym, bool& SeenNestedFile) {
+ SeenNestedFile = false;
+ auto Opts = AllowEAccess ? directory_options::skip_permission_denied
+ : directory_options::none;
+ if (FollowSym)
+ Opts |= directory_options::follow_directory_symlink;
+ recursive_directory_iterator it(startDir, Opts, ec);
+ while (!ec && it != EndIt && *it != nestedDir) {
+ if (*it == nestedFile)
+ SeenNestedFile = true;
+ it.increment(ec);
+ }
+ return it;
+ };
+
+ struct {
+ bool SkipPermDenied;
+ bool FollowSymlinks;
+ bool ExpectSuccess;
+ } TestCases[] = {
+ // Passing cases
+ {false, false, true}, {true, true, true}, {true, false, true},
+ // Failing cases
+ {false, true, false}
+ };
+ for (auto TC : TestCases){
+ bool SeenNestedFile = false;
+ recursive_directory_iterator it = SetupState(TC.SkipPermDenied,
+ TC.FollowSymlinks,
+ SeenNestedFile);
+ TEST_REQUIRE(!ec);
+ TEST_REQUIRE(it != EndIt);
+ TEST_REQUIRE(*it == nestedDir);
+ ec = GetTestEC();
+ it.increment(ec);
+ TEST_REQUIRE(it != EndIt);
+ TEST_CHECK(!ec);
+ TEST_CHECK(*it == symFile);
+ ec = GetTestEC();
+ it.increment(ec);
+ if (TC.ExpectSuccess) {
+ if (!SeenNestedFile) {
+ TEST_CHECK(!ec);
+ TEST_REQUIRE(it != EndIt);
+ TEST_CHECK(*it == nestedFile);
+ ec = GetTestEC();
+ it.increment(ec);
+ }
+ TEST_CHECK(!ec);
+ TEST_CHECK(it == EndIt);
+ } else {
+ TEST_CHECK(ec);
+ TEST_CHECK(ec == eacess_ec);
+ TEST_CHECK(it == EndIt);
+ }
+ }
+}
+
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator(recursive_directory_iterator&&) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,168 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator& operator=(recursive_directory_iterator const&);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+// The filesystem specification explicitly allows for self-move on
+// the directory iterators. Turn off this warning so we can test it.
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wself-move"
+#endif
+
+using namespace fs;
+
+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/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// void pop();
+// void pop(error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,161 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// bool recursion_pending() const;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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;
+
+ auto& DE0 = StaticEnv::DirIterationList;
+ std::set<path> notSeenDepth0(std::begin(DE0), std::end(DE0));
+
+ recursive_directory_iterator it(StaticEnv::Dir);
+ TEST_REQUIRE(it != endIt);
+
+ while (it.depth() == 0) {
+ notSeenDepth0.erase(it->path());
+ ++it;
+ TEST_REQUIRE(it != endIt);
+ }
+ TEST_REQUIRE(it.depth() == 1);
+ it.disable_recursion_pending();
+ it.pop();
+ // Since the order of iteration is unspecified the pop() could result
+ // in the end iterator. When this is the case it is undefined behavior
+ // to call recursion_pending().
+ if (it == endIt) {
+ TEST_CHECK(notSeenDepth0.empty());
+#if defined(_LIBCPP_VERSION)
+ TEST_CHECK(it.recursion_pending() == false);
+#endif
+ } else {
+ TEST_CHECK(! notSeenDepth0.empty());
+ TEST_CHECK(it.recursion_pending() == false);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
+// recursive_directory_iterator end(recursive_directory_iterator iter) noexcept;
+
+#include "filesystem_include.hpp"
+#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 fs;
+
+TEST_SUITE(recursive_directory_iterator_begin_end_tests)
+
+TEST_CASE(test_function_signatures)
+{
+ 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/input.output/filesystems/fs.enum/check_bitmask_types.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.enum/check_bitmask_types.hpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.enum/check_bitmask_types.hpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.enum/check_bitmask_types.hpp Tue Mar 19 12:27:29 2019
@@ -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/input.output/filesystems/fs.enum/enum.copy_options.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.copy_options.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.copy_options.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.copy_options.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// enum class copy_options;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "check_bitmask_types.hpp"
+#include "test_macros.h"
+
+
+constexpr fs::copy_options ME(int val) { return static_cast<fs::copy_options>(val); }
+
+int main(int, char**) {
+ 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");
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// enum class directory_options;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+#include <sys/stat.h>
+
+#include "test_macros.h"
+#include "check_bitmask_types.hpp"
+
+
+constexpr fs::directory_options ME(int val) { return static_cast<fs::directory_options>(val); }
+
+int main(int, char**) {
+ 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");
+
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.file_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.file_type.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.file_type.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.file_type.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// enum class file_type;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+
+constexpr fs::file_type ME(int val) { return static_cast<fs::file_type>(val); }
+
+int main(int, char**) {
+ 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");
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// class path;
+// enum class format;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ typedef fs::path::format 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, "");
+
+ LIBCPP_ONLY(static_assert(std::is_same<UT, unsigned char>::value, "")); // Implementation detail
+
+ static_assert(
+ E::auto_format != E::native_format &&
+ E::auto_format != E::generic_format &&
+ E::native_format != E::generic_format,
+ "Expected enumeration values are not unique");
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// enum class perm_options;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+#include <sys/stat.h>
+
+#include "test_macros.h"
+#include "check_bitmask_types.hpp"
+
+
+constexpr fs::perm_options ME(int val) {
+ return static_cast<fs::perm_options>(val);
+}
+
+int main(int, char**) {
+ typedef fs::perm_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, ""); // Implementation detail
+
+ typedef check_bitmask_type<E, E::replace, E::nofollow> BitmaskTester;
+ assert(BitmaskTester::check());
+
+ static_assert(
+ E::replace == ME(1) &&
+ E::add == ME(2) &&
+ E::remove == ME(4) &&
+ E::nofollow == ME(8),
+ "Expected enumeration values do not match");
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// enum class perms;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+#include <sys/stat.h>
+
+#include "test_macros.h"
+#include "check_bitmask_types.hpp"
+
+
+constexpr fs::perms ME(int val) { return static_cast<fs::perms>(val); }
+
+int main(int, char**) {
+ 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),
+ "Expected enumeration values do not match");
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.error.report/tested_elsewhere.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.error.report/tested_elsewhere.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.error.report/tested_elsewhere.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.error.report/tested_elsewhere.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+int main(int, char**)
+{
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.filesystem.synopsis/file_time_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.filesystem.synopsis/file_time_type.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.filesystem.synopsis/file_time_type.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.filesystem.synopsis/file_time_type.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// typedef TrivialClock file_time_type;
+
+#include "filesystem_include.hpp"
+#include <chrono>
+#include <type_traits>
+
+#include "test_macros.h"
+
+// system_clock is used because it meets the requirements of TrivialClock,
+// and the resolution and range of system_clock should match the operating
+// system's file time type.
+
+void test_trivial_clock() {
+ using namespace fs;
+ using Clock = file_time_type::clock;
+ ASSERT_NOEXCEPT(Clock::now());
+ ASSERT_SAME_TYPE(decltype(Clock::now()), file_time_type);
+ ASSERT_SAME_TYPE(Clock::time_point, file_time_type);
+ volatile auto* odr_use = &Clock::is_steady;
+ ((void)odr_use);
+}
+
+void test_time_point_resolution_and_range() {
+ using namespace fs;
+ using Dur = file_time_type::duration;
+ using Period = Dur::period;
+ ASSERT_SAME_TYPE(Period, std::nano);
+}
+
+int main(int, char**) {
+ test_trivial_clock();
+ test_time_point_resolution_and_range();
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.absolute/absolute.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.absolute/absolute.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.absolute/absolute.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.absolute/absolute.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// path absolute(const path& p, const path& base=current_path());
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+TEST_SUITE(filesystem_absolute_path_test_suite)
+
+TEST_CASE(absolute_signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec;
+ ASSERT_NOT_NOEXCEPT(absolute(p));
+ ASSERT_NOT_NOEXCEPT(absolute(p, ec));
+}
+
+
+TEST_CASE(basic_test)
+{
+ const fs::path cwd = fs::current_path();
+ const struct {
+ std::string input;
+ std::string expect;
+ } TestCases [] = {
+ {"", cwd / ""},
+ {"foo", cwd / "foo"},
+ {"foo/", cwd / "foo/"},
+ {"/already_absolute", "/already_absolute"}
+ };
+ for (auto& TC : TestCases) {
+ std::error_code ec = GetTestEC();
+ const path ret = absolute(TC.input, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(PathEq(ret, TC.expect));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,123 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// path canonical(const path& p);
+// path canonical(const path& p, error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+struct CWDGuard {
+ path OldCWD;
+ CWDGuard() : OldCWD(fs::current_path()) { }
+ ~CWDGuard() { fs::current_path(OldCWD); }
+
+ CWDGuard(CWDGuard const&) = delete;
+ CWDGuard& operator=(CWDGuard const&) = delete;
+};
+
+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, ec));
+}
+
+// There are 4 cases is the proposal for absolute path.
+// Each scope tests one of the cases.
+TEST_CASE(test_canonical)
+{
+ CWDGuard guard;
+ // 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;
+ TestCase(path p1, path e, path b = StaticEnv::Root)
+ : p(p1), expect(e), base(b) {}
+ };
+ 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 = GetTestEC();
+ fs::current_path(TC.base);
+ const path ret = canonical(TC.p, ec);
+ TEST_REQUIRE(!ec);
+ const path ret2 = canonical(TC.p);
+ TEST_CHECK(PathEq(ret, TC.expect));
+ TEST_CHECK(PathEq(ret, ret2));
+ TEST_CHECK(ret.is_absolute());
+ }
+}
+
+TEST_CASE(test_dne_path)
+{
+ std::error_code ec = GetTestEC();
+ {
+ const path ret = canonical(StaticEnv::DNE, ec);
+ TEST_CHECK(ec != GetTestEC());
+ TEST_REQUIRE(ec);
+ TEST_CHECK(ret == path{});
+ }
+ {
+ TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE));
+ }
+}
+
+TEST_CASE(test_exception_contains_paths)
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ CWDGuard guard;
+ const path p = "blabla/dne";
+ try {
+ canonical(p);
+ TEST_REQUIRE(false);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ // libc++ provides the current path as the second path in the exception
+ LIBCPP_ONLY(TEST_CHECK(err.path2() == current_path()));
+ }
+ fs::current_path(StaticEnv::Dir);
+ try {
+ canonical(p);
+ TEST_REQUIRE(false);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ LIBCPP_ONLY(TEST_CHECK(err.path2() == StaticEnv::Dir));
+ }
+#endif
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy/copy.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy/copy.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,314 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// void copy(const path& from, const path& to);
+// void copy(const path& from, const path& to, error_code& ec);
+// void copy(const path& from, const path& to, copy_options options);
+// void copy(const path& from, const path& to, copy_options options,
+// error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cstddef>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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_NOT_NOEXCEPT(fs::copy(p, p, ec));
+ ASSERT_NOT_NOEXCEPT(copy(p, p, opts));
+ ASSERT_NOT_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
+ ((void)f); ((void)t); ((void)ec);
+ 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));
+
+ const auto test_ec = GetTestEC();
+
+ // !exists(f)
+ {
+ std::error_code ec = test_ec;
+ const path f = StaticEnv::DNE;
+ const path t = env.test_root;
+ fs::copy(f, t, ec);
+ TEST_REQUIRE(ec);
+ TEST_REQUIRE(ec != test_ec);
+ TEST_CHECK(checkThrow(f, t, ec));
+ }
+ { // equivalent(f, t) == true
+ std::error_code ec = test_ec;
+ fs::copy(file, file, ec);
+ TEST_REQUIRE(ec);
+ TEST_REQUIRE(ec != test_ec);
+ TEST_CHECK(checkThrow(file, file, ec));
+ }
+ { // is_directory(from) && is_file(to)
+ std::error_code ec = test_ec;
+ fs::copy(dir, file, ec);
+ TEST_REQUIRE(ec);
+ TEST_REQUIRE(ec != test_ec);
+ TEST_CHECK(checkThrow(dir, file, ec));
+ }
+ { // is_other(from)
+ std::error_code ec = test_ec;
+ fs::copy(fifo, dir, ec);
+ TEST_REQUIRE(ec);
+ TEST_REQUIRE(ec != test_ec);
+ TEST_CHECK(checkThrow(fifo, dir, ec));
+ }
+ { // is_other(to)
+ std::error_code ec = test_ec;
+ fs::copy(file, fifo, ec);
+ TEST_REQUIRE(ec);
+ TEST_REQUIRE(ec != test_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 = GetTestEC();
+ 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 = GetTestEC();
+ 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 = GetTestEC();
+ fs::copy(symlink, file, copy_options::copy_symlinks, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+ }
+ { // create symlinks but target exists
+ std::error_code ec = GetTestEC();
+ fs::copy(symlink, file, copy_options::create_symlinks, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+ }
+}
+
+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 = GetTestEC();
+ 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 = GetTestEC();
+ 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 = GetTestEC();
+ 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 = GetTestEC();
+ 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 = GetTestEC();
+ fs::copy(file, dest, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_regular_file(dest));
+ }
+}
+
+TEST_CASE(from_is_directory)
+{
+ struct FileInfo {
+ path filename;
+ std::size_t 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-existent directory
+ const path dest = env.make_env_path("dest_dir1");
+ std::error_code ec = GetTestEC();
+ 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 = GetTestEC();
+ 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 = GetTestEC();
+ 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_CASE(test_copy_symlinks_to_symlink_dir)
+{
+ scoped_test_env env;
+ const path file1 = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 101);
+ const path file2_sym = env.create_symlink(file2, "file2_sym");
+ const path dir = env.create_dir("dir");
+ const path dir_sym = env.create_symlink(dir, "dir_sym");
+ {
+ std::error_code ec = GetTestEC();
+ fs::copy(file1, dir_sym, copy_options::copy_symlinks, ec);
+ TEST_CHECK(!ec);
+ const path dest = env.make_env_path("dir/file1");
+ TEST_CHECK(exists(dest));
+ TEST_CHECK(!is_symlink(dest));
+ TEST_CHECK(file_size(dest) == 42);
+ }
+}
+
+
+TEST_CASE(test_dir_create_symlink)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir1");
+ const path dest = env.make_env_path("dne");
+ {
+ std::error_code ec = GetTestEC();
+ fs::copy(dir, dest, copy_options::create_symlinks, ec);
+ TEST_CHECK(ec == std::make_error_code(std::errc::is_a_directory));
+ TEST_CHECK(!exists(dest));
+ TEST_CHECK(!is_symlink(dest));
+ }
+ {
+ std::error_code ec = GetTestEC();
+ fs::copy(dir, dest, copy_options::create_symlinks|copy_options::recursive, ec);
+ TEST_CHECK(ec == std::make_error_code(std::errc::is_a_directory));
+ TEST_CHECK(!exists(dest));
+ TEST_CHECK(!is_symlink(dest));
+ }
+}
+
+TEST_CASE(test_otherwise_no_effects_clause)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir1");
+ { // skip copy because of directory
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ fs::copy(dir, dest, CO::directories_only, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(dest));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,188 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <chrono>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+#include <iostream>
+
+using namespace fs;
+
+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_NOT_NOEXCEPT(fs::copy_file(p, p, ec));
+ ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts, ec));
+}
+
+TEST_CASE(test_error_reporting) {
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path non_regular_file = env.create_fifo("non_reg");
+ const path dne = env.make_env_path("dne");
+
+ { // exists(to) && equivalent(to, from)
+ std::error_code ec;
+ TEST_CHECK(fs::copy_file(file, file, copy_options::overwrite_existing,
+ ec) == false);
+ TEST_CHECK(ErrorIs(ec, std::errc::file_exists));
+ ExceptionChecker Checker(file, file, std::errc::file_exists, "copy_file");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, copy_file(file, file, copy_options::overwrite_existing));
+
+ }
+ { // exists(to) && !(skip_existing | overwrite_existing | update_existing)
+ std::error_code ec;
+ TEST_CHECK(fs::copy_file(file, file2, ec) == false);
+ TEST_CHECK(ErrorIs(ec, std::errc::file_exists));
+ ExceptionChecker Checker(file, file, std::errc::file_exists, "copy_file");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, copy_file(file, file, copy_options::overwrite_existing));
+
+ }
+}
+
+TEST_CASE(non_regular_file_test) {
+ scoped_test_env env;
+ const path fifo = env.create_fifo("fifo");
+ const path dest = env.make_env_path("dest");
+ const path file = env.create_file("file", 42);
+
+ {
+ std::error_code ec = GetTestEC();
+ TEST_REQUIRE(fs::copy_file(fifo, dest, ec) == false);
+ TEST_CHECK(ErrorIs(ec, std::errc::not_supported));
+ TEST_CHECK(!exists(dest));
+ }
+ {
+ std::error_code ec = GetTestEC();
+ TEST_REQUIRE(fs::copy_file(file, fifo, copy_options::overwrite_existing,
+ ec) == false);
+ TEST_CHECK(ErrorIs(ec, std::errc::not_supported));
+ TEST_CHECK(is_fifo(fifo));
+ }
+
+}
+
+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 new_perms = perms::owner_read;
+ permissions(file, new_perms);
+ std::error_code ec = GetTestEC();
+ 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 = GetTestEC();
+ TEST_CHECK(fs::copy_file(file, dest, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+ ec = GetTestEC();
+ TEST_CHECK(fs::copy_file(dest, file, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+}
+
+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 = GetTestEC();
+
+ 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);
+ permissions(dest, perms::all);
+ permissions(file,
+ perms::group_write | perms::owner_write | perms::others_write,
+ perm_options::remove);
+
+ std::error_code ec = GetTestEC();
+ TEST_REQUIRE(fs::copy_file(file, dest, copy_options::overwrite_existing,
+ ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(dest) == 42);
+ TEST_CHECK(status(dest).permissions() == status(file).permissions());
+ }
+ { // exists(to) && update_existing
+ using Sec = std::chrono::seconds;
+ const path older = env.create_file("older_file", 1);
+
+ SleepFor(Sec(2));
+ const path from = env.create_file("update_from", 55);
+
+ SleepFor(Sec(2));
+ const path newer = env.create_file("newer_file", 2);
+
+ std::error_code ec = GetTestEC();
+ 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 = GetTestEC();
+ TEST_REQUIRE(fs::copy_file(file, file2, copy_options::skip_existing, ec) ==
+ false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file2) == 55);
+ }
+}
+
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_large.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_large.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_large.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_large.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+// REQUIRES: long_tests
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <chrono>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+TEST_SUITE(filesystem_copy_file_test_suite)
+
+static std::string random_hex_chars(uintmax_t size) {
+ std::string data;
+ data.reserve(size);
+ for (uintmax_t I = 0; I < size; ++I)
+ data.push_back(random_utils::random_hex_char());
+ return data;
+}
+
+// This test is intended to test 'sendfile's 2gb limit for a single call, and
+// to ensure that libc++ correctly copies files larger than that limit.
+// However it requires allocating ~5GB of filesystem space. This might not
+// be acceptable on all systems.
+TEST_CASE(large_file) {
+ using namespace fs;
+ constexpr uintmax_t sendfile_size_limit = 2147479552ull;
+ constexpr uintmax_t additional_size = 1024;
+ constexpr uintmax_t test_file_size = sendfile_size_limit + additional_size;
+ static_assert(test_file_size > sendfile_size_limit, "");
+
+ scoped_test_env env;
+
+ // Check that we have more than sufficient room to create the files needed
+ // to perform the test.
+ if (space(env.test_root).available < 3 * test_file_size) {
+ TEST_UNSUPPORTED();
+ }
+
+ // Use python to create a file right at the size limit.
+ const path file = env.create_file("source", sendfile_size_limit);
+ // Create some random data that looks different than the data before the
+ // size limit.
+ const std::string additional_data = random_hex_chars(additional_size);
+ // Append this known data to the end of the source file.
+ {
+ std::ofstream outf(file.native(), std::ios_base::app);
+ TEST_REQUIRE(outf.good());
+ outf << additional_data;
+ TEST_REQUIRE(outf);
+ }
+ TEST_REQUIRE(file_size(file) == test_file_size);
+ const path dest = env.make_env_path("dest");
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(copy_file(file, dest, ec));
+ TEST_CHECK(!ec);
+
+ TEST_REQUIRE(is_regular_file(dest));
+ TEST_CHECK(file_size(dest) == test_file_size);
+
+ // Read the data from the end of the destination file, and ensure it matches
+ // the data at the end of the source file.
+ std::string out_data;
+ out_data.reserve(additional_size);
+ {
+ std::ifstream dest_file(dest.native());
+ TEST_REQUIRE(dest_file);
+ dest_file.seekg(sendfile_size_limit);
+ TEST_REQUIRE(dest_file);
+ dest_file >> out_data;
+ TEST_CHECK(dest_file.eof());
+ }
+ TEST_CHECK(out_data.size() == additional_data.size());
+ TEST_CHECK(out_data == additional_data);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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
+ ((void)f); ((void)t); ((void)ec);
+ 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/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// bool create_directories(const path& p);
+// bool create_directories(const path& p, error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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_NOT_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_CASE(create_directory_symlinks) {
+ scoped_test_env env;
+ const path root = env.create_dir("dir");
+ const path sym_dest_dead = env.make_env_path("dead");
+ const path dead_sym = env.create_symlink(sym_dest_dead, "dir/sym_dir");
+ const path target = env.make_env_path("dir/sym_dir/foo");
+ {
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(create_directories(target, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(!exists(sym_dest_dead));
+ TEST_CHECK(!exists(dead_sym));
+ }
+}
+
+
+TEST_CASE(create_directory_through_symlinks) {
+ scoped_test_env env;
+ const path root = env.create_dir("dir");
+ const path sym_dir = env.create_symlink(root, "sym_dir");
+ const path target = env.make_env_path("sym_dir/foo");
+ const path resolved_target = env.make_env_path("dir/foo");
+ TEST_REQUIRE(is_directory(sym_dir));
+ {
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(create_directories(target, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(target));
+ TEST_CHECK(is_directory(resolved_target));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+using namespace fs;
+
+fs::perms read_umask() {
+ mode_t old_mask = umask(0);
+ umask(old_mask); // reset the mask to the old value.
+ return static_cast<fs::perms>(old_mask);
+}
+
+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);
+ const perms expect_perms = perms::all & ~(read_umask());
+ TEST_CHECK((st.permissions() & perms::all) == expect_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 = GetTestEC();
+ 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/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,131 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// bool create_directory(const path& p, const path& attr);
+// bool create_directory(const path& p, const path& attr, error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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;
+ // Remove setgid which mkdir would inherit
+ permissions(env.test_root, perms::set_gid, perm_options::remove);
+
+ 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 = GetTestEC();
+ TEST_CHECK(fs::create_directory(dir, attr_dir, ec) == false);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+ 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 = GetTestEC();
+ TEST_CHECK(fs::create_directory(file, attr_dir, ec) == false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_regular_file(file));
+}
+
+TEST_CASE(attr_dir_is_invalid) {
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path dest = env.make_env_path("dir");
+ const path dne = env.make_env_path("dne");
+ {
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(create_directory(dest, file, ec) == false);
+ TEST_CHECK(ErrorIs(ec, std::errc::not_a_directory));
+ }
+ TEST_REQUIRE(!exists(dest));
+ {
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(create_directory(dest, dne, ec) == false);
+ TEST_CHECK(ErrorIs(ec, std::errc::not_a_directory));
+ }
+}
+
+TEST_CASE(dest_is_symlink) {
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path sym = env.create_symlink("dne_sym", "dne_sym_name");
+ {
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(create_directory(sym, dir, ec) == false);
+ TEST_CHECK(!ec);
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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)
+{
+ 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/input.output/filesystems/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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)
+{
+ 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/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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)
+{
+ 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/input.output/filesystems/fs.op.funcs/fs.op.current_path/current_path.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.current_path/current_path.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.current_path/current_path.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.current_path/current_path.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// bool equivalent(path const& lhs, path const& rhs);
+// bool equivalent(path const& lhs, path const& rhs, std::error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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_error_if_input_dne) {
+ const path E = StaticEnv::File;
+ const path DNE = StaticEnv::DNE;
+ { // Test that an error is reported when either of the paths don't exist
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(equivalent(E, DNE, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+ }
+ {
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(equivalent(DNE, E, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+ }
+ {
+ TEST_CHECK_THROW(filesystem_error, equivalent(DNE, E));
+ TEST_CHECK_THROW(filesystem_error, equivalent(E, DNE));
+ }
+ { // Test that an exception is thrown if both paths do not exist.
+ TEST_CHECK_THROW(filesystem_error, equivalent(DNE, DNE));
+ }
+ {
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(equivalent(DNE, DNE, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+ }
+}
+
+TEST_CASE(equivalent_hardlink_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_CASE(equivalent_is_other_succeeds) {
+ scoped_test_env env;
+ path const file = env.create_file("file", 42);
+ const path fifo1 = env.create_fifo("fifo1");
+ const path fifo2 = env.create_fifo("fifo2");
+ // Required to test behavior for inputs where is_other(p) is true.
+ TEST_REQUIRE(is_other(fifo1));
+ TEST_CHECK(!equivalent(file, fifo1));
+ TEST_CHECK(!equivalent(fifo2, file));
+ TEST_CHECK(!equivalent(fifo1, fifo2));
+ TEST_CHECK(equivalent(fifo1, fifo1));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,96 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// bool exists(file_status s) noexcept
+// bool exists(path const& p);
+// bool exists(path const& p, std::error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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);
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(exists(p, ec) == false);
+ TEST_CHECK(!ec);
+}
+
+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_CASE(test_name_too_long) {
+ std::string long_name(2500, 'a');
+ const path file(long_name);
+
+ std::error_code ec;
+ TEST_CHECK(exists(file, ec) == false);
+ TEST_CHECK(ec);
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// uintmax_t file_size(const path& p);
+// uintmax_t file_size(const path& p, std::error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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)
+{
+ struct {
+ path p;
+ std::errc expected_err;
+ } TestCases[] = {
+ {StaticEnv::Dir, std::errc::is_a_directory},
+ {StaticEnv::SymlinkToDir, std::errc::is_a_directory},
+ {StaticEnv::BadSymlink, std::errc::no_such_file_or_directory},
+ {StaticEnv::DNE, std::errc::no_such_file_or_directory},
+ {"", std::errc::no_such_file_or_directory}};
+ const uintmax_t expect = static_cast<uintmax_t>(-1);
+ for (auto& TC : TestCases) {
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(file_size(TC.p, ec) == expect);
+ TEST_CHECK(ErrorIs(ec, TC.expected_err));
+
+ ExceptionChecker Checker(TC.p, TC.expected_err, "file_size");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, file_size(TC.p));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// uintmax_t hard_link_count(const path& p);
+// uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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; // hard link from . .. and Dir2
+ uintmax_t Dir3Expect = 2; // hard link from . ..
+ uintmax_t DirExpectAlt = DirExpect;
+ uintmax_t Dir3ExpectAlt = Dir3Expect;
+#if defined(__APPLE__)
+ // Filesystems formatted with case sensitive hfs+ behave unixish as
+ // expected. Normal hfs+ filesystems report the number of directory
+ // entries instead.
+ DirExpectAlt = 5; // . .. Dir2 file1 file2
+ Dir3Expect = 3; // . .. file5
+#endif
+ TEST_CHECK(hard_link_count(StaticEnv::Dir) == DirExpect ||
+ hard_link_count(StaticEnv::Dir) == DirExpectAlt ||
+ hard_link_count(StaticEnv::Dir) == 1);
+ TEST_CHECK(hard_link_count(StaticEnv::Dir3) == Dir3Expect ||
+ hard_link_count(StaticEnv::Dir3) == Dir3ExpectAlt ||
+ hard_link_count(StaticEnv::Dir3) == 1);
+
+ std::error_code ec;
+ TEST_CHECK(hard_link_count(StaticEnv::Dir, ec) == DirExpect ||
+ hard_link_count(StaticEnv::Dir, ec) == DirExpectAlt ||
+ hard_link_count(StaticEnv::Dir) == 1);
+ TEST_CHECK(hard_link_count(StaticEnv::Dir3, ec) == Dir3Expect ||
+ hard_link_count(StaticEnv::Dir3, ec) == Dir3ExpectAlt ||
+ hard_link_count(StaticEnv::Dir3) == 1);
+}
+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/input.output/filesystems/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// bool is_empty(path const& p);
+// bool is_empty(path const& p, std::error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+TEST_SUITE(is_empty_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_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_CASE(test_directory_access_denied)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file1 = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(is_empty(dir, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+
+ TEST_CHECK_THROW(filesystem_error, is_empty(dir));
+}
+
+
+TEST_CASE(test_fifo_fails)
+{
+ scoped_test_env env;
+ const path fifo = env.create_fifo("fifo");
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(is_empty(fifo, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+
+ TEST_CHECK_THROW(filesystem_error, is_empty(fifo));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.is_other/is_other.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_other/is_other.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_other/is_other.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_other/is_other.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,588 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+#include <type_traits>
+#include <chrono>
+#include <fstream>
+#include <cstdlib>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+#include <sys/stat.h>
+#include <iostream>
+
+#include <fcntl.h>
+#include <sys/time.h>
+
+using namespace fs;
+
+using TimeSpec = struct ::timespec;
+using StatT = struct ::stat;
+
+using Sec = std::chrono::duration<file_time_type::rep>;
+using Hours = std::chrono::hours;
+using Minutes = std::chrono::minutes;
+using MicroSec = std::chrono::duration<file_time_type::rep, std::micro>;
+using NanoSec = std::chrono::duration<file_time_type::rep, std::nano>;
+using std::chrono::duration_cast;
+
+#if defined(__APPLE__)
+TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
+TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
+#else
+TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
+TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
+#endif
+
+bool ConvertToTimeSpec(TimeSpec& ts, file_time_type ft) {
+ using SecFieldT = decltype(TimeSpec::tv_sec);
+ using NSecFieldT = decltype(TimeSpec::tv_nsec);
+ using SecLim = std::numeric_limits<SecFieldT>;
+ using NSecLim = std::numeric_limits<NSecFieldT>;
+
+ auto secs = duration_cast<Sec>(ft.time_since_epoch());
+ auto nsecs = duration_cast<NanoSec>(ft.time_since_epoch() - secs);
+ if (nsecs.count() < 0) {
+ if (Sec::min().count() > SecLim::min()) {
+ secs += Sec(1);
+ nsecs -= Sec(1);
+ } else {
+ nsecs = NanoSec(0);
+ }
+ }
+ if (SecLim::max() < secs.count() || SecLim::min() > secs.count())
+ return false;
+ if (NSecLim::max() < nsecs.count() || NSecLim::min() > nsecs.count())
+ return false;
+ ts.tv_sec = secs.count();
+ ts.tv_nsec = nsecs.count();
+ return true;
+}
+
+bool ConvertFromTimeSpec(file_time_type& ft, TimeSpec ts) {
+ auto secs_part = duration_cast<file_time_type::duration>(Sec(ts.tv_sec));
+ if (duration_cast<Sec>(secs_part).count() != ts.tv_sec)
+ return false;
+ auto subsecs = duration_cast<file_time_type::duration>(NanoSec(ts.tv_nsec));
+ auto dur = secs_part + subsecs;
+ if (dur < secs_part && subsecs.count() >= 0)
+ return false;
+ ft = file_time_type(dur);
+ return true;
+}
+
+bool CompareTimeExact(TimeSpec ts, TimeSpec ts2) {
+ return ts2.tv_sec == ts.tv_sec && ts2.tv_nsec == ts.tv_nsec;
+}
+bool CompareTimeExact(file_time_type ft, TimeSpec ts) {
+ TimeSpec ts2 = {};
+ if (!ConvertToTimeSpec(ts2, ft))
+ return false;
+ return CompareTimeExact(ts, ts2);
+}
+bool CompareTimeExact(TimeSpec ts, file_time_type ft) {
+ return CompareTimeExact(ft, ts);
+}
+
+struct Times {
+ TimeSpec access, write;
+};
+
+Times GetTimes(path const& p) {
+ StatT 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 {extract_atime(st), extract_mtime(st)};
+}
+
+TimeSpec LastAccessTime(path const& p) { return GetTimes(p).access; }
+
+TimeSpec LastWriteTime(path const& p) { return GetTimes(p).write; }
+
+Times GetSymlinkTimes(path const& p) {
+ StatT 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
+ }
+ Times res;
+ res.access = extract_atime(st);
+ res.write = extract_mtime(st);
+ return res;
+}
+
+namespace {
+
+// In some configurations, the comparison is tautological and the test is valid.
+// We disable the warning so that we can actually test it regardless. Also, that
+// diagnostic is pretty new, so also don't fail if old clang does not support it
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-warning-option"
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic ignored "-Wtautological-constant-compare"
+#endif
+
+static const bool SupportsNegativeTimes = [] {
+ using namespace std::chrono;
+ std::error_code ec;
+ TimeSpec old_write_time, new_write_time;
+ { // WARNING: Do not assert in this scope.
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ old_write_time = LastWriteTime(file);
+ file_time_type tp(seconds(-5));
+ fs::last_write_time(file, tp, ec);
+ new_write_time = LastWriteTime(file);
+ }
+
+ return !ec && new_write_time.tv_sec < 0;
+}();
+
+static const bool SupportsMaxTime = [] {
+ using namespace std::chrono;
+ TimeSpec max_ts = {};
+ if (!ConvertToTimeSpec(max_ts, file_time_type::max()))
+ return false;
+
+ std::error_code ec;
+ TimeSpec old_write_time, new_write_time;
+ { // WARNING: Do not assert in this scope.
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ old_write_time = LastWriteTime(file);
+ file_time_type tp = file_time_type::max();
+ fs::last_write_time(file, tp, ec);
+ new_write_time = LastWriteTime(file);
+ }
+ return !ec && new_write_time.tv_sec > max_ts.tv_sec - 1;
+}();
+
+static const bool SupportsMinTime = [] {
+ using namespace std::chrono;
+ TimeSpec min_ts = {};
+ if (!ConvertToTimeSpec(min_ts, file_time_type::min()))
+ return false;
+ std::error_code ec;
+ TimeSpec old_write_time, new_write_time;
+ { // WARNING: Do not assert in this scope.
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ old_write_time = LastWriteTime(file);
+ file_time_type tp = file_time_type::min();
+ fs::last_write_time(file, tp, ec);
+ new_write_time = LastWriteTime(file);
+ }
+ return !ec && new_write_time.tv_sec < min_ts.tv_sec + 1;
+}();
+
+static const bool SupportsNanosecondRoundTrip = [] {
+ NanoSec ns(3);
+ static_assert(std::is_same<file_time_type::period, std::nano>::value, "");
+
+ // Test that the system call we use to set the times also supports nanosecond
+ // resolution. (utimes does not)
+ file_time_type ft(ns);
+ {
+ scoped_test_env env;
+ const path p = env.create_file("file", 42);
+ last_write_time(p, ft);
+ return last_write_time(p) == ft;
+ }
+}();
+
+// The HFS+ filesystem (used by default before macOS 10.13) stores timestamps at
+// a 1-second granularity, and APFS (now the default) at a 1 nanosecond granularity.
+// 1-second granularity is also the norm on many of the supported filesystems
+// on Linux as well.
+static const bool WorkaroundStatTruncatesToSeconds = [] {
+ MicroSec micros(3);
+ static_assert(std::is_same<file_time_type::period, std::nano>::value, "");
+
+ file_time_type ft(micros);
+ {
+ scoped_test_env env;
+ const path p = env.create_file("file", 42);
+ if (LastWriteTime(p).tv_nsec != 0)
+ return false;
+ last_write_time(p, ft);
+ return last_write_time(p) != ft && LastWriteTime(p).tv_nsec == 0;
+ }
+}();
+
+static const bool SupportsMinRoundTrip = [] {
+ TimeSpec ts = {};
+ if (!ConvertToTimeSpec(ts, file_time_type::min()))
+ return false;
+ file_time_type min_val = {};
+ if (!ConvertFromTimeSpec(min_val, ts))
+ return false;
+ return min_val == file_time_type::min();
+}();
+
+} // end namespace
+
+static bool CompareTime(TimeSpec t1, TimeSpec t2) {
+ if (SupportsNanosecondRoundTrip)
+ return CompareTimeExact(t1, t2);
+ if (t1.tv_sec != t2.tv_sec)
+ return false;
+
+ auto diff = std::abs(t1.tv_nsec - t2.tv_nsec);
+ if (WorkaroundStatTruncatesToSeconds)
+ return diff < duration_cast<NanoSec>(Sec(1)).count();
+ return diff < duration_cast<NanoSec>(MicroSec(1)).count();
+}
+
+static bool CompareTime(file_time_type t1, TimeSpec t2) {
+ TimeSpec ts1 = {};
+ if (!ConvertToTimeSpec(ts1, t1))
+ return false;
+ return CompareTime(ts1, t2);
+}
+
+static bool CompareTime(TimeSpec t1, file_time_type t2) {
+ return CompareTime(t2, t1);
+}
+
+static bool CompareTime(file_time_type t1, file_time_type t2) {
+ auto min_secs = duration_cast<Sec>(file_time_type::min().time_since_epoch());
+ bool IsMin =
+ t1.time_since_epoch() < min_secs || t2.time_since_epoch() < min_secs;
+
+ if (SupportsNanosecondRoundTrip && (!IsMin || SupportsMinRoundTrip))
+ return t1 == t2;
+ if (IsMin) {
+ return duration_cast<Sec>(t1.time_since_epoch()) ==
+ duration_cast<Sec>(t2.time_since_epoch());
+ }
+ file_time_type::duration dur;
+ if (t1 > t2)
+ dur = t1 - t2;
+ else
+ dur = t2 - t1;
+ if (WorkaroundStatTruncatesToSeconds)
+ return duration_cast<Sec>(dur).count() == 0;
+ return duration_cast<MicroSec>(dur).count() == 0;
+}
+
+// Check if a time point is representable on a given filesystem. Check that:
+// (A) 'tp' is representable as a time_t
+// (B) 'tp' is non-negative or the filesystem supports negative times.
+// (C) 'tp' is not 'file_time_type::max()' or the filesystem supports the max
+// value.
+// (D) 'tp' is not 'file_time_type::min()' or the filesystem supports the min
+// value.
+inline bool TimeIsRepresentableByFilesystem(file_time_type tp) {
+ TimeSpec ts = {};
+ if (!ConvertToTimeSpec(ts, tp))
+ return false;
+ else if (tp.time_since_epoch().count() < 0 && !SupportsNegativeTimes)
+ return false;
+ else if (tp == file_time_type::max() && !SupportsMaxTime)
+ return false;
+ else if (tp == file_time_type::min() && !SupportsMinTime)
+ return false;
+ return true;
+}
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+// Create a sub-second duration using the smallest period the filesystem supports.
+file_time_type::duration SubSec(long long val) {
+ using SubSecT = file_time_type::duration;
+ if (SupportsNanosecondRoundTrip) {
+ return duration_cast<SubSecT>(NanoSec(val));
+ } else {
+ return duration_cast<SubSecT>(MicroSec(val));
+ }
+}
+
+TEST_SUITE(last_write_time_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(CompareTime(ret, LastWriteTime(StaticEnv::File)));
+
+ file_time_type ret2 = last_write_time(StaticEnv::SymlinkToFile);
+ TEST_CHECK(CompareTime(ret, ret2));
+ TEST_CHECK(CompareTime(ret2, LastWriteTime(StaticEnv::SymlinkToFile)));
+ }
+ {
+ file_time_type ret = last_write_time(StaticEnv::Dir);
+ TEST_CHECK(ret != min);
+ TEST_CHECK(ret < C::now());
+ TEST_CHECK(CompareTime(ret, LastWriteTime(StaticEnv::Dir)));
+
+ file_time_type ret2 = last_write_time(StaticEnv::SymlinkToDir);
+ TEST_CHECK(CompareTime(ret, ret2));
+ TEST_CHECK(CompareTime(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 TimeSpec file_write_time = file_times.write;
+ const auto dir_times = GetTimes(dir);
+ const TimeSpec dir_write_time = dir_times.write;
+
+ file_time_type ftime = last_write_time(file);
+ TEST_CHECK(Clock::to_time_t(ftime) == file_write_time.tv_sec);
+ TEST_CHECK(CompareTime(ftime, file_write_time));
+
+ file_time_type dtime = last_write_time(dir);
+ TEST_CHECK(Clock::to_time_t(dtime) == dir_write_time.tv_sec);
+ TEST_CHECK(CompareTime(dtime, dir_write_time));
+
+ SleepFor(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(CompareTime(LastWriteTime(file), ftime2));
+ TEST_CHECK(CompareTime(LastWriteTime(dir), dtime2));
+}
+
+
+TEST_CASE(set_last_write_time_dynamic_env_test)
+{
+ using Clock = file_time_type::clock;
+ scoped_test_env env;
+
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+ const auto now = Clock::now();
+ const file_time_type epoch_time = now - now.time_since_epoch();
+
+ const file_time_type future_time = now + Hours(3) + Sec(42) + SubSec(17);
+ const file_time_type past_time = now - Minutes(3) - Sec(42) - SubSec(17);
+ const file_time_type before_epoch_time =
+ epoch_time - Minutes(3) - Sec(42) - SubSec(17);
+ // FreeBSD has a bug in their utimes implementation where the time is not update
+ // when the number of seconds is '-1'.
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+ const file_time_type just_before_epoch_time =
+ epoch_time - Sec(2) - SubSec(17);
+#else
+ const file_time_type just_before_epoch_time = epoch_time - SubSec(17);
+#endif
+
+ struct TestCase {
+ const char * case_name;
+ path p;
+ file_time_type new_time;
+ } cases[] = {
+ {"file, epoch_time", file, epoch_time},
+ {"dir, epoch_time", dir, epoch_time},
+ {"file, future_time", file, future_time},
+ {"dir, future_time", dir, future_time},
+ {"file, past_time", file, past_time},
+ {"dir, past_time", dir, past_time},
+ {"file, before_epoch_time", file, before_epoch_time},
+ {"dir, before_epoch_time", dir, before_epoch_time},
+ {"file, just_before_epoch_time", file, just_before_epoch_time},
+ {"dir, just_before_epoch_time", dir, just_before_epoch_time}
+ };
+ for (const auto& TC : cases) {
+ std::cerr << "Test Case = " << TC.case_name << "\n";
+ const auto old_times = GetTimes(TC.p);
+ file_time_type old_time;
+ TEST_REQUIRE(ConvertFromTimeSpec(old_time, old_times.write));
+
+ std::error_code ec = GetTestEC();
+ last_write_time(TC.p, TC.new_time, ec);
+ TEST_CHECK(!ec);
+
+ ec = GetTestEC();
+ file_time_type got_time = last_write_time(TC.p, ec);
+ TEST_REQUIRE(!ec);
+
+ if (TimeIsRepresentableByFilesystem(TC.new_time)) {
+ TEST_CHECK(got_time != old_time);
+ TEST_CHECK(CompareTime(got_time, TC.new_time));
+ TEST_CHECK(CompareTime(LastAccessTime(TC.p), old_times.access));
+ }
+ }
+}
+
+TEST_CASE(last_write_time_symlink_test)
+{
+ using Clock = file_time_type::clock;
+
+ 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);
+
+ file_time_type got_time = last_write_time(sym);
+ TEST_CHECK(!CompareTime(got_time, old_times.write));
+ if (!WorkaroundStatTruncatesToSeconds) {
+ TEST_CHECK(got_time == new_time);
+ } else {
+ TEST_CHECK(CompareTime(got_time, new_time));
+ }
+
+ TEST_CHECK(CompareTime(LastWriteTime(file), new_time));
+ TEST_CHECK(CompareTime(LastAccessTime(sym), old_times.access));
+ Times sym_times = GetSymlinkTimes(sym);
+ TEST_CHECK(CompareTime(sym_times.write, old_sym_times.write));
+}
+
+
+TEST_CASE(test_write_min_time)
+{
+ scoped_test_env env;
+ const path p = env.create_file("file", 42);
+ const file_time_type old_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 (TimeIsRepresentableByFilesystem(new_time)) {
+ TEST_CHECK(!ec);
+ TEST_CHECK(CompareTime(tt, new_time));
+
+ last_write_time(p, old_time);
+ new_time = file_time_type::min() + SubSec(1);
+
+ ec = GetTestEC();
+ last_write_time(p, new_time, ec);
+ tt = last_write_time(p);
+
+ if (TimeIsRepresentableByFilesystem(new_time)) {
+ TEST_CHECK(!ec);
+ TEST_CHECK(CompareTime(tt, new_time));
+ } else {
+ TEST_CHECK(ErrorIs(ec, std::errc::value_too_large));
+ TEST_CHECK(tt == old_time);
+ }
+ } else {
+ TEST_CHECK(ErrorIs(ec, std::errc::value_too_large));
+ TEST_CHECK(tt == old_time);
+ }
+}
+
+TEST_CASE(test_write_max_time) {
+ scoped_test_env env;
+ const path p = env.create_file("file", 42);
+ const file_time_type old_time = last_write_time(p);
+ file_time_type new_time = file_time_type::max();
+
+ std::error_code ec = GetTestEC();
+ last_write_time(p, new_time, ec);
+ file_time_type tt = last_write_time(p);
+
+ if (TimeIsRepresentableByFilesystem(new_time)) {
+ TEST_CHECK(!ec);
+ TEST_CHECK(CompareTime(tt, new_time));
+ } else {
+ TEST_CHECK(ErrorIs(ec, std::errc::value_too_large));
+ TEST_CHECK(tt == old_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(ErrorIs(ec, std::errc::no_such_file_or_directory));
+}
+
+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(ErrorIs(ec, std::errc::permission_denied));
+
+ ExceptionChecker Checker(file, std::errc::permission_denied,
+ "last_write_time");
+ TEST_CHECK_THROW_RESULT(filesystem_error, Checker, last_write_time(file));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,181 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// void permissions(const path& p, perms prms,
+// perm_options opts = perm_options::replace);
+// void permissions(const path& p, perms prms, std::error_code& ec) noexcept;
+// void permissions(const path& p, perms prms, perm_options opts, std::error_code);
+
+
+
+#include "filesystem_include.hpp"
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+using PR = fs::perms;
+
+TEST_SUITE(filesystem_permissions_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ const perms pr{}; ((void)pr);
+ const perm_options opts{}; ((void)opts);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::permissions(p, pr));
+ ASSERT_NOT_NOEXCEPT(fs::permissions(p, pr, opts));
+ ASSERT_NOEXCEPT(fs::permissions(p, pr, ec));
+ ASSERT_NOT_NOEXCEPT(fs::permissions(p, pr, 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
+ ((void)f); ((void)opts); ((void)ec);
+ 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 = GetTestEC();
+ fs::permissions(dne, fs::perms{}, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(ec != GetTestEC());
+ TEST_CHECK(checkThrow(dne, fs::perms{}, ec));
+ }
+ {
+ std::error_code ec = GetTestEC();
+ fs::permissions(dne_sym, fs::perms{}, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(ec != GetTestEC());
+ TEST_CHECK(checkThrow(dne_sym, fs::perms{}, 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 perm_options AP = perm_options::add;
+ const perm_options RP = perm_options::remove;
+ const perm_options NF = perm_options::nofollow;
+ struct TestCase {
+ path p;
+ perms set_perms;
+ perms expected;
+ perm_options opts;
+ TestCase(path xp, perms xperms, perms xexpect,
+ perm_options xopts = perm_options::replace)
+ : p(xp), set_perms(xperms), expected(xexpect), opts(xopts) {}
+ } cases[] = {
+ // test file
+ {file, perms::none, perms::none},
+ {file, perms::owner_all, perms::owner_all},
+ {file, perms::group_all, perms::owner_all | perms::group_all, AP},
+ {file, perms::group_all, perms::owner_all, RP},
+ // test directory
+ {dir, perms::none, perms::none},
+ {dir, perms::owner_all, perms::owner_all},
+ {dir, perms::group_all, perms::owner_all | perms::group_all, AP},
+ {dir, perms::group_all, perms::owner_all, RP},
+ // test symlink without symlink_nofollow
+ {sym, perms::none, perms::none},
+ {sym, perms::owner_all, perms::owner_all},
+ {sym, perms::group_all, perms::owner_all | perms::group_all, AP},
+ {sym, perms::group_all, perms::owner_all, RP},
+ // test non-symlink with symlink_nofollow. The last test on file/dir
+ // will have set their permissions to perms::owner_all
+ {file, perms::group_all, perms::owner_all | perms::group_all, AP | NF},
+ {dir, perms::group_all, perms::owner_all | perms::group_all, AP | NF}
+ };
+ for (auto const& TC : cases) {
+ TEST_CHECK(status(TC.p).permissions() != TC.expected);
+ {
+ std::error_code ec = GetTestEC();
+ permissions(TC.p, TC.set_perms, TC.opts, ec);
+ TEST_CHECK(!ec);
+ auto pp = status(TC.p).permissions();
+ TEST_CHECK(pp == TC.expected);
+ }
+ if (TC.opts == perm_options::replace) {
+ std::error_code ec = GetTestEC();
+ permissions(TC.p, TC.set_perms, ec);
+ TEST_CHECK(!ec);
+ auto pp = status(TC.p).permissions();
+ TEST_CHECK(pp == 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.
+ perm_options opts = perm_options::replace;
+ TestCase(perms xperms, perms xexpect,
+ perm_options xopts = perm_options::replace)
+ : set_perms(xperms), expected(xexpect), opts(xopts) {}
+ } cases[] = {
+ {perms::owner_all, perms::owner_all},
+ {perms::group_all, perms::owner_all | perms::group_all, perm_options::add},
+ {perms::owner_all, perms::group_all, perm_options::remove},
+ };
+ for (auto const& TC : cases) {
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
+ // 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 symlink 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 = GetTestEC();
+ permissions(sym, TC.set_perms, TC.opts | perm_options::nofollow, 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/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,132 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// path proximate(const path& p, error_code &ec)
+// path proximate(const path& p, const path& base = current_path())
+// path proximate(const path& p, const path& base, error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <vector>
+#include <iostream>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+static int count_path_elems(const fs::path& p) {
+ int count = 0;
+ for (auto& elem : p) {
+ if (elem != "/" && elem != "")
+ ++count;
+ }
+ return count;
+}
+
+TEST_SUITE(filesystem_proximate_path_test_suite)
+
+
+TEST_CASE(signature_test)
+{
+ using fs::path;
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(proximate(p));
+ ASSERT_NOT_NOEXCEPT(proximate(p, p));
+ ASSERT_NOT_NOEXCEPT(proximate(p, ec));
+ ASSERT_NOT_NOEXCEPT(proximate(p, p, ec));
+}
+
+TEST_CASE(basic_test) {
+ using fs::path;
+ const path cwd = fs::current_path();
+ const path parent_cwd = cwd.parent_path();
+ const path curdir = cwd.filename();
+ TEST_REQUIRE(!cwd.native().empty());
+ int cwd_depth = count_path_elems(cwd);
+ path dot_dot_to_root;
+ for (int i=0; i < cwd_depth; ++i)
+ dot_dot_to_root /= "..";
+ path relative_cwd = cwd.native().substr(1);
+ // clang-format off
+ struct {
+ std::string input;
+ std::string base;
+ std::string expect;
+ } TestCases[] = {
+ {"", "", "."},
+ {cwd, "a", ".."},
+ {parent_cwd, "a", "../.."},
+ {"a", cwd, "a"},
+ {"a", parent_cwd, "fs.op.proximate/a"},
+ {"/", "a", dot_dot_to_root / ".."},
+ {"/", "a/b", dot_dot_to_root / "../.."},
+ {"/", "a/b/", dot_dot_to_root / "../.."},
+ {"a", "/", relative_cwd / "a"},
+ {"a/b", "/", relative_cwd / "a/b"},
+ {"a", "/net", ".." / relative_cwd / "a"},
+ {"//foo/", "//foo", "."},
+ {"//foo", "//foo/", "."},
+ {"//foo", "//foo", "."},
+ {"//foo/", "//foo/", "."},
+ {"//base", "a", dot_dot_to_root / "../base"},
+ {"a", "a", "."},
+ {"a/b", "a/b", "."},
+ {"a/b/c/", "a/b/c/", "."},
+ {"//foo/a/b", "//foo/a/b", "."},
+ {"/a/d", "/a/b/c", "../../d"},
+ {"/a/b/c", "/a/d", "../b/c"},
+ {"a/b/c", "a", "b/c"},
+ {"a/b/c", "a/b/c/x/y", "../.."},
+ {"a/b/c", "a/b/c", "."},
+ {"a/b", "c/d", "../../a/b"}
+ };
+ // clang-format on
+ int ID = 0;
+ for (auto& TC : TestCases) {
+ ++ID;
+ std::error_code ec = GetTestEC();
+ fs::path p(TC.input);
+ const fs::path output = fs::proximate(p, TC.base, ec);
+ if (ec) {
+ TEST_CHECK(!ec);
+ std::cerr << "TEST CASE #" << ID << " FAILED: \n";
+ std::cerr << " Input: '" << TC.input << "'\n";
+ std::cerr << " Base: '" << TC.base << "'\n";
+ std::cerr << " Expected: '" << TC.expect << "'\n";
+
+ std::cerr << std::endl;
+ } else if (!PathEq(output, TC.expect)) {
+ TEST_CHECK(PathEq(output, TC.expect));
+
+ const path canon_input = fs::weakly_canonical(TC.input);
+ const path canon_base = fs::weakly_canonical(TC.base);
+ const path lexically_p = canon_input.lexically_proximate(canon_base);
+ std::cerr << "TEST CASE #" << ID << " FAILED: \n";
+ std::cerr << " Input: '" << TC.input << "'\n";
+ std::cerr << " Base: '" << TC.base << "'\n";
+ std::cerr << " Expected: '" << TC.expect << "'\n";
+ std::cerr << " Output: '" << output.native() << "'\n";
+ std::cerr << " Lex Prox: '" << lexically_p.native() << "'\n";
+ std::cerr << " Canon Input: " << canon_input << "\n";
+ std::cerr << " Canon Base: " << canon_base << "\n";
+
+ std::cerr << std::endl;
+ }
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// path read_symlink(const path& p);
+// path read_symlink(const path& p, error_code& ec);
+
+#include "filesystem_include.hpp"
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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
+ ((void)f); ((void)ec);
+ 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/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// path proximate(const path& p, error_code &ec)
+// path proximate(const path& p, const path& base = current_path())
+// path proximate(const path& p, const path& base, error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <string>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+TEST_SUITE(filesystem_proximate_path_test_suite)
+
+TEST_CASE(test_signature_0) {
+ fs::path p("");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(fs::current_path()));
+}
+
+TEST_CASE(test_signature_1) {
+ fs::path p(".");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(fs::current_path()));
+}
+
+TEST_CASE(test_signature_2) {
+ fs::path p(StaticEnv::File);
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::File));
+}
+
+TEST_CASE(test_signature_3) {
+ fs::path p(StaticEnv::Dir);
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir));
+}
+
+TEST_CASE(test_signature_4) {
+ fs::path p(StaticEnv::SymlinkToDir);
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir));
+}
+
+TEST_CASE(test_signature_5) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/.");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2"));
+}
+
+TEST_CASE(test_signature_6) {
+ // FIXME? If the trailing separator occurs in a part of the path that exists,
+ // it is ommitted. Otherwise it is added to the end of the result.
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/./");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2"));
+}
+
+TEST_CASE(test_signature_7) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/DNE/./");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2/DNE/"));
+}
+
+TEST_CASE(test_signature_8) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir2));
+}
+
+TEST_CASE(test_signature_9) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/../dir2/DNE/..");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir2 / ""));
+}
+
+TEST_CASE(test_signature_10) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/dir3/../DNE/DNE2");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir2 / "DNE/DNE2"));
+}
+
+TEST_CASE(test_signature_11) {
+ fs::path p(StaticEnv::Dir / "../dir1");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir));
+}
+
+TEST_CASE(test_signature_12) {
+ fs::path p(StaticEnv::Dir / "./.");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir));
+}
+
+TEST_CASE(test_signature_13) {
+ fs::path p(StaticEnv::Dir / "DNE/../foo");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir / "foo"));
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove/remove.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove/remove.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove/remove.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove/remove.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// bool remove(const path& p);
+// bool remove(const path& p, error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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
+ ((void)f); ((void)ec);
+ 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[] = {
+ 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));
+ }
+
+ // PR#35780
+ const path testCasesNonexistant[] = {
+ "",
+ env.make_env_path("dne")
+ };
+
+ for (auto& p : testCasesNonexistant) {
+ std::error_code ec;
+
+ TEST_CHECK(!fs::remove(p, ec));
+ TEST_CHECK(!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/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,152 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// uintmax_t remove_all(const path& p);
+// uintmax_t remove_all(const path& p, error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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_NOT_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
+ ((void)f); ((void)ec);
+ 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[] = {
+ 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));
+ }
+
+ // PR#35780
+ const path testCasesNonexistant[] = {
+ "",
+ env.make_env_path("dne")
+ };
+ for (auto &p : testCasesNonexistant) {
+ std::error_code ec;
+
+ TEST_CHECK(fs::remove_all(p, ec) == 0);
+ TEST_CHECK(!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/input.output/filesystems/fs.op.funcs/fs.op.rename/rename.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.rename/rename.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.rename/rename.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.rename/rename.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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
+ ((void)f); ((void)t); ((void)ec);
+ 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/input.output/filesystems/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <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 "filesystem_include.hpp"
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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
+ ((void)f); ((void)s); ((void)ec);
+ 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/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,127 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// space_info space(const path& p);
+// space_info space(const path& p, error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+#include <sys/statvfs.h>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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
+ ((void)f); ((void)ec);
+ 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);
+ TEST_REQUIRE(expect.f_frsize > 0);
+ auto do_mult = [&](std::uintmax_t val) {
+ std::uintmax_t fsize = expect.f_frsize;
+ std::uintmax_t new_val = val * fsize;
+ TEST_CHECK(new_val / fsize == val); // Test for overflow
+ return new_val;
+ };
+ const std::uintmax_t bad_value = static_cast<std::uintmax_t>(-1);
+ const std::uintmax_t expect_capacity = do_mult(expect.f_blocks);
+ const std::uintmax_t expect_free = do_mult(expect.f_bfree);
+ const std::uintmax_t expect_avail = do_mult(expect.f_bavail);
+
+ // 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_capacity / 20;
+ const path cases[] = {
+ StaticEnv::File,
+ StaticEnv::Dir,
+ StaticEnv::Dir2,
+ StaticEnv::SymlinkToFile,
+ StaticEnv::SymlinkToDir
+ };
+ for (auto& p : cases) {
+ std::error_code ec = GetTestEC();
+ space_info info = space(p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(info.capacity != bad_value);
+ TEST_CHECK(expect_capacity == info.capacity);
+ TEST_CHECK(info.free != bad_value);
+ TEST_CHECK(EqualDelta(expect_free, info.free, delta));
+ TEST_CHECK(info.available != bad_value);
+ TEST_CHECK(EqualDelta(expect_avail, info.available, delta));
+ }
+}
+
+TEST_SUITE_END()
Added: libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// file_status status(const path& p);
+// file_status status(const path& p, error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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 perm_ec =
+ std::make_error_code(std::errc::permission_denied);
+ const std::error_code name_too_long_ec =
+ std::make_error_code(std::errc::filename_too_long);
+
+ struct TestCase {
+ path p;
+ std::error_code expect_ec;
+ } const TestCases[] = {
+ {file, perm_ec},
+ {sym, perm_ec},
+ {path(std::string(2500, 'a')), name_too_long_ec}
+ };
+ for (auto& TC : TestCases)
+ {
+ { // test non-throwing case
+ std::error_code ec = set_ec;
+ file_status st = status(TC.p, ec);
+ TEST_CHECK(ec == TC.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(TC.p);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == TC.p);
+ TEST_CHECK(err.path2() == "");
+ TEST_CHECK(err.code() == TC.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/input.output/filesystems/fs.op.funcs/fs.op.status_known/status_known.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status_known/status_known.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status_known/status_known.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.status_known/status_known.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// bool status_known(file_status s) noexcept;
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,191 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// file_status symlink_status(const path& p);
+// file_status symlink_status(const path& p, error_code& ec) noexcept;
+
+#include "filesystem_include.hpp"
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,120 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// path temp_directory_path();
+// path temp_directory_path(error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <memory>
+#include <cstdlib>
+#include <cstring>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace fs;
+
+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 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 = GetTestEC();
+ 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 = GetTestEC();
+ ret = temp_directory_path(ec);
+ LIBCPP_ONLY(TEST_CHECK(ec == expect_ec));
+ TEST_CHECK(ec != GetTestEC());
+ TEST_CHECK(ec);
+ TEST_CHECK(ret == "");
+
+ // Set the env variable to point to a file and check that it fails.
+ PutEnv(TC.name, file);
+ ec = GetTestEC();
+ ret = temp_directory_path(ec);
+ LIBCPP_ONLY(TEST_CHECK(ec == expect_ec));
+ TEST_CHECK(ec != GetTestEC());
+ TEST_CHECK(ec);
+ TEST_CHECK(ret == "");
+
+ // Set the env variable to point to a dir we can't access
+ PutEnv(TC.name, nested_dir);
+ ec = GetTestEC();
+ ret = temp_directory_path(ec);
+ TEST_CHECK(ec == std::make_error_code(std::errc::permission_denied));
+ TEST_CHECK(ret == "");
+
+ // Set the env variable to point to a non-existent dir
+ PutEnv(TC.name, TC.p / "does_not_exist");
+ ec = GetTestEC();
+ ret = temp_directory_path(ec);
+ TEST_CHECK(ec != GetTestEC());
+ TEST_CHECK(ec);
+ TEST_CHECK(ret == "");
+
+ // Finally erase this env variable
+ UnsetEnv(TC.name);
+ }
+ // No env variables are defined
+ {
+ std::error_code ec = GetTestEC();
+ 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/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+// path weakly_canonical(const path& p);
+// path weakly_canonical(const path& p, error_code& ec);
+
+#include "filesystem_include.hpp"
+#include <type_traits>
+#include <vector>
+#include <iostream>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+
+int main(int, char**) {
+ // clang-format off
+ struct {
+ std::string input;
+ std::string expect;
+ } TestCases[] = {
+ {"", fs::current_path()},
+ {".", fs::current_path()},
+ {"/", "/"},
+ {"/foo", "/foo"},
+ {"/.", "/"},
+ {"/./", "/"},
+ {"a/b", fs::current_path() / "a/b"},
+ {"a", fs::current_path() / "a"},
+ {"a/b/", fs::current_path() / "a/b/"},
+ {StaticEnv::File, StaticEnv::File},
+ {StaticEnv::Dir, StaticEnv::Dir},
+ {StaticEnv::SymlinkToDir, StaticEnv::Dir},
+ {StaticEnv::SymlinkToDir / "dir2/.", StaticEnv::Dir / "dir2"},
+ // FIXME? If the trailing separator occurs in a part of the path that exists,
+ // it is ommitted. Otherwise it is added to the end of the result.
+ {StaticEnv::SymlinkToDir / "dir2/./", StaticEnv::Dir / "dir2"},
+ {StaticEnv::SymlinkToDir / "dir2/DNE/./", StaticEnv::Dir / "dir2/DNE/"},
+ {StaticEnv::SymlinkToDir / "dir2", StaticEnv::Dir2},
+ {StaticEnv::SymlinkToDir / "dir2/../dir2/DNE/..", StaticEnv::Dir2 / ""},
+ {StaticEnv::SymlinkToDir / "dir2/dir3/../DNE/DNE2", StaticEnv::Dir2 / "DNE/DNE2"},
+ {StaticEnv::Dir / "../dir1", StaticEnv::Dir},
+ {StaticEnv::Dir / "./.", StaticEnv::Dir},
+ {StaticEnv::Dir / "DNE/../foo", StaticEnv::Dir / "foo"}
+ };
+ // clang-format on
+ int ID = 0;
+ bool Failed = false;
+ for (auto& TC : TestCases) {
+ ++ID;
+ fs::path p(TC.input);
+ const fs::path output = fs::weakly_canonical(p);
+ if (!PathEq(output, TC.expect)) {
+ Failed = true;
+ std::cerr << "TEST CASE #" << ID << " FAILED: \n";
+ std::cerr << " Input: '" << TC.input << "'\n";
+ std::cerr << " Expected: '" << TC.expect << "'\n";
+ std::cerr << " Output: '" << output.native() << "'";
+ std::cerr << std::endl;
+ }
+ }
+ return Failed;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.req.macros/feature_macro.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.req.macros/feature_macro.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.req.macros/feature_macro.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.req.macros/feature_macro.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <filesystem>
+
+// #define __cpp_lib_filesystem 201703L
+
+#include <filesystem>
+#include "test_macros.h"
+
+#if TEST_STD_VER >= 17
+#ifndef __cpp_lib_filesystem
+#error Filesystem feature test macro is not defined (__cpp_lib_filesystem)
+#elif __cpp_lib_filesystem != 201703L
+#error Filesystem feature test macro has an incorrect value (__cpp_lib_filesystem)
+#endif
+#else // TEST_STD_VER < 17
+#ifdef __cpp_lib_filesystem
+#error Filesystem feature test macro should not be defined before C++17
+#endif
+#endif
+
+int main(int, char**) {
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.fail.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.fail.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.fail.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: c++98 || c++03 || c++11 || c++14
+
+// <filesystem>
+
+// namespace std::filesystem
+
+#include <filesystem>
+#include "test_macros.h"
+
+using namespace std::filesystem;
+
+#if TEST_STD_VER >= 11
+// expected-error at -3 {{no namespace named 'filesystem' in namespace 'std';}}
+#else
+// expected-error at -5 {{expected namespace name}}
+#endif
+
+int main(int, char**) {
+
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.pass.cpp?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.pass.cpp (added)
+++ libcxx/trunk/test/std/input.output/filesystems/fs.req.namespace/namespace.pass.cpp Tue Mar 19 12:27:29 2019
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <filesystem>
+
+// namespace std::filesystem
+
+#include <filesystem>
+#include <type_traits>
+
+using namespace std::filesystem;
+
+int main(int, char**) {
+ static_assert(std::is_same<
+ path,
+ std::filesystem::path
+ >::value, "");
+
+ return 0;
+}
Added: libcxx/trunk/test/std/input.output/filesystems/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/filesystems/lit.local.cfg?rev=356505&view=auto
==============================================================================
--- libcxx/trunk/test/std/input.output/filesystems/lit.local.cfg (added)
+++ libcxx/trunk/test/std/input.output/filesystems/lit.local.cfg Tue Mar 19 12:27:29 2019
@@ -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/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp Tue Mar 19 12:27:29 2019
@@ -7,6 +7,9 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+//
+// TODO: Remove this when filesystem gets integrated into the dylib
+// REQUIRES: c++filesystem
// <chrono>
Modified: libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp Tue Mar 19 12:27:29 2019
@@ -8,6 +8,9 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// TODO: Remove this when filesystem gets integrated into the dylib
+// REQUIRES: c++filesystem
+
// <chrono>
// file_clock
Modified: libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp Tue Mar 19 12:27:29 2019
@@ -8,6 +8,9 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// TODO: Remove this when filesystem gets integrated into the dylib
+// REQUIRES: c++filesystem
+
// <chrono>
// file_clock
Modified: libcxx/trunk/utils/ci/macos-backdeployment.sh
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/ci/macos-backdeployment.sh?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/utils/ci/macos-backdeployment.sh (original)
+++ libcxx/trunk/utils/ci/macos-backdeployment.sh Tue Mar 19 12:27:29 2019
@@ -167,6 +167,7 @@ echo "@@@@@@"
echo "@@@ Running tests for libc++ @@@"
"${LIBCXX_BUILD_DIR}/bin/llvm-lit" -sv "${LIBCXX_ROOT}/test" \
--param=enable_experimental=false \
+ --param=enable_filesystem=false \
${LIT_ARCH_STRING} \
--param=cxx_under_test="${CXX}" \
--param=cxx_headers="${LIBCXX_INSTALL_DIR}/include/c++/v1" \
Modified: libcxx/trunk/utils/libcxx/test/config.py
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/libcxx/test/config.py?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/utils/libcxx/test/config.py (original)
+++ libcxx/trunk/utils/libcxx/test/config.py Tue Mar 19 12:27:29 2019
@@ -332,6 +332,8 @@ class Configuration(object):
# FIXME this is a hack.
if self.get_lit_conf('enable_experimental') is None:
self.config.enable_experimental = 'true'
+ if self.get_lit_conf('enable_filesystem') is None:
+ self.config.enable_filesystem = 'true'
def configure_use_clang_verify(self):
'''If set, run clang with -verify on failing tests.'''
@@ -705,6 +707,10 @@ class Configuration(object):
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
+ self.config.available_features.add('c++filesystem')
static_env = os.path.join(self.libcxx_src_root, 'test', 'std',
'input.output', 'filesystems', 'Inputs', 'static_test_env')
static_env = os.path.realpath(static_env)
@@ -742,8 +748,12 @@ class Configuration(object):
self.configure_link_flags_abi_library()
self.configure_extra_library_flags()
elif self.cxx_stdlib_under_test == 'libstdc++':
- self.config.available_features.add('c++experimental')
- self.cxx.link_flags += ['-lstdc++fs', '-lm', '-pthread']
+ enable_fs = self.get_lit_bool('enable_filesystem',
+ default=False)
+ if enable_fs:
+ self.config.available_features.add('c++experimental')
+ self.cxx.link_flags += ['-lstdc++fs']
+ self.cxx.link_flags += ['-lm', '-pthread']
elif self.cxx_stdlib_under_test == 'msvc':
# FIXME: Correctly setup debug/release flags here.
pass
@@ -793,6 +803,10 @@ class Configuration(object):
if libcxx_experimental:
self.config.available_features.add('c++experimental')
self.cxx.link_flags += ['-lc++experimental']
+ libcxx_fs = self.get_lit_bool('enable_filesystem', default=False)
+ if libcxx_fs:
+ self.config.available_features.add('c++fs')
+ self.cxx.link_flags += ['-lc++fs']
if self.link_shared:
self.cxx.link_flags += ['-lc++']
else:
Modified: libcxx/trunk/utils/libcxx/test/target_info.py
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/libcxx/test/target_info.py?rev=356505&r1=356504&r2=356505&view=diff
==============================================================================
--- libcxx/trunk/utils/libcxx/test/target_info.py (original)
+++ libcxx/trunk/utils/libcxx/test/target_info.py Tue Mar 19 12:27:29 2019
@@ -234,13 +234,18 @@ class LinuxLocalTI(DefaultTargetInfo):
self.full_config.config.available_features)
llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False)
shared_libcxx = self.full_config.get_lit_bool('enable_shared', True)
+ # FIXME: Remove the need to link -lrt in all the tests, and instead
+ # limit it only to the filesystem tests. This ensures we don't cause an
+ # implicit dependency on librt except when filesystem is needed.
+ enable_fs = self.full_config.get_lit_bool('enable_filesystem',
+ default=False)
flags += ['-lm']
if not llvm_unwinder:
flags += ['-lgcc_s', '-lgcc']
if enable_threads:
flags += ['-lpthread']
- if not shared_libcxx:
- flags += ['-lrt']
+ if not shared_libcxx or enable_fs:
+ flags += ['-lrt']
flags += ['-lc']
if llvm_unwinder:
flags += ['-lunwind', '-ldl']
More information about the libcxx-commits
mailing list