summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/filesystem/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/filesystem/test')
-rw-r--r--src/boost/libs/filesystem/test/Jamfile.v2109
-rw-r--r--src/boost/libs/filesystem/test/config_info.cpp50
-rw-r--r--src/boost/libs/filesystem/test/convenience_test.cpp178
-rw-r--r--src/boost/libs/filesystem/test/copy_test.cpp340
-rw-r--r--src/boost/libs/filesystem/test/deprecated_test.cpp268
-rw-r--r--src/boost/libs/filesystem/test/design_use_cases.cpp81
-rw-r--r--src/boost/libs/filesystem/test/equivalent.cpp39
-rw-r--r--src/boost/libs/filesystem/test/foreach_test.cpp62
-rw-r--r--src/boost/libs/filesystem/test/fstream_test.cpp164
-rw-r--r--src/boost/libs/filesystem/test/issues/10038.cpp7
-rw-r--r--src/boost/libs/filesystem/test/issues/10205.cpp17
-rw-r--r--src/boost/libs/filesystem/test/issues/10485.cpp14
-rw-r--r--src/boost/libs/filesystem/test/issues/10641.cpp22
-rw-r--r--src/boost/libs/filesystem/test/issues/11166-remove-race.cpp40
-rw-r--r--src/boost/libs/filesystem/test/issues/11228--filtered-recursive_directory_iterator-range.cpp24
-rw-r--r--src/boost/libs/filesystem/test/issues/3332/test.cpp37
-rw-r--r--src/boost/libs/filesystem/test/issues/4329.-basename.cpp18
-rw-r--r--src/boost/libs/filesystem/test/issues/5300-temp-dir-path-130.cpp0
-rw-r--r--src/boost/libs/filesystem/test/issues/6638-global-init-fails-3.cpp36
-rw-r--r--src/boost/libs/filesystem/test/issues/70-71-copy.cpp20
-rw-r--r--src/boost/libs/filesystem/test/issues/8930.cpp7
-rw-r--r--src/boost/libs/filesystem/test/issues/9054_static_const_codecvt_segfault_pre_main.cpp9
-rw-r--r--src/boost/libs/filesystem/test/issues/9219.cpp40
-rw-r--r--src/boost/libs/filesystem/test/issues/99_canonical_with_junction_point.cpp85
-rw-r--r--src/boost/libs/filesystem/test/issues/Jamfile.v238
-rw-r--r--src/boost/libs/filesystem/test/issues/boost-no-inspect0
-rw-r--r--src/boost/libs/filesystem/test/issues/copy_file-compilation-error-2015-05-04.cpp14
-rw-r--r--src/boost/libs/filesystem/test/issues/fchmodat_AT_SYMLINK_NOFOLLOW_6659.cpp41
-rw-r--r--src/boost/libs/filesystem/test/issues/hello_filesystem.cpp39
-rw-r--r--src/boost/libs/filesystem/test/issues/readme.txt9
-rw-r--r--src/boost/libs/filesystem/test/issues/recurse_dir_iter_5403.cpp116
-rw-r--r--src/boost/libs/filesystem/test/issues/reparse_tag_file_placeholder.cpp169
-rw-r--r--src/boost/libs/filesystem/test/large_file_support_test.cpp36
-rw-r--r--src/boost/libs/filesystem/test/locale_info.cpp85
-rw-r--r--src/boost/libs/filesystem/test/long_path_test.cpp57
-rw-r--r--src/boost/libs/filesystem/test/macro_default_test.cpp35
-rw-r--r--src/boost/libs/filesystem/test/odr1_test.cpp22
-rw-r--r--src/boost/libs/filesystem/test/odr2_test.cpp20
-rw-r--r--src/boost/libs/filesystem/test/operations_test.cpp2786
-rw-r--r--src/boost/libs/filesystem/test/operations_unit_test.cpp380
-rw-r--r--src/boost/libs/filesystem/test/path_test.cpp2667
-rw-r--r--src/boost/libs/filesystem/test/path_times.cpp97
-rw-r--r--src/boost/libs/filesystem/test/path_unit_test.cpp1298
-rw-r--r--src/boost/libs/filesystem/test/quick.cpp24
-rw-r--r--src/boost/libs/filesystem/test/relative_test.cpp119
-rw-r--r--src/boost/libs/filesystem/test/sample_test.cpp62
-rw-r--r--src/boost/libs/filesystem/test/test_cmake/CMakeLists.txt20
-rw-r--r--src/boost/libs/filesystem/test/test_cmake/main.cpp13
-rw-r--r--src/boost/libs/filesystem/test/test_codecvt.hpp72
-rw-r--r--src/boost/libs/filesystem/test/windows_attributes.cpp106
50 files changed, 9992 insertions, 0 deletions
diff --git a/src/boost/libs/filesystem/test/Jamfile.v2 b/src/boost/libs/filesystem/test/Jamfile.v2
new file mode 100644
index 000000000..8dccb9fad
--- /dev/null
+++ b/src/boost/libs/filesystem/test/Jamfile.v2
@@ -0,0 +1,109 @@
+# Boost Filesystem Library test Jamfile
+
+# (C) Copyright Beman Dawes 2002-2006
+# (C) Copyright Andrey Semashev 2020
+# Distributed under the Boost Software License, Version 1.0.
+# See www.boost.org/LICENSE_1_0.txt
+
+import testing ;
+import os ;
+
+# The rule checks we're running on Windows that supports mklink command (Vista and later)
+rule check-mklink ( properties * )
+{
+ local result ;
+
+ if <target-os>windows in $(properties)
+ {
+ # mklink is a builtin shell command, so we can't check if an executable exists.
+ # Testing the exit status of the mklink command (in the hope that it will be different
+ # when the command is not supported) is inconclusive as for some reason Windows 8.1 shell
+ # always returns exit code of 1. We have to match the output of the command. :(
+ # Note that the output may be localized, so pick some part that is likely to be stable regardless
+ # of localization.
+ local output = [ SHELL "mklink /?" : exit-status ] ;
+ if [ MATCH (MKLINK) : $(output[1]) ]
+ {
+ result = <define>BOOST_FILESYSTEM_HAS_MKLINK ;
+
+ if ! $(.annouced-mklink)
+ {
+ ECHO " - Boost.Filesystem: mklink found" ;
+ .annouced-mklink = 1 ;
+ }
+ }
+ else
+ {
+ if ! $(.annouced-mklink)
+ {
+ ECHO " - Boost.Filesystem: mklink not found" ;
+ .annouced-mklink = 1 ;
+ }
+ }
+ }
+
+ #ECHO Result: $(result) ;
+ return $(result) ;
+}
+
+project
+ : requirements
+ <target-os>windows:<define>_SCL_SECURE_NO_WARNINGS
+ <target-os>windows:<define>_SCL_SECURE_NO_DEPRECATE
+ <target-os>windows:<define>_CRT_SECURE_NO_WARNINGS
+ <target-os>windows:<define>_CRT_SECURE_NO_DEPRECATE
+ <library>/boost/filesystem//boost_filesystem
+ <conditional>@check-mklink
+ ;
+
+# Some tests are run both statically and as shared libraries since Filesystem
+# has a history of bugs that appear only in one type of build or the other.
+
+path-constant HERE : . ;
+
+local VIS ;
+
+if [ os.environ UBSAN ]
+{
+ VIS = <visibility>global
+ -<library>/boost/filesystem//boost_filesystem
+ <library>/boost/filesystem//boost_filesystem/<visibility>global ;
+}
+
+run config_info.cpp : : : <link>shared <test-info>always_show_run_output ;
+run config_info.cpp : : : <link>static <test-info>always_show_run_output : config_info_static ;
+run convenience_test.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+compile macro_default_test.cpp ;
+run odr1_test.cpp odr2_test.cpp ;
+run deprecated_test.cpp : : : <define>BOOST_FILESYSTEM_VERSION=3 ;
+run fstream_test.cpp : : : $(VIS) <define>BOOST_FILESYSTEM_VERSION=4 ;
+run large_file_support_test.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+run locale_info.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 <test-info>always_show_run_output ;
+run operations_test.cpp : : : <link>shared <define>BOOST_FILESYSTEM_VERSION=4 <test-info>always_show_run_output ;
+run operations_test.cpp : : : <link>static <define>BOOST_FILESYSTEM_VERSION=4 : operations_test_static ;
+run operations_unit_test.cpp : $(HERE) : : <link>shared <define>BOOST_FILESYSTEM_VERSION=4 <test-info>always_show_run_output ;
+run copy_test.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+run path_test.cpp : : : <link>shared <define>BOOST_FILESYSTEM_VERSION=4 ;
+run path_test.cpp : : : <link>static <define>BOOST_FILESYSTEM_VERSION=4 : path_test_static ;
+run path_test.cpp : : : <link>shared <define>BOOST_FILESYSTEM_VERSION=3 : path_test_v3 ;
+run path_unit_test.cpp : : : <link>shared $(VIS) <define>BOOST_FILESYSTEM_VERSION=4 ;
+run path_unit_test.cpp : : : <link>static $(VIS) <define>BOOST_FILESYSTEM_VERSION=4 : path_unit_test_static ;
+run path_unit_test.cpp : : : <link>shared $(VIS) <define>BOOST_FILESYSTEM_VERSION=3 : path_unit_test_v3 ;
+run relative_test.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+run ../example/simple_ls.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+run ../example/file_status.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+run foreach_test.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+
+# `quick` target (for CI)
+run quick.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+
+# Tests for specific issues
+run issues/70-71-copy.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+
+run issues/99_canonical_with_junction_point.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+run issues/reparse_tag_file_placeholder.cpp : : : <define>BOOST_FILESYSTEM_VERSION=4 ;
+
+if [ os.environ BOOST_FILESYSTEM_TEST_WITH_EXAMPLES ]
+{
+ build-project ../example ;
+}
diff --git a/src/boost/libs/filesystem/test/config_info.cpp b/src/boost/libs/filesystem/test/config_info.cpp
new file mode 100644
index 000000000..aa7cfe085
--- /dev/null
+++ b/src/boost/libs/filesystem/test/config_info.cpp
@@ -0,0 +1,50 @@
+// boost/libs/filesystem/test/config_info.cpp ----------------------------------------//
+
+// Copyright Beman Dawes 2017
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/detail/macro_value.hpp>
+#include <iostream>
+
+using std::cout;
+using std::endl;
+
+int main()
+{
+ cout << "Verify macro reporting works correctly\n";
+ cout << " NOSUCHMACRO: " << BOOST_MACRO_VALUE(NOSUCHMACRO) << endl;
+#define SUCHAMACRO
+ cout << " SUCHAMACRO: " << BOOST_MACRO_VALUE(SUCHAMACRO) << endl;
+ cout << " BOOST_VERSION: " << BOOST_MACRO_VALUE(BOOST_VERSION) << endl;
+
+ cout << "Report macro values that may be useful in debugging various test programs\n";
+ cout << " BOOST_VERSION: " << BOOST_MACRO_VALUE(BOOST_VERSION) << endl;
+ cout << " BOOST_FILESYSTEM_VERSION: " << BOOST_MACRO_VALUE(BOOST_FILESYSTEM_VERSION) << endl;
+ cout << " BOOST_FILESYSTEM_DEPRECATED: " << BOOST_MACRO_VALUE(BOOST_FILESYSTEM_DEPRECATED) << endl;
+ cout << " BOOST_FILESYSTEM_SOURCE: " << BOOST_MACRO_VALUE(BOOST_FILESYSTEM_SOURCE) << endl;
+ cout << " BOOST_FILESYSTEM_DYN_LINK: " << BOOST_MACRO_VALUE(BOOST_FILESYSTEM_DYN_LINK) << endl;
+ cout << " BOOST_FILESYSTEM_STATIC_LINK: " << BOOST_MACRO_VALUE(BOOST_FILESYSTEM_STATIC_LINK) << endl;
+ cout << " BOOST_ALL_NO_LIB: " << BOOST_MACRO_VALUE(BOOST_ALL_NO_LIB) << endl;
+ cout << " BOOST_FILESYSTEM_NO_LIB: " << BOOST_MACRO_VALUE(BOOST_FILESYSTEM_NO_LIB) << endl;
+ cout << " BOOST_LIB_NAME: " << BOOST_MACRO_VALUE(BOOST_LIB_NAME) << endl;
+ cout << " BOOST_POSIX_API: " << BOOST_MACRO_VALUE(BOOST_POSIX_API) << endl;
+ cout << " BOOST_WINDOWS_API: " << BOOST_MACRO_VALUE(BOOST_WINDOWS_API) << endl;
+ cout << " _MSC_VER: " << BOOST_MACRO_VALUE(_MSC_VER) << endl;
+ cout << " __MINGW32__: " << BOOST_MACRO_VALUE(__MINGW32__) << endl;
+ //cout << " : " << BOOST_MACRO_VALUE() << endl;
+ //cout << " : " << BOOST_MACRO_VALUE() << endl;
+ //cout << " : " << BOOST_MACRO_VALUE() << endl;
+ //cout << " : " << BOOST_MACRO_VALUE() << endl;
+ //cout << " : " << BOOST_MACRO_VALUE() << endl;
+ //cout << " : " << BOOST_MACRO_VALUE() << endl;
+ //cout << " : " << BOOST_MACRO_VALUE() << endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/convenience_test.cpp b/src/boost/libs/filesystem/test/convenience_test.cpp
new file mode 100644
index 000000000..67de42781
--- /dev/null
+++ b/src/boost/libs/filesystem/test/convenience_test.cpp
@@ -0,0 +1,178 @@
+// libs/filesystem/test/convenience_test.cpp -----------------------------------------//
+
+// Copyright Beman Dawes, 2002
+// Copyright Vladimir Prus, 2002
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#endif
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/directory.hpp>
+#include <boost/filesystem/exception.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+#include <boost/bind/bind.hpp>
+#include <fstream>
+#include <iostream>
+
+namespace fs = boost::filesystem;
+using fs::path;
+namespace sys = boost::system;
+
+namespace {
+template< typename F >
+bool throws_fs_error(F func)
+{
+ try
+ {
+ func();
+ }
+
+ catch (const fs::filesystem_error&)
+ {
+ return true;
+ }
+ return false;
+}
+
+void create_recursive_iterator(const fs::path& ph)
+{
+ fs::recursive_directory_iterator it(ph);
+}
+} // namespace
+
+// ------------------------------------------------------------------------------------//
+
+int cpp_main(int, char*[])
+{
+
+ // create_directories() tests --------------------------------------------------------//
+
+ BOOST_TEST(!fs::create_directories("/")); // should be harmless
+
+ path unique_dir = fs::unique_path(); // unique name in case tests running in parallel
+ path unique_yy = unique_dir / "yy";
+ path unique_yya = unique_dir / "yya";
+ path unique_yy_zz = unique_dir / "yy" / "zz";
+
+ fs::remove_all(unique_dir); // make sure slate is blank
+ BOOST_TEST(!fs::exists(unique_dir)); // reality check
+
+ BOOST_TEST(fs::create_directories(unique_dir));
+ BOOST_TEST(fs::exists(unique_dir));
+ BOOST_TEST(fs::is_directory(unique_dir));
+
+ BOOST_TEST(fs::create_directories(unique_yy_zz));
+ BOOST_TEST(fs::exists(unique_dir));
+ BOOST_TEST(fs::exists(unique_yy));
+ BOOST_TEST(fs::exists(unique_yy_zz));
+ BOOST_TEST(fs::is_directory(unique_dir));
+ BOOST_TEST(fs::is_directory(unique_yy));
+ BOOST_TEST(fs::is_directory(unique_yy_zz));
+
+ path is_a_file(unique_dir / "uu");
+ {
+ std::ofstream f(is_a_file.string().c_str());
+ BOOST_TEST(!!f);
+ }
+ BOOST_TEST(throws_fs_error(
+ boost::bind(fs::create_directories, is_a_file)));
+ BOOST_TEST(throws_fs_error(
+ boost::bind(fs::create_directories, is_a_file / "aa")));
+
+ // recursive_directory_iterator tests ----------------------------------------//
+
+ sys::error_code ec;
+ fs::recursive_directory_iterator it("/no-such-path", ec);
+ BOOST_TEST(ec);
+
+ BOOST_TEST(throws_fs_error(
+ boost::bind(create_recursive_iterator, "/no-such-path")));
+
+ fs::remove(unique_dir / "uu");
+
+#ifdef BOOST_WINDOWS_API
+ // These tests depends on ordering of directory entries, and that's guaranteed
+ // on Windows but not necessarily on other operating systems
+ {
+ std::ofstream f(unique_yya.string().c_str());
+ BOOST_TEST(!!f);
+ }
+
+ for (it = fs::recursive_directory_iterator(unique_dir);
+ it != fs::recursive_directory_iterator(); ++it)
+ {
+ std::cout << it->path() << '\n';
+ }
+
+ it = fs::recursive_directory_iterator(unique_dir);
+ BOOST_TEST(it->path() == unique_yy);
+ BOOST_TEST(it.depth() == 0);
+ ++it;
+ BOOST_TEST(it->path() == unique_yy_zz);
+ BOOST_TEST(it.depth() == 1);
+ it.pop();
+ BOOST_TEST(it->path() == unique_yya);
+ BOOST_TEST(it.depth() == 0);
+ it++;
+ BOOST_TEST(it == fs::recursive_directory_iterator());
+
+ it = fs::recursive_directory_iterator(unique_dir);
+ BOOST_TEST(it->path() == unique_yy);
+ it.disable_recursion_pending();
+ ++it;
+ BOOST_TEST(it->path() == unique_yya);
+ ++it;
+ BOOST_TEST(it == fs::recursive_directory_iterator());
+
+ fs::remove(unique_yya);
+#endif
+
+ it = fs::recursive_directory_iterator(unique_yy_zz);
+ BOOST_TEST(it == fs::recursive_directory_iterator());
+
+ it = fs::recursive_directory_iterator(unique_dir);
+ BOOST_TEST(it->path() == unique_yy);
+ BOOST_TEST(it.depth() == 0);
+ ++it;
+ BOOST_TEST(it->path() == unique_yy_zz);
+ BOOST_TEST(it.depth() == 1);
+ it++;
+ BOOST_TEST(it == fs::recursive_directory_iterator());
+
+ it = fs::recursive_directory_iterator(unique_dir);
+ BOOST_TEST(it->path() == unique_yy);
+ it.disable_recursion_pending();
+ ++it;
+ BOOST_TEST(it == fs::recursive_directory_iterator());
+
+ it = fs::recursive_directory_iterator(unique_dir);
+ BOOST_TEST(it->path() == unique_yy);
+ ++it;
+ it.pop();
+ BOOST_TEST(it == fs::recursive_directory_iterator());
+
+ ec.clear();
+ BOOST_TEST(!ec);
+ // check that two argument failed constructor creates the end iterator
+ BOOST_TEST(fs::recursive_directory_iterator("nosuchdir", ec) == fs::recursive_directory_iterator());
+ BOOST_TEST(ec);
+
+ fs::remove_all(unique_dir); // clean up behind ourselves
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/copy_test.cpp b/src/boost/libs/filesystem/test/copy_test.cpp
new file mode 100644
index 000000000..af9a35c7e
--- /dev/null
+++ b/src/boost/libs/filesystem/test/copy_test.cpp
@@ -0,0 +1,340 @@
+// Copyright Andrey Semashev 2020.
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+// This test verifies copy operation behavior.
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/directory.hpp>
+#include <boost/filesystem/exception.hpp>
+#include <boost/filesystem/fstream.hpp> // for BOOST_FILESYSTEM_C_STR
+#include <boost/system/error_code.hpp>
+
+#include <set>
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <stdexcept>
+
+#include <boost/throw_exception.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+namespace fs = boost::filesystem;
+
+namespace {
+
+void create_file(fs::path const& ph, std::string const& contents = std::string())
+{
+ std::ofstream f(BOOST_FILESYSTEM_C_STR(ph), std::ios_base::out | std::ios_base::trunc);
+ if (!f)
+ BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create file: " + ph.string()));
+ if (!contents.empty())
+ f << contents;
+}
+
+void verify_file(fs::path const& ph, std::string const& expected)
+{
+ std::ifstream f(BOOST_FILESYSTEM_C_STR(ph));
+ if (!f)
+ BOOST_THROW_EXCEPTION(std::runtime_error("Failed to open file: " + ph.string()));
+ std::string contents;
+ f >> contents;
+ BOOST_TEST_EQ(contents, expected);
+ if (contents != expected)
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error("verify_file failed: contents \"" + contents + "\" != \"" + expected + "\" in " + ph.string()));
+ }
+}
+
+fs::path create_tree()
+{
+ fs::path root_dir = fs::unique_path();
+
+ fs::create_directory(root_dir);
+ create_file(root_dir / "f1", "f1");
+ create_file(root_dir / "f2", "f2");
+
+ fs::create_directory(root_dir / "d1");
+ create_file(root_dir / "d1/f1", "d1f1");
+
+ fs::create_directory(root_dir / "d1/d1");
+ create_file(root_dir / "d1/d1/f1", "d1d1f1");
+
+ fs::create_directory(root_dir / "d1/d2");
+
+ fs::create_directory(root_dir / "d2");
+ create_file(root_dir / "d2/f1", "d2f1");
+
+ return root_dir;
+}
+
+typedef std::set< fs::path > directory_tree;
+
+directory_tree collect_directory_tree(fs::path const& root_dir)
+{
+ std::cout << "Collecting directory tree in: " << root_dir << '\n';
+
+ directory_tree tree;
+ fs::recursive_directory_iterator it(root_dir, fs::directory_options::skip_permission_denied |
+ fs::directory_options::follow_directory_symlink | fs::directory_options::skip_dangling_symlinks);
+ fs::recursive_directory_iterator end;
+ while (it != end)
+ {
+ fs::path p = fs::relative(it->path(), root_dir);
+ std::cout << p << '\n';
+ tree.insert(p);
+ ++it;
+ }
+
+ std::cout << "done." << std::endl;
+
+ return tree;
+}
+
+void test_copy_file_default(fs::path const& root_dir)
+{
+ std::cout << "test_copy_file_default" << std::endl;
+
+ fs::path target_dir = fs::unique_path();
+ fs::create_directory(target_dir);
+
+ fs::copy(root_dir / "f1", target_dir);
+ fs::copy(root_dir / "f2", target_dir / "f3");
+
+ directory_tree tree = collect_directory_tree(target_dir);
+
+ BOOST_TEST_EQ(tree.size(), 2u);
+ BOOST_TEST(tree.find("f1") != tree.end());
+ BOOST_TEST(tree.find("f3") != tree.end());
+
+ verify_file(target_dir / "f1", "f1");
+ verify_file(target_dir / "f3", "f2");
+
+ fs::remove_all(target_dir);
+}
+
+void test_copy_dir_default(fs::path const& root_dir, bool with_symlinks)
+{
+ std::cout << "test_copy_dir_default" << std::endl;
+
+ fs::path target_dir = fs::unique_path();
+
+ fs::copy(root_dir, target_dir);
+
+ directory_tree tree = collect_directory_tree(target_dir);
+
+ BOOST_TEST_EQ(tree.size(), 4u + with_symlinks);
+ BOOST_TEST(tree.find("f1") != tree.end());
+ BOOST_TEST(tree.find("f2") != tree.end());
+ BOOST_TEST(tree.find("d1") != tree.end());
+ BOOST_TEST(tree.find("d2") != tree.end());
+ if (with_symlinks)
+ {
+ BOOST_TEST(tree.find("s1") != tree.end());
+ }
+
+ verify_file(target_dir / "f1", "f1");
+ verify_file(target_dir / "f2", "f2");
+
+ fs::remove_all(target_dir);
+}
+
+void test_copy_dir_default_ec(fs::path const& root_dir, bool with_symlinks)
+{
+ // This test is similar to test_copy_dir_default, but uses an error_code overload of the operation.
+ // Tests for https://github.com/boostorg/filesystem/issues/152 fix.
+
+ std::cout << "test_copy_dir_default_ec" << std::endl;
+
+ fs::path target_dir = fs::unique_path();
+
+ boost::system::error_code ec;
+ fs::copy(root_dir, target_dir, ec);
+ BOOST_TEST(!ec);
+
+ directory_tree tree = collect_directory_tree(target_dir);
+
+ BOOST_TEST_EQ(tree.size(), 4u + with_symlinks);
+ BOOST_TEST(tree.find("f1") != tree.end());
+ BOOST_TEST(tree.find("f2") != tree.end());
+ BOOST_TEST(tree.find("d1") != tree.end());
+ BOOST_TEST(tree.find("d2") != tree.end());
+ if (with_symlinks)
+ {
+ BOOST_TEST(tree.find("s1") != tree.end());
+ }
+
+ verify_file(target_dir / "f1", "f1");
+ verify_file(target_dir / "f2", "f2");
+
+ fs::remove_all(target_dir);
+}
+
+void test_copy_dir_recursive(fs::path const& root_dir)
+{
+ std::cout << "test_copy_dir_recursive" << std::endl;
+
+ fs::path target_dir = fs::unique_path();
+
+ fs::copy(root_dir, target_dir, fs::copy_options::recursive);
+
+ directory_tree tree = collect_directory_tree(target_dir);
+
+ BOOST_TEST_EQ(tree.size(), 9u);
+ BOOST_TEST(tree.find("f1") != tree.end());
+ BOOST_TEST(tree.find("f2") != tree.end());
+ BOOST_TEST(tree.find("d1") != tree.end());
+ BOOST_TEST(tree.find(fs::path("d1") / "f1") != tree.end());
+ BOOST_TEST(tree.find(fs::path("d1") / "d1") != tree.end());
+ BOOST_TEST(tree.find(fs::path("d1") / "d1" / "f1") != tree.end());
+ BOOST_TEST(tree.find(fs::path("d1") / "d2") != tree.end());
+ BOOST_TEST(tree.find("d2") != tree.end());
+ BOOST_TEST(tree.find(fs::path("d2") / "f1") != tree.end());
+
+ verify_file(target_dir / "f1", "f1");
+ verify_file(target_dir / "f2", "f2");
+ verify_file(target_dir / "d1/f1", "d1f1");
+ verify_file(target_dir / "d1/d1/f1", "d1d1f1");
+ verify_file(target_dir / "d2/f1", "d2f1");
+
+ fs::remove_all(target_dir);
+}
+
+void test_copy_dir_recursive_tree(fs::path const& root_dir)
+{
+ std::cout << "test_copy_dir_recursive_tree" << std::endl;
+
+ fs::path target_dir = fs::unique_path();
+
+ fs::copy(root_dir, target_dir, fs::copy_options::recursive | fs::copy_options::directories_only);
+
+ directory_tree tree = collect_directory_tree(target_dir);
+
+ BOOST_TEST_EQ(tree.size(), 4u);
+ BOOST_TEST(tree.find("d1") != tree.end());
+ BOOST_TEST(tree.find(fs::path("d1") / "d1") != tree.end());
+ BOOST_TEST(tree.find(fs::path("d1") / "d2") != tree.end());
+ BOOST_TEST(tree.find("d2") != tree.end());
+
+ fs::remove_all(target_dir);
+}
+
+void test_copy_file_symlinks(fs::path const& root_dir)
+{
+ std::cout << "test_copy_file_symlinks" << std::endl;
+
+ fs::path target_dir = fs::unique_path();
+ fs::create_directory(target_dir);
+
+ fs::copy(root_dir / "f1", target_dir);
+
+ fs::path prev_cur_dir = fs::current_path();
+ fs::current_path(target_dir);
+ fs::copy(".." / root_dir / "f2", "f2", fs::copy_options::create_symlinks);
+ fs::current_path(prev_cur_dir);
+
+ // Copying from a relative path with copy_options::create_symlinks to a directory other than current directory is a non-standard extension
+ fs::copy(target_dir / "f1", target_dir / "f3", fs::copy_options::create_symlinks);
+
+ verify_file(target_dir / "f1", "f1");
+
+ fs::path link_target = fs::read_symlink(target_dir / "f2");
+ if (link_target != (".." / root_dir / "f2"))
+ {
+ BOOST_ERROR("Incorrect f2 symlink in test_copy_file_symlinks");
+ std::cout << (target_dir / "f2") << " => " << link_target << std::endl;
+ }
+
+ link_target = fs::read_symlink(target_dir / "f3");
+ if (link_target != "f1" && link_target != (fs::path(".") / "f1"))
+ {
+ BOOST_ERROR("Incorrect f3 symlink in test_copy_file_symlinks");
+ std::cout << (target_dir / "f3") << " => " << link_target << std::endl;
+ }
+
+ fs::remove_all(target_dir);
+}
+
+void test_copy_errors(fs::path const& root_dir, bool symlinks_supported)
+{
+ std::cout << "test_copy_errors" << std::endl;
+
+ fs::path target_dir = fs::unique_path();
+ fs::create_directory(target_dir);
+
+ BOOST_TEST_THROWS(fs::copy(root_dir / "non-existing", target_dir), fs::filesystem_error);
+
+ create_file(target_dir / "f1");
+
+ BOOST_TEST_THROWS(fs::copy(root_dir / "f1", target_dir), fs::filesystem_error);
+ BOOST_TEST_THROWS(fs::copy(root_dir / "f1", target_dir / "f1"), fs::filesystem_error);
+ BOOST_TEST_THROWS(fs::copy(root_dir / "d1", target_dir / "f1"), fs::filesystem_error);
+
+ BOOST_TEST_THROWS(fs::copy(target_dir, target_dir), fs::filesystem_error);
+ BOOST_TEST_THROWS(fs::copy(target_dir / "f1", target_dir / "f1"), fs::filesystem_error);
+
+ if (symlinks_supported)
+ {
+ // Should fail with is_a_directory error code
+ BOOST_TEST_THROWS(fs::copy(root_dir, target_dir, fs::copy_options::create_symlinks), fs::filesystem_error);
+ }
+
+ fs::remove_all(target_dir);
+}
+
+} // namespace
+
+int main()
+{
+ try
+ {
+ fs::path root_dir = create_tree();
+
+ test_copy_file_default(root_dir);
+ test_copy_dir_default(root_dir, false);
+ test_copy_dir_default_ec(root_dir, false);
+ test_copy_dir_recursive(root_dir);
+ test_copy_dir_recursive_tree(root_dir);
+
+ bool symlinks_supported = false;
+ try
+ {
+ fs::create_symlink("f1", root_dir / "s1");
+ symlinks_supported = true;
+ std::cout << " *** For information only ***\n"
+ " create_symlink() attempt succeeded"
+ << std::endl;
+ }
+ catch (fs::filesystem_error& e)
+ {
+ std::cout << " *** For information only ***\n"
+ " create_symlink() attempt failed\n"
+ " filesystem_error.what() reports: "
+ << e.what() << "\n"
+ " create_symlink() may not be supported on this operating system or file system"
+ << std::endl;
+ }
+
+ if (symlinks_supported)
+ {
+ test_copy_dir_default(root_dir, true);
+ test_copy_file_symlinks(root_dir);
+ }
+
+ test_copy_errors(root_dir, symlinks_supported);
+
+ fs::remove_all(root_dir);
+
+ return boost::report_errors();
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "FAIL, exception caught: " << boost::diagnostic_information(e) << std::endl;
+ return 1;
+ }
+}
diff --git a/src/boost/libs/filesystem/test/deprecated_test.cpp b/src/boost/libs/filesystem/test/deprecated_test.cpp
new file mode 100644
index 000000000..afc1494d9
--- /dev/null
+++ b/src/boost/libs/filesystem/test/deprecated_test.cpp
@@ -0,0 +1,268 @@
+// deprecated_test program --------------------------------------------------//
+
+// Copyright Beman Dawes 2002
+// Copyright Vladimir Prus 2002
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+// This test verifies that various deprecated names still work. This is
+// important to preserve existing code that uses the old names.
+
+#define BOOST_FILESYSTEM_DEPRECATED
+
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/string_file.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+
+namespace fs = boost::filesystem;
+using boost::filesystem::path;
+
+#define PATH_CHECK(a, b) check(a, b, __LINE__)
+
+namespace {
+std::string platform(BOOST_PLATFORM);
+
+void check(const fs::path& source, const std::string& expected, int line)
+{
+ if (source.generic_string() == expected)
+ return;
+
+ ++::boost::detail::test_errors();
+
+ std::cout << '(' << line << ") source.string(): \"" << source.string()
+ << "\" != expected: \"" << expected
+ << "\"" << std::endl;
+}
+
+void normalize_test()
+{
+ PATH_CHECK(path("").normalize(), "");
+ PATH_CHECK(path("/").normalize(), "/");
+ PATH_CHECK(path("//").normalize(), "//");
+ PATH_CHECK(path("///").normalize(), "/");
+ PATH_CHECK(path("f").normalize(), "f");
+ PATH_CHECK(path("foo").normalize(), "foo");
+ PATH_CHECK(path("foo/").normalize(), "foo/.");
+ PATH_CHECK(path("f/").normalize(), "f/.");
+ PATH_CHECK(path("/foo").normalize(), "/foo");
+ PATH_CHECK(path("foo/bar").normalize(), "foo/bar");
+ PATH_CHECK(path("..").normalize(), "..");
+ PATH_CHECK(path("../..").normalize(), "../..");
+ PATH_CHECK(path("/..").normalize(), "/..");
+ PATH_CHECK(path("/../..").normalize(), "/../..");
+ PATH_CHECK(path("../foo").normalize(), "../foo");
+ PATH_CHECK(path("foo/..").normalize(), ".");
+ PATH_CHECK(path("foo/../").normalize(), ".");
+ PATH_CHECK((path("foo") / "..").normalize(), ".");
+ PATH_CHECK(path("foo/...").normalize(), "foo/...");
+ PATH_CHECK(path("foo/.../").normalize(), "foo/.../.");
+ PATH_CHECK(path("foo/..bar").normalize(), "foo/..bar");
+ PATH_CHECK(path("../f").normalize(), "../f");
+ PATH_CHECK(path("/../f").normalize(), "/../f");
+ PATH_CHECK(path("f/..").normalize(), ".");
+ PATH_CHECK((path("f") / "..").normalize(), ".");
+ PATH_CHECK(path("foo/../..").normalize(), "..");
+ PATH_CHECK(path("foo/../../").normalize(), "../.");
+ PATH_CHECK(path("foo/../../..").normalize(), "../..");
+ PATH_CHECK(path("foo/../../../").normalize(), "../../.");
+ PATH_CHECK(path("foo/../bar").normalize(), "bar");
+ PATH_CHECK(path("foo/../bar/").normalize(), "bar/.");
+ PATH_CHECK(path("foo/bar/..").normalize(), "foo");
+ PATH_CHECK(path("foo/bar/../").normalize(), "foo/.");
+ PATH_CHECK(path("foo/bar/../..").normalize(), ".");
+ PATH_CHECK(path("foo/bar/../../").normalize(), ".");
+ PATH_CHECK(path("foo/bar/../blah").normalize(), "foo/blah");
+ PATH_CHECK(path("f/../b").normalize(), "b");
+ PATH_CHECK(path("f/b/..").normalize(), "f");
+ PATH_CHECK(path("f/b/../").normalize(), "f/.");
+ PATH_CHECK(path("f/b/../a").normalize(), "f/a");
+ PATH_CHECK(path("foo/bar/blah/../..").normalize(), "foo");
+ PATH_CHECK(path("foo/bar/blah/../../bletch").normalize(), "foo/bletch");
+ PATH_CHECK(path("//net").normalize(), "//net");
+ PATH_CHECK(path("//net/").normalize(), "//net/");
+ PATH_CHECK(path("//..net").normalize(), "//..net");
+ PATH_CHECK(path("//net/..").normalize(), "//net/..");
+ PATH_CHECK(path("//net/foo").normalize(), "//net/foo");
+ PATH_CHECK(path("//net/foo/").normalize(), "//net/foo/.");
+ PATH_CHECK(path("//net/foo/..").normalize(), "//net/");
+ PATH_CHECK(path("//net/foo/../").normalize(), "//net/.");
+
+ PATH_CHECK(path("/net/foo/bar").normalize(), "/net/foo/bar");
+ PATH_CHECK(path("/net/foo/bar/").normalize(), "/net/foo/bar/.");
+ PATH_CHECK(path("/net/foo/..").normalize(), "/net");
+ PATH_CHECK(path("/net/foo/../").normalize(), "/net/.");
+
+ PATH_CHECK(path("//net//foo//bar").normalize(), "//net/foo/bar");
+ PATH_CHECK(path("//net//foo//bar//").normalize(), "//net/foo/bar/.");
+ PATH_CHECK(path("//net//foo//..").normalize(), "//net/");
+ PATH_CHECK(path("//net//foo//..//").normalize(), "//net/.");
+
+ PATH_CHECK(path("///net///foo///bar").normalize(), "/net/foo/bar");
+ PATH_CHECK(path("///net///foo///bar///").normalize(), "/net/foo/bar/.");
+ PATH_CHECK(path("///net///foo///..").normalize(), "/net");
+ PATH_CHECK(path("///net///foo///..///").normalize(), "/net/.");
+
+ if (platform == "Windows")
+ {
+ PATH_CHECK(path("c:..").normalize(), "c:..");
+ PATH_CHECK(path("c:foo/..").normalize(), "c:");
+
+ PATH_CHECK(path("c:foo/../").normalize(), "c:.");
+
+ PATH_CHECK(path("c:/foo/..").normalize(), "c:/");
+ PATH_CHECK(path("c:/foo/../").normalize(), "c:/.");
+ PATH_CHECK(path("c:/..").normalize(), "c:/..");
+ PATH_CHECK(path("c:/../").normalize(), "c:/../.");
+ PATH_CHECK(path("c:/../..").normalize(), "c:/../..");
+ PATH_CHECK(path("c:/../../").normalize(), "c:/../../.");
+ PATH_CHECK(path("c:/../foo").normalize(), "c:/../foo");
+ PATH_CHECK(path("c:/../foo/").normalize(), "c:/../foo/.");
+ PATH_CHECK(path("c:/../../foo").normalize(), "c:/../../foo");
+ PATH_CHECK(path("c:/../../foo/").normalize(), "c:/../../foo/.");
+ PATH_CHECK(path("c:/..foo").normalize(), "c:/..foo");
+ }
+ else // POSIX
+ {
+ PATH_CHECK(path("c:..").normalize(), "c:..");
+ PATH_CHECK(path("c:foo/..").normalize(), ".");
+ PATH_CHECK(path("c:foo/../").normalize(), ".");
+ PATH_CHECK(path("c:/foo/..").normalize(), "c:");
+ PATH_CHECK(path("c:/foo/../").normalize(), "c:/.");
+ PATH_CHECK(path("c:/..").normalize(), ".");
+ PATH_CHECK(path("c:/../").normalize(), ".");
+ PATH_CHECK(path("c:/../..").normalize(), "..");
+ PATH_CHECK(path("c:/../../").normalize(), "../.");
+ PATH_CHECK(path("c:/../foo").normalize(), "foo");
+ PATH_CHECK(path("c:/../foo/").normalize(), "foo/.");
+ PATH_CHECK(path("c:/../../foo").normalize(), "../foo");
+ PATH_CHECK(path("c:/../../foo/").normalize(), "../foo/.");
+ PATH_CHECK(path("c:/..foo").normalize(), "c:/..foo");
+ }
+}
+
+// misc_test ------------------------------------------------------------------------//
+
+void misc_test()
+{
+ fs::path p;
+
+ fs::initial_path< fs::path >();
+ fs::initial_path< fs::wpath >();
+
+ p.file_string();
+ p.directory_string();
+}
+
+// path_rename_test -----------------------------------------------------------------//
+
+void path_rename_test()
+{
+ fs::path p("foo/bar/blah");
+
+ BOOST_TEST_EQ(path("foo/bar/blah").remove_leaf(), "foo/bar");
+ BOOST_TEST_EQ(p.leaf(), "blah");
+ BOOST_TEST_EQ(p.branch_path(), "foo/bar");
+ BOOST_TEST(p.has_leaf());
+ BOOST_TEST(p.has_branch_path());
+ BOOST_TEST(!p.is_complete());
+
+ if (platform == "Windows")
+ {
+ BOOST_TEST_EQ(path("foo\\bar\\blah").remove_leaf(), "foo\\bar");
+ p = "foo\\bar\\blah";
+ BOOST_TEST_EQ(p.branch_path(), "foo\\bar");
+ }
+}
+
+// string_file_tests ---------------------------------------------------------------//
+
+void string_file_tests(const fs::path& temp_dir)
+{
+ std::cout << "string_file_tests..." << std::endl;
+ std::string contents("0123456789");
+ fs::path p(temp_dir / "string_file");
+ save_string_file(p, contents);
+ save_string_file(p, contents);
+ BOOST_TEST_EQ(file_size(p), 10u);
+ std::string round_trip;
+ load_string_file(p, round_trip);
+ BOOST_TEST_EQ(contents, round_trip);
+}
+
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+
+int cpp_main(int /*argc*/, char* /*argv*/[])
+{
+ // The choice of platform is make at runtime rather than compile-time
+ // so that compile errors for all platforms will be detected even though
+ // only the current platform is runtime tested.
+ platform = (platform == "Win32" || platform == "Win64" || platform == "Cygwin") ? "Windows" : "POSIX";
+ std::cout << "Platform is " << platform << '\n';
+
+ BOOST_TEST(fs::initial_path() == fs::current_path());
+
+ //path::default_name_check(fs::no_check);
+
+ fs::directory_entry de("foo/bar");
+
+ de.replace_leaf("", fs::file_status(), fs::file_status());
+
+ //de.leaf();
+ //de.string();
+
+ fs::path ng(" no-way, Jose");
+ BOOST_TEST(!fs::is_regular(ng)); // verify deprecated name still works
+ BOOST_TEST(!fs::symbolic_link_exists("nosuchfileordirectory"));
+
+ const fs::path temp_dir(fs::current_path() / ".." / fs::unique_path("deprecated_test-%%%%-%%%%-%%%%"));
+ std::cout << "temp_dir is " << temp_dir.string() << std::endl;
+
+ fs::create_directory(temp_dir);
+
+ misc_test();
+ path_rename_test();
+ normalize_test();
+ string_file_tests(temp_dir);
+
+ BOOST_TEST(fs::path("foo/bar").generic() == fs::path("foo/bar"));
+
+ // extension() tests ---------------------------------------------------------//
+
+ BOOST_TEST(fs::extension("a/b") == "");
+ BOOST_TEST(fs::extension("a/b.txt") == ".txt");
+ BOOST_TEST(fs::extension("a/b.") == ".");
+ BOOST_TEST(fs::extension("a.b.c") == ".c");
+ BOOST_TEST(fs::extension("a.b.c.") == ".");
+ BOOST_TEST(fs::extension("") == "");
+ BOOST_TEST(fs::extension("a/") == "");
+
+ // basename() tests ----------------------------------------------------------//
+
+ BOOST_TEST(fs::basename("b") == "b");
+ BOOST_TEST(fs::basename("a/b.txt") == "b");
+ BOOST_TEST(fs::basename("a/b.") == "b");
+ BOOST_TEST(fs::basename("a.b.c") == "a.b");
+ BOOST_TEST(fs::basename("a.b.c.") == "a.b.c");
+ BOOST_TEST(fs::basename("") == "");
+
+ // change_extension tests ---------------------------------------------------//
+
+ BOOST_TEST(fs::change_extension("a.txt", ".tex").string() == "a.tex");
+ BOOST_TEST(fs::change_extension("a.", ".tex").string() == "a.tex");
+ BOOST_TEST(fs::change_extension("a", ".txt").string() == "a.txt");
+ BOOST_TEST(fs::change_extension("a.b.txt", ".tex").string() == "a.b.tex");
+ // see the rationale in html docs for explanation why this works
+ BOOST_TEST(fs::change_extension("", ".png").string() == ".png");
+
+ std::cout << "post-test removal of " << temp_dir << std::endl;
+ BOOST_TEST(fs::remove_all(temp_dir) != 0);
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/design_use_cases.cpp b/src/boost/libs/filesystem/test/design_use_cases.cpp
new file mode 100644
index 000000000..dbbf3ed22
--- /dev/null
+++ b/src/boost/libs/filesystem/test/design_use_cases.cpp
@@ -0,0 +1,81 @@
+#include <string>
+#include <iostream>
+
+// Minimal class path
+
+class path
+{
+public:
+ path(const char*)
+ {
+ std::cout << "path( const char * )\n";
+ }
+ path(const std::string&)
+ {
+ std::cout << "path( std::string & )\n";
+ }
+
+// for maximum efficiency, either signature must work
+#ifdef BY_VALUE
+ operator const std::string() const
+#else
+ operator const std::string&() const
+#endif
+ {
+ std::cout << "operator string\n";
+ return m_path;
+ }
+
+#ifdef NAMED_CONVERSION
+ std::string string() const
+ {
+ std::cout << "std::string string() const\n";
+ return m_path;
+ }
+#endif
+
+private:
+ std::string m_path;
+};
+
+bool operator==(const path&, const path&)
+{
+ std::cout << "operator==( const path &, const path & )\n";
+ return true;
+}
+
+// These are the critical use cases. If any of these don't compile, usability
+// is unacceptably degraded.
+
+void f(const path&)
+{
+ std::cout << "f( const path & )\n";
+}
+
+int main()
+{
+ f("foo");
+ f(std::string("foo"));
+ f(path("foo"));
+
+ std::cout << '\n';
+
+ std::string s1(path("foo"));
+ std::string s2 = path("foo");
+ s2 = path("foo");
+
+#ifdef NAMED_CONVERSION
+ s2 = path("foo").string();
+#endif
+
+ std::cout << '\n';
+
+ // these must call bool path( const path &, const path & );
+ path("foo") == path("foo");
+ path("foo") == "foo";
+ path("foo") == std::string("foo");
+ "foo" == path("foo");
+ std::string("foo") == path("foo");
+
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/equivalent.cpp b/src/boost/libs/filesystem/test/equivalent.cpp
new file mode 100644
index 000000000..92875a776
--- /dev/null
+++ b/src/boost/libs/filesystem/test/equivalent.cpp
@@ -0,0 +1,39 @@
+// equivalent program -------------------------------------------------------//
+
+// Copyright (c) 2004 Beman Dawes
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
+// at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//----------------------------------------------------------------------------//
+
+#include <boost/filesystem/operations.hpp>
+#include <iostream>
+#include <exception>
+
+int main(int argc, char* argv[])
+{
+ boost::filesystem::path::default_name_check(boost::filesystem::native);
+ if (argc != 3)
+ {
+ std::cout << "Usage: equivalent path1 path2\n";
+ return 2;
+ }
+
+ bool eq;
+ try
+ {
+ eq = boost::filesystem::equivalent(argv[1], argv[2]);
+ }
+ catch (const std::exception& ex)
+ {
+ std::cout << ex.what() << "\n";
+ return 3;
+ }
+
+ std::cout << (eq ? "Paths are equivalent\n" : "Paths are not equivalent\n");
+ return !eq;
+}
diff --git a/src/boost/libs/filesystem/test/foreach_test.cpp b/src/boost/libs/filesystem/test/foreach_test.cpp
new file mode 100644
index 000000000..50a86c76e
--- /dev/null
+++ b/src/boost/libs/filesystem/test/foreach_test.cpp
@@ -0,0 +1,62 @@
+
+// Copyright 2018 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+#include <boost/filesystem.hpp>
+#include <boost/foreach.hpp>
+#include <boost/config.hpp>
+
+namespace fs = boost::filesystem;
+
+int main()
+{
+ {
+ fs::directory_iterator const it;
+
+ BOOST_FOREACH(fs::path const& p, it)
+ {
+ p.string();
+ }
+ }
+
+#if !defined(BOOST_NO_CXX11_RANGE_BASED_FOR)
+
+ {
+ fs::directory_iterator const it;
+
+ for (fs::path const& p : it)
+ {
+ p.string();
+ }
+ }
+
+#endif
+
+ {
+ fs::recursive_directory_iterator it;
+
+ BOOST_FOREACH(fs::path const& p, it)
+ {
+ p.string();
+ }
+ }
+
+#if !defined(BOOST_NO_CXX11_RANGE_BASED_FOR)
+
+ {
+ fs::recursive_directory_iterator const it;
+
+ for (fs::path const& p : it)
+ {
+ p.string();
+ }
+ }
+
+#endif
+}
diff --git a/src/boost/libs/filesystem/test/fstream_test.cpp b/src/boost/libs/filesystem/test/fstream_test.cpp
new file mode 100644
index 000000000..77fa5c2c6
--- /dev/null
+++ b/src/boost/libs/filesystem/test/fstream_test.cpp
@@ -0,0 +1,164 @@
+// fstream_test.cpp ------------------------------------------------------------------//
+
+// Copyright Beman Dawes 2002
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#endif
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <string>
+#include <iostream>
+#include <cstdio> // for std::remove
+
+#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
+
+namespace fs = boost::filesystem;
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std {
+using ::remove;
+}
+#endif
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+
+namespace {
+bool cleanup = true;
+
+void test(const fs::path& p)
+{
+ fs::remove(p);
+ {
+ std::cout << " in test 1\n";
+ fs::filebuf fb1;
+ fb1.open(p, std::ios_base::out);
+ BOOST_TEST(fb1.is_open());
+ }
+ {
+ std::cout << " in test 2\n";
+ fs::filebuf fb2;
+ fb2.open(p, std::ios_base::in);
+ BOOST_TEST(fb2.is_open());
+ }
+ {
+ std::cout << " in test 3\n";
+ fs::ifstream tfs(p);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 4\n";
+ fs::ifstream tfs(p / p.filename()); // should fail
+ BOOST_TEST(!tfs.is_open());
+ }
+ {
+ std::cout << " in test 5\n";
+ fs::ifstream tfs(p, std::ios_base::in);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 6\n";
+ fs::ifstream tfs;
+ tfs.open(p);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 7\n";
+ fs::ifstream tfs;
+ tfs.open(p, std::ios_base::in);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 8\n";
+ fs::ofstream tfs(p);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 9\n";
+ fs::ofstream tfs(p, std::ios_base::out);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 10\n";
+ fs::ofstream tfs;
+ tfs.open(p);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 11\n";
+ fs::ofstream tfs;
+ tfs.open(p, std::ios_base::out);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 12\n";
+ fs::fstream tfs(p);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 13\n";
+ fs::fstream tfs(p, std::ios_base::in | std::ios_base::out);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 14\n";
+ fs::fstream tfs;
+ tfs.open(p);
+ BOOST_TEST(tfs.is_open());
+ }
+ {
+ std::cout << " in test 15\n";
+ fs::fstream tfs;
+ tfs.open(p, std::ios_base::in | std::ios_base::out);
+ BOOST_TEST(tfs.is_open());
+ }
+
+ if (cleanup)
+ fs::remove(p);
+
+} // test
+} // unnamed namespace
+
+int cpp_main(int argc, char*[])
+{
+ if (argc > 1)
+ cleanup = false;
+
+ std::cout << "BOOST_FILESYSTEM_C_STR(p) defined as \""
+ << BOOST_STRINGIZE(BOOST_FILESYSTEM_C_STR(p)) << "\"\n";
+
+ // test narrow characters
+ std::cout << "narrow character tests:\n";
+ test("narrow_fstream_test");
+
+ // So that tests are run with known encoding, use Boost UTF-8 codecvt
+ std::locale global_loc = std::locale();
+ std::locale loc(global_loc, new fs::detail::utf8_codecvt_facet());
+ fs::path::imbue(loc);
+
+ // test with some wide characters
+ // \u2780 is circled 1 against white background == e2 9e 80 in UTF-8
+ // \u2781 is circled 2 against white background == e2 9e 81 in UTF-8
+ // \u263A is a white smiling face
+ std::cout << "\nwide character tests:\n";
+ std::wstring ws(L"wide_fstream_test_");
+ ws.push_back(static_cast< wchar_t >(0x2780));
+ ws.push_back(static_cast< wchar_t >(0x263A));
+ test(ws);
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/issues/10038.cpp b/src/boost/libs/filesystem/test/issues/10038.cpp
new file mode 100644
index 000000000..15b500571
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/10038.cpp
@@ -0,0 +1,7 @@
+#include <boost/filesystem.hpp>
+
+int main(void)
+{
+ boost::filesystem::copy_file("a", "b");
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/issues/10205.cpp b/src/boost/libs/filesystem/test/issues/10205.cpp
new file mode 100644
index 000000000..966d5d638
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/10205.cpp
@@ -0,0 +1,17 @@
+// Linux test; before running: export LANG=foo
+
+#include <locale>
+#include <iostream>
+#include <string>
+#include <boost/filesystem/path.hpp>
+
+int main()
+{
+ std::string pathname = "/some/filesystem/path/%%%%";
+
+ boost::filesystem::path path(pathname);
+
+ std::wcout << path.wstring() << std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/issues/10485.cpp b/src/boost/libs/filesystem/test/issues/10485.cpp
new file mode 100644
index 000000000..aa9a03b07
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/10485.cpp
@@ -0,0 +1,14 @@
+// Copyright iamvfx@gmail.com 2014
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <stdio.h>
+#include <boost/filesystem.hpp>
+
+int main()
+{
+ boost::filesystem::path dir("/");
+ for (char c : dir.filename().string())
+ printf("%c\n", c);
+}
diff --git a/src/boost/libs/filesystem/test/issues/10641.cpp b/src/boost/libs/filesystem/test/issues/10641.cpp
new file mode 100644
index 000000000..210739644
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/10641.cpp
@@ -0,0 +1,22 @@
+#include <iostream>
+#include <boost/filesystem/path.hpp>
+using namespace std;
+namespace fs = boost::filesystem;
+int main(int argc, char** argv)
+{
+
+ try
+ {
+ fs::path my_path("test/test.txt");
+ cout << "current path is " << my_path << endl;
+ cout << "parent path is " << my_path.parent_path() << endl;
+ }
+ catch (std::exception& e)
+ {
+ cerr << endl
+ << "Error during execution: " << e.what() << endl
+ << endl;
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/src/boost/libs/filesystem/test/issues/11166-remove-race.cpp b/src/boost/libs/filesystem/test/issues/11166-remove-race.cpp
new file mode 100644
index 000000000..a871ad71e
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/11166-remove-race.cpp
@@ -0,0 +1,40 @@
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+#include <fstream>
+
+boost::condition_variable cond;
+boost::mutex mut;
+
+#define FNAME ("remove-test")
+void remover()
+{
+ while (1)
+ {
+ boost::filesystem::remove(FNAME);
+ }
+}
+
+void creater()
+{
+ for (int i = 0; i < 100000; i++)
+ std::fstream(FNAME, std::fstream::out);
+}
+
+int main()
+{
+ boost::filesystem::remove(FNAME);
+ boost::filesystem::remove(FNAME);
+
+ std::cout << "If you got this far, it's OK to remove a file that doesn't exist\n"
+ "Now trying with one creator thread and two remover threads.\n"
+ "This is likely to crash after just a few seconds at most."
+ << std::endl;
+
+ boost::thread c(creater), r1(remover), r2(remover);
+
+ c.join();
+ r1.interrupt();
+ r1.join();
+ r2.interrupt();
+ r2.join();
+}
diff --git a/src/boost/libs/filesystem/test/issues/11228--filtered-recursive_directory_iterator-range.cpp b/src/boost/libs/filesystem/test/issues/11228--filtered-recursive_directory_iterator-range.cpp
new file mode 100644
index 000000000..4e12bb792
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/11228--filtered-recursive_directory_iterator-range.cpp
@@ -0,0 +1,24 @@
+#include <boost/filesystem.hpp>
+#include <boost/range.hpp>
+#include <boost/range/algorithm.hpp>
+#include <boost/range/adaptors.hpp>
+#include <vector>
+#include <iostream>
+
+namespace fs = boost::filesystem;
+using namespace boost::adaptors;
+
+int main()
+{
+ fs::recursive_directory_iterator beg("."), end;
+
+ auto fileFilter = [](fs::path const& path) {
+ return is_regular_file(path);
+ };
+
+ std::vector< fs::path > paths;
+ copy(boost::make_iterator_range(beg, end) | filtered(fileFilter), std::back_inserter(paths));
+
+ for (auto& p : paths)
+ std::cout << p << "\n";
+} \ No newline at end of file
diff --git a/src/boost/libs/filesystem/test/issues/3332/test.cpp b/src/boost/libs/filesystem/test/issues/3332/test.cpp
new file mode 100644
index 000000000..f43acdc4a
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/3332/test.cpp
@@ -0,0 +1,37 @@
+#include <boost/filesystem.hpp>
+#include <cvt/cp950>
+#include <iostream>
+#include <string>
+#include <locale>
+
+namespace fs = boost::filesystem;
+
+int main(void)
+{
+
+ std::locale global_loc = std::locale();
+ std::locale loc(global_loc, new stdext::cvt::codecvt_cp950< wchar_t >);
+ fs::path::imbue(loc);
+
+ std::cout << "HEADS UP! PIPE OUTPUT TO FILE AND INSPECT WITH HEX OR CP950 EDITOR.\n"
+ "WINDOWS COMMAND PROMPT FONTS DON'T SUPPORT CHINESE,\n"
+ "EVEN WITH CODEPAGE SET AND EVEN AS OF WIN 10 TECH PREVIEW."
+ << std::endl;
+
+ fs::recursive_directory_iterator end;
+ fs::recursive_directory_iterator iter("C:/boost/test-files/utf-8");
+
+ while (iter != end)
+ {
+ if (fs::is_directory(*iter))
+ {
+ std::cout << "[directory] " << iter->path().generic_string() << std::endl;
+ }
+ else if (fs::is_regular(*iter))
+ {
+ std::cout << " [file] " << iter->path().generic_string() << std::endl;
+ }
+ ++iter;
+ }
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/issues/4329.-basename.cpp b/src/boost/libs/filesystem/test/issues/4329.-basename.cpp
new file mode 100644
index 000000000..80ba03c95
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/4329.-basename.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <boost/filesystem.hpp>
+using boost::filesystem::path;
+
+int main()
+{
+ std::cout << path("a").stem() << std::endl;
+ std::cout << path("a/").stem() << std::endl;
+ std::cout << path("a/b").stem() << std::endl;
+ std::cout << path("a/b/").stem() << std::endl;
+ std::cout << path("a/b/c").stem() << std::endl;
+ std::cout << path("a/b/c/").stem() << std::endl;
+ std::cout << path("a/b/c/d").stem() << std::endl;
+ std::cout << path("a/b/c/d/").stem() << std::endl;
+ std::cout << path("a/b/c/d/e").stem() << std::endl;
+ std::cout << path("a/b/c/d/e/").stem() << std::endl;
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/issues/5300-temp-dir-path-130.cpp b/src/boost/libs/filesystem/test/issues/5300-temp-dir-path-130.cpp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/5300-temp-dir-path-130.cpp
diff --git a/src/boost/libs/filesystem/test/issues/6638-global-init-fails-3.cpp b/src/boost/libs/filesystem/test/issues/6638-global-init-fails-3.cpp
new file mode 100644
index 000000000..2bedbcdae
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/6638-global-init-fails-3.cpp
@@ -0,0 +1,36 @@
+#include <boost/filesystem.hpp>
+#include <boost/detail/lightweight_main.hpp>
+#include <string>
+
+using namespace boost::filesystem;
+
+// The original bug report was that this broke:
+// path p(L"C:\\TEMP\\");
+// path r(p / "narrow");
+// That code now works, but ...
+
+// Nils Gladitz has provided this example ...
+
+class Test
+{
+public:
+ ~Test()
+ {
+ path p(L"C:\\TEMP\\");
+ path r(p / "narrow");
+ }
+};
+
+// path p("narrow");
+
+// fails if static linked and Test object is global variable, but does not fail if
+// path p("narrow") line above is not commented out, and also does not fail if the
+// Test test2 line below is commented out.
+
+Test test1;
+Test test2;
+
+int cpp_main(int, char*[])
+{
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/issues/70-71-copy.cpp b/src/boost/libs/filesystem/test/issues/70-71-copy.cpp
new file mode 100644
index 000000000..98e621be0
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/70-71-copy.cpp
@@ -0,0 +1,20 @@
+
+// Copyright 2018 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+#include <boost/filesystem.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+namespace fs = boost::filesystem;
+
+int main()
+{
+ BOOST_TEST_THROWS(fs::copy("/tmp/non-existent-a", "/tmp/non-existent-b"), std::exception);
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/issues/8930.cpp b/src/boost/libs/filesystem/test/issues/8930.cpp
new file mode 100644
index 000000000..1c3c252a1
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/8930.cpp
@@ -0,0 +1,7 @@
+// Before running this test: export LANG=foo
+
+#include <boost/filesystem.hpp>
+int main()
+{
+ boost::filesystem::path("/abc").root_directory();
+}
diff --git a/src/boost/libs/filesystem/test/issues/9054_static_const_codecvt_segfault_pre_main.cpp b/src/boost/libs/filesystem/test/issues/9054_static_const_codecvt_segfault_pre_main.cpp
new file mode 100644
index 000000000..53234b4a2
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/9054_static_const_codecvt_segfault_pre_main.cpp
@@ -0,0 +1,9 @@
+#include "boost/filesystem.hpp"
+
+static const boost::filesystem::path::codecvt_type& dummy =
+ boost::filesystem::path::codecvt();
+
+int main()
+{
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/issues/9219.cpp b/src/boost/libs/filesystem/test/issues/9219.cpp
new file mode 100644
index 000000000..7da6488e8
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/9219.cpp
@@ -0,0 +1,40 @@
+// Boost 9219.cpp --------------------------------------------------------------------//
+
+// Copyright Beman Dawes 2014
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+// //
+// In researching filesystem issues it is convenient to have a program that can be //
+// quickly modified to test reported problems. That's the purpose of this file and //
+// its associated Visual Studio and Boost.Build infrastructure. //
+// //
+//--------------------------------------------------------------------------------------//
+
+#include <boost/config/warning_disable.hpp>
+
+#include <boost/filesystem.hpp>
+
+#include <iostream>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+
+using std::cout;
+using std::endl;
+namespace fs = boost::filesystem;
+
+//------------------------------------ cpp_main --------------------------------------//
+
+int cpp_main(int argc, char* argv[])
+{
+ cout << "Hello, 9219" << endl;
+ cout << "This is a test for non-Windows systems" << endl;
+
+ BOOST_TEST(fs::exists(const_cast< char* >(".")));
+
+ return ::boost::report_errors();
+} // cpp_main
diff --git a/src/boost/libs/filesystem/test/issues/99_canonical_with_junction_point.cpp b/src/boost/libs/filesystem/test/issues/99_canonical_with_junction_point.cpp
new file mode 100644
index 000000000..38e3bc078
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/99_canonical_with_junction_point.cpp
@@ -0,0 +1,85 @@
+// Boost operations_test.cpp ---------------------------------------------------------//
+
+// Copyright Alexander Grund 2020
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#include <iostream>
+
+#if defined(BOOST_FILESYSTEM_HAS_MKLINK)
+
+#include <boost/filesystem.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <cstdlib>
+#include <vector>
+
+namespace fs = boost::filesystem;
+
+struct TmpDir
+{
+ fs::path path;
+ TmpDir(const fs::path& base) :
+ path(fs::absolute(base) / fs::unique_path())
+ {
+ fs::create_directories(path);
+ }
+ ~TmpDir()
+ {
+ boost::system::error_code ec;
+ fs::remove_all(path, ec);
+ }
+};
+
+// Test fs::canonical for various path in a Windows directory junction point
+// This failed before due to broken handling of absolute paths and ignored ReparseTag
+int main()
+{
+
+ const fs::path cwd = fs::current_path();
+ const TmpDir tmp(cwd);
+ const fs::path junction = tmp.path / "junction";
+ const fs::path real = tmp.path / "real";
+ const fs::path subDir = "sub";
+ fs::create_directories(real / subDir);
+ fs::current_path(tmp.path);
+ BOOST_TEST(std::system("mklink /J junction real") == 0);
+ BOOST_TEST(fs::exists(junction));
+
+ // Due to a bug there was a dependency on the current path so try the below for all:
+ std::vector< fs::path > paths;
+ paths.push_back(cwd);
+ paths.push_back(junction);
+ paths.push_back(real);
+ paths.push_back(junction / subDir);
+ paths.push_back(real / subDir);
+ for (std::vector< fs::path >::iterator it = paths.begin(); it != paths.end(); ++it)
+ {
+ std::cout << "Testing in " << *it << std::endl;
+ fs::current_path(*it);
+
+ // Used by canonical, must work too
+ BOOST_TEST(fs::read_symlink(junction) == real);
+
+ BOOST_TEST(fs::canonical(junction) == real);
+ BOOST_TEST(fs::canonical(junction / subDir) == real / subDir);
+ }
+
+ // Restore the original current directory so that temp directory can be removed
+ fs::current_path(cwd);
+
+ return boost::report_errors();
+}
+
+#else // defined(BOOST_FILESYSTEM_HAS_MKLINK)
+
+int main()
+{
+ std::cout << "Skipping test as the target system does not support mklink." << std::endl;
+ return 0;
+}
+
+#endif // defined(BOOST_FILESYSTEM_HAS_MKLINK)
diff --git a/src/boost/libs/filesystem/test/issues/Jamfile.v2 b/src/boost/libs/filesystem/test/issues/Jamfile.v2
new file mode 100644
index 000000000..47fce4075
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/Jamfile.v2
@@ -0,0 +1,38 @@
+# Boost Filesystem test/issues Jamfile
+
+# Copyright Beman Dawes 2014
+
+# Distributed under the Boost Software License, Version 1.0.
+# See www.boost.org/LICENSE_1_0.txt
+
+# Library home page: http://www.boost.org/libs/filesystem
+
+project
+ : requirements
+ <library>/boost/filesystem//boost_filesystem
+ <link>static
+ ;
+
+ test-suite "filesystem-issues" :
+# [ run 9054_static_const_codecvt_segfault_pre_main.cpp
+# : : : <link>shared : 9054_shared ]
+# [ run 9054_static_const_codecvt_segfault_pre_main.cpp
+# : : : <link>static : 9054_static ]
+# [ run hello_filesystem.cpp
+# : : : <link>shared : hello_shared ]
+# [ run hello_filesystem.cpp
+# : : : <link>static : hello_static ]
+# [ run 9219.cpp
+# : : : <link>shared : 9219_shared ]
+# [ run 9219.cpp
+# : : : <link>static : 9219_static ]
+# [ run 10485.cpp
+# : : : <link>shared <test-info>always_show_run_output ]
+# [ run copy_file-compilation-error-2015-05-04.cpp ]
+ [ run 6638-convert_aux-fails-init-global.cpp
+ : : : <link>shared : 6638_shared ]
+ [ run 6638-convert_aux-fails-init-global.cpp
+ : : : <link>static : 6638_static ]
+
+ ;
+
diff --git a/src/boost/libs/filesystem/test/issues/boost-no-inspect b/src/boost/libs/filesystem/test/issues/boost-no-inspect
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/boost-no-inspect
diff --git a/src/boost/libs/filesystem/test/issues/copy_file-compilation-error-2015-05-04.cpp b/src/boost/libs/filesystem/test/issues/copy_file-compilation-error-2015-05-04.cpp
new file mode 100644
index 000000000..8c2ea398f
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/copy_file-compilation-error-2015-05-04.cpp
@@ -0,0 +1,14 @@
+// Rob Conde <rob.conde@ai-solutions.com> reports this fails
+// to compile for Boost 1.58 with g++ 4.4.7 but is OK with FC++ 2013
+
+#include "boost/filesystem/operations.hpp"
+
+void myFunc()
+{
+ using namespace boost::filesystem;
+
+ copy_options opt(copy_options::overwrite_existing);
+
+ copy_file(path("p1"), path("p2"), copy_options::overwrite_existing);
+ // copy_file(path("p1"),path("p2"),opt);
+} \ No newline at end of file
diff --git a/src/boost/libs/filesystem/test/issues/fchmodat_AT_SYMLINK_NOFOLLOW_6659.cpp b/src/boost/libs/filesystem/test/issues/fchmodat_AT_SYMLINK_NOFOLLOW_6659.cpp
new file mode 100644
index 000000000..ea5a61980
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/fchmodat_AT_SYMLINK_NOFOLLOW_6659.cpp
@@ -0,0 +1,41 @@
+// Test program to demonstrate that Linux does not support AT_SYMLINK_NOFOLLOW
+
+// Copyright Duncan Exon Smith 2012
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Test this by running:
+//
+// rm -rf data && mkdir data && g++ -otest-fchmodat fchmodat_AT_SYMLINK_NOFOLLOW_6659.cpp && (cd data && ../test-fchmodat)
+//
+// If no assertions go off, then it looks like fchmodat is supported,
+// but AT_SYMLINK_NOFOLLOW is not supported.
+
+#include <fstream>
+#include <cassert>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <cerrno>
+
+#ifdef NDEBUG
+#error This program depends on assert() so makes no sense if NDEBUG is defined
+#endif
+
+int main(int argc, char* argv[])
+{
+ {
+ std::ofstream file("out");
+ file << "contents";
+ }
+
+ assert(!::symlink("out", "sym"));
+
+ assert(!::fchmodat(AT_FDCWD, "out", S_IRUSR | S_IWUSR | S_IXUSR, 0));
+ assert(!::fchmodat(AT_FDCWD, "sym", S_IRUSR | S_IWUSR | S_IXUSR, 0));
+
+ assert(::fchmodat(AT_FDCWD, "sym", S_IRUSR | S_IWUSR | S_IXUSR, AT_SYMLINK_NOFOLLOW) == -1);
+ assert(errno == ENOTSUP);
+
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/issues/hello_filesystem.cpp b/src/boost/libs/filesystem/test/issues/hello_filesystem.cpp
new file mode 100644
index 000000000..69124e53a
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/hello_filesystem.cpp
@@ -0,0 +1,39 @@
+// Boost hello_filesystem.cpp --------------------------------------------------------//
+
+// Copyright Beman Dawes 2014
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+// //
+// In researching filesystem issues it is convenient to have a program that can be //
+// quickly modified to test reported problems. That's the purpose of this file and //
+// its associated Visual Studio and Boost.Build infrastructure. //
+// //
+//--------------------------------------------------------------------------------------//
+
+#include <boost/config/warning_disable.hpp>
+
+#include <boost/filesystem.hpp>
+
+#include <iostream>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+
+using std::cout;
+using std::endl;
+namespace fs = boost::filesystem;
+
+//------------------------------------ cpp_main --------------------------------------//
+
+int cpp_main(int argc, char* argv[])
+{
+ cout << "Hello, filesystem world" << endl;
+
+ BOOST_TEST(fs::exists("."));
+
+ return ::boost::report_errors();
+} // cpp_main
diff --git a/src/boost/libs/filesystem/test/issues/readme.txt b/src/boost/libs/filesystem/test/issues/readme.txt
new file mode 100644
index 000000000..cf8198e5c
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/readme.txt
@@ -0,0 +1,9 @@
+This directory contains tests related to specific issues.
+
+The names are intended to indicate both the function or condition being tested
+and the issue number.
+
+-----
+Copyright Beman Dawes 2012
+Distributed under the Boost Software License, Version 1.0.
+See http://www.boost.org/LICENSE_1_0.txt
diff --git a/src/boost/libs/filesystem/test/issues/recurse_dir_iter_5403.cpp b/src/boost/libs/filesystem/test/issues/recurse_dir_iter_5403.cpp
new file mode 100644
index 000000000..ef6d0f4c2
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/recurse_dir_iter_5403.cpp
@@ -0,0 +1,116 @@
+// Boost Filesystem recurse_dir_iter_test.cpp ----------------------------------------//
+
+// Copyright Beman Dawes 2014.
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#endif
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/operations.hpp>
+
+#include <boost/cerrno.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+
+namespace fs = boost::filesystem;
+using boost::system::error_code;
+
+#include <iostream>
+
+using std::cout;
+using std::endl;
+
+namespace {
+typedef int errno_t;
+std::string platform(BOOST_PLATFORM);
+bool report_throws = false;
+bool cleanup = true;
+bool skip_long_windows_tests = false;
+
+} // unnamed namespace
+
+//------------------------------------------------------------------------------------//
+// //
+// main //
+// //
+//------------------------------------------------------------------------------------//
+
+int cpp_main(int argc, char* argv[])
+{
+ // document state of critical macros
+#ifdef BOOST_POSIX_API
+ cout << "BOOST_POSIX_API is defined\n";
+#endif
+#ifdef BOOST_WINDOWS_API
+ cout << "BOOST_WINDOWS_API is defined\n";
+#endif
+
+ for (; argc > 1; --argc, ++argv)
+ {
+ //if (*argv[1]=='-' && *(argv[1]+1)=='t')
+ // report_throws = true;
+ //else if (*argv[1]=='-' && *(argv[1]+1)=='x')
+ // cleanup = false;
+ //else if (*argv[1]=='-' && *(argv[1]+1)=='w')
+ // skip_long_windows_tests = true;
+ }
+
+ // The choice of platform to test is made at runtime rather than compile-time
+ // so that compile errors for all platforms will be detected even though
+ // only the current platform is runtime tested.
+#if defined(BOOST_POSIX_API)
+ platform = "POSIX";
+#elif defined(BOOST_WINDOWS_API)
+ platform = "Windows";
+#else
+#error neither BOOST_POSIX_API nor BOOST_WINDOWS_API is defined. See boost/system/api_config.hpp
+#endif
+ cout << "API is " << platform << endl;
+ cout << "initial_path() is " << fs::initial_path() << endl;
+ fs::path ip = fs::initial_path();
+
+ for (fs::path::const_iterator it = ip.begin(); it != ip.end(); ++it)
+ {
+ if (it != ip.begin())
+ cout << ", ";
+ cout << *it;
+ }
+ cout << endl;
+
+ // From the root, walk the directory tree looking for a permissions error
+
+ fs::recursive_directory_iterator it("/");
+ fs::recursive_directory_iterator end_it;
+
+ // The increment function has an invarient that it always makes progress,
+ // so even if an error occurs this loop will eventually terminate.
+
+ while (it != end_it)
+ {
+ error_code ec;
+ fs::path init_path = it->path();
+ it.increment(ec);
+ if (ec)
+ {
+ cout << "initial path: " << init_path << endl;
+ cout << "error_code: " << ec.value() << " with msg: " << ec.message() << endl;
+ if (it != end_it)
+ cout << "post-increment path: " << it->path() << endl;
+ }
+ }
+
+ cout << "returning from main()" << endl;
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/issues/reparse_tag_file_placeholder.cpp b/src/boost/libs/filesystem/test/issues/reparse_tag_file_placeholder.cpp
new file mode 100644
index 000000000..6c423a440
--- /dev/null
+++ b/src/boost/libs/filesystem/test/issues/reparse_tag_file_placeholder.cpp
@@ -0,0 +1,169 @@
+// Boost reparse_tag_file_placeholder.cpp ---------------------------------------------------------//
+
+// Copyright Roman Savchenko 2020
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#include <iostream>
+
+#if defined(BOOST_FILESYSTEM_HAS_MKLINK)
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+#include <cstddef>
+#include <exception>
+
+#include <windows.h>
+#include <winnt.h>
+
+#ifdef _MSC_VER
+#pragma comment(lib, "Advapi32.lib")
+#endif
+
+// Test correct boost::filesystem::status when reparse point ReparseTag set to IO_REPARSE_TAG_FILE_PLACEHOLDER
+// https://docs.microsoft.com/en-us/windows/compatibility/placeholder-files?redirectedfrom=MSDN
+
+#if !defined(__MINGW32__) || defined(__MINGW64__)
+typedef struct _REPARSE_DATA_BUFFER
+{
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union
+ {
+ struct
+ {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[1];
+ } SymbolicLinkReparseBuffer;
+ struct
+ {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct
+ {
+ UCHAR DataBuffer[1];
+ } GenericReparseBuffer;
+ };
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+#endif
+
+#ifndef IO_REPARSE_TAG_FILE_PLACEHOLDER
+#define IO_REPARSE_TAG_FILE_PLACEHOLDER (0x80000015L)
+#endif
+
+#ifndef FSCTL_SET_REPARSE_POINT
+#define FSCTL_SET_REPARSE_POINT (0x000900a4)
+#endif
+
+#ifndef REPARSE_DATA_BUFFER_HEADER_SIZE
+#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
+#endif
+
+bool obtain_restore_privilege()
+{
+ HANDLE hToken;
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
+ {
+ DWORD err = GetLastError();
+ std::cout << "OpenProcessToken() failed with: " << err << std::endl;
+ return false;
+ }
+
+ TOKEN_PRIVILEGES tp;
+ if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid))
+ {
+ DWORD err = GetLastError();
+ CloseHandle(hToken);
+ std::cout << "LookupPrivilegeValue() failed with: " << err << std::endl;
+ return false;
+ }
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
+ {
+ DWORD err = GetLastError();
+ CloseHandle(hToken);
+ std::cout << "AdjustTokenPrivileges() failed with: " << err << std::endl;
+ return false;
+ }
+
+ CloseHandle(hToken);
+ return true;
+}
+
+bool create_io_reparse_file_placeholder(const wchar_t* name)
+{
+ if (!obtain_restore_privilege())
+ {
+ return false;
+ }
+
+ HANDLE hHandle = CreateFileW(name, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_FLAG_OPEN_REPARSE_POINT, 0);
+ if (hHandle == INVALID_HANDLE_VALUE)
+ {
+ DWORD err = GetLastError();
+ std::cout << "CreateFile() failed with: " << err << std::endl;
+ return false;
+ }
+
+ PREPARSE_DATA_BUFFER pReparse = reinterpret_cast< PREPARSE_DATA_BUFFER >(GlobalAlloc(GPTR, MAXIMUM_REPARSE_DATA_BUFFER_SIZE));
+ if (!pReparse)
+ {
+ DWORD err = GetLastError();
+ CloseHandle(hHandle);
+ std::cout << "GlobalAlloc() failed with: " << err << std::endl;
+ return false;
+ }
+ //note: IO_REPARSE_TAG_FILE_PLACEHOLDER - just to show that reparse point could be not only symlink or junction
+ pReparse->ReparseTag = IO_REPARSE_TAG_FILE_PLACEHOLDER;
+
+ DWORD dwLen;
+ bool ret = !!DeviceIoControl(hHandle, FSCTL_SET_REPARSE_POINT, pReparse, pReparse->ReparseDataLength + REPARSE_DATA_BUFFER_HEADER_SIZE, NULL, 0, &dwLen, NULL);
+ if (!ret)
+ {
+ DWORD err = GetLastError();
+ std::cout << "DeviceIoControl() failed with: " << err << std::endl;
+ }
+
+ CloseHandle(hHandle);
+ GlobalFree(pReparse);
+ return ret;
+}
+
+int main()
+{
+ boost::filesystem::path rpt = boost::filesystem::temp_directory_path() / "reparse_point_test.txt";
+
+ BOOST_TEST(create_io_reparse_file_placeholder(rpt.native().c_str()));
+ std::cout << "Created file placeholder reparse point: " << rpt.string() << std::endl;
+ BOOST_TEST_NO_THROW(BOOST_TEST(boost::filesystem::status(rpt).type() == boost::filesystem::reparse_file));
+ BOOST_TEST_NO_THROW(BOOST_TEST(boost::filesystem::remove(rpt)));
+
+ return boost::report_errors();
+}
+
+#else // defined(BOOST_FILESYSTEM_HAS_MKLINK)
+
+int main()
+{
+ std::cout << "Skipping test as the target system does not support mklink." << std::endl;
+ return 0;
+}
+
+#endif // defined(BOOST_FILESYSTEM_HAS_MKLINK)
diff --git a/src/boost/libs/filesystem/test/large_file_support_test.cpp b/src/boost/libs/filesystem/test/large_file_support_test.cpp
new file mode 100644
index 000000000..75f4133df
--- /dev/null
+++ b/src/boost/libs/filesystem/test/large_file_support_test.cpp
@@ -0,0 +1,36 @@
+// Boost large_file_support_test.cpp ---------------------------------------//
+
+// Copyright Beman Dawes 2004.
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+// See deprecated_test for tests of deprecated features
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#define BOOST_SYSTEM_NO_DEPRECATED
+
+#include <boost/filesystem/operations.hpp>
+#include <iostream>
+
+namespace fs = boost::filesystem;
+
+int main()
+{
+ if (fs::detail::possible_large_file_size_support())
+ {
+ std::cout << "It appears that file sizes greater that 2 gigabytes are possible\n"
+ "for this configuration on this platform since the operating system\n"
+ "does use a large enough integer type to report large file sizes.\n\n"
+ "Whether or not such support is actually present depends on the OS\n";
+ return 0;
+ }
+ std::cout << "The operating system is using an integer type to report file sizes\n"
+ "that can not represent file sizes greater that 2 gigabytes (31-bits).\n"
+ "Thus the Filesystem Library will not correctly deal with such large\n"
+ "files. If you think that this operatiing system should be able to\n"
+ "support large files, please report the problem to the Boost developers\n"
+ "mailing list.\n";
+ return 1;
+}
diff --git a/src/boost/libs/filesystem/test/locale_info.cpp b/src/boost/libs/filesystem/test/locale_info.cpp
new file mode 100644
index 000000000..e9a8147eb
--- /dev/null
+++ b/src/boost/libs/filesystem/test/locale_info.cpp
@@ -0,0 +1,85 @@
+// locale_info.cpp ---------------------------------------------------------//
+
+// Copyright Beman Dawes 2011
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <locale>
+#include <iostream>
+#include <exception>
+#include <cstdlib>
+using namespace std;
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4996) // ... Function call with parameters that may be unsafe
+#endif
+
+namespace {
+void facet_info(const locale& loc, const char* msg)
+{
+ cout << "has_facet<std::codecvt<wchar_t, char, std::mbstate_t> >("
+ << msg << ") is "
+ << (has_facet< std::codecvt< wchar_t, char, std::mbstate_t > >(loc) ? "true\n" : "false\n");
+}
+
+void default_info()
+{
+ try
+ {
+ locale loc;
+ cout << "\nlocale default construction OK" << endl;
+ facet_info(loc, "locale()");
+ }
+ catch (const exception& ex)
+ {
+ cout << "\nlocale default construction threw: " << ex.what() << endl;
+ }
+}
+
+void null_string_info()
+{
+ try
+ {
+ locale loc("");
+ cout << "\nlocale(\"\") construction OK" << endl;
+ facet_info(loc, "locale(\"\")");
+ }
+ catch (const exception& ex)
+ {
+ cout << "\nlocale(\"\") construction threw: " << ex.what() << endl;
+ }
+}
+
+void classic_info()
+{
+ try
+ {
+ locale loc(locale::classic());
+ cout << "\nlocale(locale::classic()) copy construction OK" << endl;
+ facet_info(loc, "locale::classic()");
+ }
+ catch (const exception& ex)
+ {
+ cout << "\nlocale(locale::clasic()) copy construction threw: " << ex.what() << endl;
+ }
+}
+} // namespace
+
+int main()
+{
+ const char* lang = getenv("LANG");
+ cout << "\nLANG environmental variable is "
+ << (lang ? lang : "not present") << endl;
+
+ default_info();
+ null_string_info();
+ classic_info();
+
+ return 0;
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
diff --git a/src/boost/libs/filesystem/test/long_path_test.cpp b/src/boost/libs/filesystem/test/long_path_test.cpp
new file mode 100644
index 000000000..2503bb35f
--- /dev/null
+++ b/src/boost/libs/filesystem/test/long_path_test.cpp
@@ -0,0 +1,57 @@
+// long_path_test.cpp ----------------------------------------------------------------//
+
+// Copyright Beman Dawes 2011
+
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/btree for documentation.
+
+// See http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
+
+#include <boost/config/warning_disable.hpp>
+
+#include <boost/filesystem.hpp>
+#include <iostream>
+#include <string>
+
+using namespace boost::filesystem;
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+
+namespace {
+} // unnamed namespace
+
+int cpp_main(int, char*[])
+{
+
+ std::string prefix("d:\\temp\\");
+ std::cout << "prefix is " << prefix << '\n';
+
+ const std::size_t safe_size = 260 - prefix.size() - 100; // Windows MAX_PATH is 260
+
+ std::string safe_x_string(safe_size, 'x');
+ std::string safe_y_string(safe_size, 'y');
+ std::string path_escape("\\\\?\\");
+
+ path x_p(prefix + safe_x_string);
+ path y_p(path_escape + prefix + safe_x_string + "\\" + safe_y_string);
+
+ std::cout << "x_p.native().size() is " << x_p.native().size() << '\n';
+ std::cout << "y_p.native().size() is " << y_p.native().size() << '\n';
+
+ create_directory(x_p);
+ BOOST_TEST(exists(x_p));
+ create_directory(y_p);
+ BOOST_TEST(exists(y_p));
+
+ //std::cout << "directory x.../y... ready for testing, where ... is " << safe_size
+ // << " repeats of x and y, respectively\n";
+
+ BOOST_TEST(exists(x_p));
+
+ //remove_all(x_p);
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/macro_default_test.cpp b/src/boost/libs/filesystem/test/macro_default_test.cpp
new file mode 100644
index 000000000..96d9cf9a2
--- /dev/null
+++ b/src/boost/libs/filesystem/test/macro_default_test.cpp
@@ -0,0 +1,35 @@
+// macro_default_test program --------------------------------------------------------//
+
+// Copyright Beman Dawes 2012
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#undef BOOST_ALL_DYN_LINK
+#undef BOOST_ALL_STATIC_LINK
+#undef BOOST_FILESYSTEM_DYN_LINK
+#undef BOOST_FILESYSTEM_STATIC_LINK
+#undef BOOST_SYSTEM_DYN_LINK
+#undef BOOST_SYSTEM_STATIC_LINK
+
+#ifndef BOOST_ALL_NO_LIB
+#define BOOST_ALL_NO_LIB
+#endif
+
+#include <boost/filesystem/config.hpp>
+#include <boost/system/config.hpp>
+
+#ifndef BOOST_FILESYSTEM_STATIC_LINK
+#error BOOST_FILESYSTEM_STATIC_LINK not set by default
+#endif
+
+#ifndef BOOST_SYSTEM_STATIC_LINK
+#error BOOST_SYSTEM_STATIC_LINK not set by default
+#endif
+
+int main()
+{
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/odr1_test.cpp b/src/boost/libs/filesystem/test/odr1_test.cpp
new file mode 100644
index 000000000..460df12e9
--- /dev/null
+++ b/src/boost/libs/filesystem/test/odr1_test.cpp
@@ -0,0 +1,22 @@
+// Boost Filesystem odr1_test.cpp ----------------------------------------------------//
+
+// Copyright Beman Dawes 2014.
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#include <boost/filesystem.hpp>
+
+namespace boost {
+namespace filesystem {
+void tu2();
+}
+} // namespace boost
+
+int main()
+{
+ boost::filesystem::tu2();
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/odr2_test.cpp b/src/boost/libs/filesystem/test/odr2_test.cpp
new file mode 100644
index 000000000..b016382c2
--- /dev/null
+++ b/src/boost/libs/filesystem/test/odr2_test.cpp
@@ -0,0 +1,20 @@
+// Boost Filesystem odr2_test.cpp ----------------------------------------------------//
+
+// Copyright Beman Dawes 2014.
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#include <boost/filesystem.hpp>
+
+namespace boost {
+namespace filesystem {
+
+void tu2()
+{
+}
+
+} // namespace filesystem
+} // namespace boost
diff --git a/src/boost/libs/filesystem/test/operations_test.cpp b/src/boost/libs/filesystem/test/operations_test.cpp
new file mode 100644
index 000000000..eb4816b42
--- /dev/null
+++ b/src/boost/libs/filesystem/test/operations_test.cpp
@@ -0,0 +1,2786 @@
+// Boost operations_test.cpp ---------------------------------------------------------//
+
+// Copyright Beman Dawes 2002, 2009.
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#endif
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/directory.hpp>
+#include <boost/filesystem/exception.hpp>
+#include <boost/filesystem/file_status.hpp>
+#include <boost/filesystem/fstream.hpp> // for BOOST_FILESYSTEM_C_STR
+
+#include <boost/cerrno.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/system/system_category.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+
+namespace fs = boost::filesystem;
+using boost::system::error_code;
+using boost::system::system_category;
+using boost::system::system_error;
+
+#include <fstream>
+#include <iostream>
+
+using std::cout;
+using std::endl;
+
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <cstring> // for strncmp, etc.
+#include <ctime>
+#include <cstdlib> // for system(), getenv(), etc.
+#ifdef BOOST_POSIX_API
+#include <unistd.h>
+#endif
+
+#ifdef BOOST_WINDOWS_API
+#include <windows.h>
+
+inline std::wstring convert(const char* c)
+{
+ std::string s(c);
+
+ return std::wstring(s.begin(), s.end());
+}
+
+// Note: these three setenv* functions are not general solutions for the missing
+// setenv* problem on VC++. See Microsoft's _putenv for that need, and ticker #7018
+// for discussion and rationale for returning void for this test program, which needs
+// to work for both the MSVC Runtime and the Windows Runtime (which does not support
+// _putenv).
+
+inline void setenv_(const char* name, const fs::path::value_type* val, int)
+{
+ SetEnvironmentVariableW(convert(name).c_str(), val);
+}
+
+inline void setenv_(const char* name, const char* val, int)
+{
+ SetEnvironmentVariableW(convert(name).c_str(), convert(val).c_str());
+}
+
+inline void unsetenv_(const char* name)
+{
+ SetEnvironmentVariableW(convert(name).c_str(), 0);
+}
+
+//! Sets read-only attribute on a file
+inline void set_read_only(fs::path const& p)
+{
+ DWORD attrs = GetFileAttributesW(p.c_str());
+ if (attrs == INVALID_FILE_ATTRIBUTES)
+ {
+ DWORD err = GetLastError();
+ throw fs::filesystem_error("operations_test set_read_only: failed to get file attributes", p, error_code(err, system_category()));
+ }
+
+ attrs |= FILE_ATTRIBUTE_READONLY;
+ if (!SetFileAttributesW(p.c_str(), attrs))
+ {
+ DWORD err = GetLastError();
+ throw fs::filesystem_error("operations_test set_read_only: failed to set file attributes", p, error_code(err, system_category()));
+ }
+}
+
+#else
+
+#include <unistd.h> // sleep
+#include <stdlib.h> // allow unqualifed calls to env funcs on SunOS
+
+inline void setenv_(const char* name, const char* val, int ovw)
+{
+ setenv(name, val, ovw);
+}
+
+inline void unsetenv_(const char* name)
+{
+ unsetenv(name);
+}
+
+#endif
+
+#define CHECK_EXCEPTION(Functor, Expect) throws_fs_error(Functor, Expect, __LINE__)
+
+namespace {
+typedef int errno_t;
+std::string platform(BOOST_PLATFORM);
+bool report_throws = false;
+bool cleanup = true;
+bool skip_long_windows_tests = false;
+
+fs::directory_iterator end_itr;
+fs::path dir;
+fs::path d1;
+fs::path d2;
+fs::path f0;
+fs::path f1;
+fs::path d1f1;
+
+bool create_symlink_ok(true);
+
+fs::path ng(" no-way, Jose");
+
+const fs::path temp_dir(fs::unique_path("op-test-%%%%-%%%%"));
+
+void create_file(const fs::path& ph, const std::string& contents = std::string())
+{
+ std::ofstream f(BOOST_FILESYSTEM_C_STR(ph));
+ if (!f)
+ throw fs::filesystem_error("operations_test create_file", ph, error_code(errno, system_category()));
+ if (!contents.empty())
+ f << contents;
+}
+
+void verify_file(const fs::path& ph, const std::string& expected)
+{
+ std::ifstream f(BOOST_FILESYSTEM_C_STR(ph));
+ if (!f)
+ throw fs::filesystem_error("operations_test verify_file", ph, error_code(errno, system_category()));
+ std::string contents;
+ f >> contents;
+ if (contents != expected)
+ throw fs::filesystem_error("operations_test verify_file contents \"" + contents + "\" != \"" + expected + "\"", ph, error_code());
+}
+
+template< typename F >
+bool throws_fs_error(F func, errno_t en, int line)
+{
+ try
+ {
+ func();
+ }
+ catch (const fs::filesystem_error& ex)
+ {
+ if (report_throws)
+ {
+ // use the what() convenience function to display exceptions
+ cout << "\n"
+ << ex.what() << "\n";
+ }
+ if (en == 0 || en == ex.code().default_error_condition().value())
+ return true;
+ cout
+ << "\nWarning: line " << line
+ << " exception reports default_error_condition().value() "
+ << ex.code().default_error_condition().value()
+ << ", should be " << en
+ << "\n value() is " << ex.code().value()
+ << endl;
+ return true;
+ }
+ return false;
+}
+
+struct poison_category_impl : public boost::system::error_category
+{
+ char const* name() const BOOST_NOEXCEPT { return "poison"; }
+ std::string message(int) const { return "poison_category::message"; }
+};
+
+boost::system::error_category& poison_category()
+{
+ static poison_category_impl instance;
+ return instance;
+}
+
+// compile-only two argument "do-the-right-thing" tests
+// verifies that all overload combinations compile without error
+void do_the_right_thing_tests(bool call_ = false)
+{
+ if (call_)
+ {
+ fs::path p;
+ std::string s;
+ const char* a = 0;
+ fs::copy_file(p, p);
+ fs::copy_file(s, p);
+ fs::copy_file(a, p);
+ fs::copy_file(p, s);
+ fs::copy_file(p, a);
+ fs::copy_file(s, s);
+ fs::copy_file(a, s);
+ fs::copy_file(s, a);
+ fs::copy_file(a, a);
+ }
+}
+
+void bad_file_size()
+{
+ fs::file_size(" No way, Jose");
+}
+
+void bad_directory_size()
+{
+ fs::file_size(fs::current_path());
+}
+
+fs::path bad_create_directory_path;
+void bad_create_directory()
+{
+ fs::create_directory(bad_create_directory_path);
+}
+
+void bad_equivalent()
+{
+ fs::equivalent("no-such-path", "another-not-present-path");
+}
+
+fs::path bad_remove_dir;
+void bad_remove()
+{
+ fs::remove(bad_remove_dir);
+}
+
+void bad_space()
+{
+ fs::space("no-such-path");
+}
+
+class renamer
+{
+public:
+ renamer(const fs::path& p1, const fs::path& p2) :
+ from(p1), to(p2) {}
+ void operator()()
+ {
+ fs::rename(from, to);
+ }
+
+private:
+ fs::path from;
+ fs::path to;
+};
+
+//------------------------------ debugging aids --------------------------------------//
+
+//std::ostream& operator<<(std::ostream& os, const fs::file_status& s)
+//{
+// if (s.type() == fs::status_error) { os << "status_error"; }
+// else if (s.type() == fs::file_not_found) { os << "file_not_found"; }
+// else if (s.type() == fs::regular_file) { os << "regular_file"; }
+// else if (s.type() == fs::directory_file) { os << "directory_file"; }
+// else if (s.type() == fs::symlink_file) { os << "symlink_file"; }
+// else if (s.type() == fs::block_file) { os << "block_file"; }
+// else if (s.type() == fs::character_file) { os << "character_file"; }
+// else if (s.type() == fs::fifo_file) { os << "fifo_file"; }
+// else if (s.type() == fs::socket_file) { os << "socket_file"; }
+// else if (s.type() == fs::reparse_file) { os << "reparse_file"; }
+// else { os << "type_unknown"; }
+// return os;
+//}
+
+//void dump_tree(const fs::path & root)
+//{
+// cout << "dumping tree rooted at " << root << endl;
+// for (fs::recursive_directory_iterator it (root, fs::directory_options::follow_directory_symlink);
+// it != fs::recursive_directory_iterator();
+// ++it)
+// {
+// for (int i = 0; i <= it.level(); ++i)
+// cout << " ";
+
+// cout << it->path();
+// if (fs::is_symlink(it->path()))
+// {
+// cout << " [symlink]" << endl;
+// }
+// else
+// cout << endl;
+// }
+//}
+
+// exception_tests() ---------------------------------------------------------------//
+
+#if defined(BOOST_GCC) && BOOST_GCC >= 80000
+#pragma GCC diagnostic push
+// catching polymorphic type "X" by value - that's the intention of the test
+#pragma GCC diagnostic ignored "-Wcatch-value"
+#endif
+
+void exception_tests()
+{
+ cout << "exception_tests..." << endl;
+ bool exception_thrown;
+
+ // catch runtime_error by value
+
+ cout << " catch runtime_error by value" << endl;
+ exception_thrown = false;
+ try
+ {
+ fs::create_directory("no-such-dir/foo/bar");
+ }
+ catch (std::runtime_error x)
+ {
+ exception_thrown = true;
+ cout << " x.what() returns \"" << x.what() << "\"" << endl;
+ }
+ BOOST_TEST(exception_thrown);
+
+ // catch system_error by value
+
+ cout << " catch system_error by value" << endl;
+ exception_thrown = false;
+ try
+ {
+ fs::create_directory("no-such-dir/foo/bar");
+ }
+ catch (system_error x)
+ {
+ exception_thrown = true;
+ cout << " x.what() returns \"" << x.what() << "\"" << endl;
+ }
+ BOOST_TEST(exception_thrown);
+
+ // catch filesystem_error by value
+
+ cout << " catch filesystem_error by value" << endl;
+ exception_thrown = false;
+ try
+ {
+ fs::create_directory("no-such-dir/foo/bar");
+ }
+ catch (fs::filesystem_error x)
+ {
+ exception_thrown = true;
+ cout << " x.what() returns \"" << x.what() << "\"" << endl;
+ }
+ BOOST_TEST(exception_thrown);
+
+ // catch filesystem_error by const reference
+
+ cout << " catch filesystem_error by const reference" << endl;
+ exception_thrown = false;
+ try
+ {
+ fs::create_directory("no-such-dir/foo/bar");
+ }
+ catch (const fs::filesystem_error& x)
+ {
+ exception_thrown = true;
+ cout << " x.what() returns \"" << x.what() << "\"" << endl;
+ }
+ BOOST_TEST(exception_thrown);
+
+ // the bound functions should throw, so CHECK_EXCEPTION() should return true
+
+ BOOST_TEST(CHECK_EXCEPTION(bad_file_size, ENOENT));
+
+ if (platform == "Windows")
+ BOOST_TEST(CHECK_EXCEPTION(bad_directory_size, ENOENT));
+ else
+ BOOST_TEST(CHECK_EXCEPTION(bad_directory_size, 0));
+
+ // test path::exception members
+ try
+ {
+ fs::file_size(ng); // will throw
+ }
+ catch (fs::filesystem_error& ex)
+ {
+ BOOST_TEST(ex.path1().string() == " no-way, Jose");
+ }
+
+ cout << " exception_tests complete" << endl;
+}
+
+#if defined(BOOST_GCC) && BOOST_GCC >= 80000
+#pragma GCC diagnostic pop
+#endif
+
+// create a directory tree that can be used by subsequent tests ---------------------//
+//
+// dir
+// d1
+// d1f1 // an empty file
+// f0 // an empty file
+// f1 // a file containing "file-f1"
+
+void create_tree()
+{
+ cout << "creating test directories and files in " << dir << endl;
+
+ // create directory d1
+ BOOST_TEST(!fs::create_directory(dir));
+ BOOST_TEST(!fs::is_symlink(dir));
+ BOOST_TEST(!fs::is_symlink("nosuchfileordirectory"));
+ d1 = dir / "d1";
+ BOOST_TEST(fs::create_directory(d1));
+ BOOST_TEST(fs::exists(d1));
+ BOOST_TEST(fs::is_directory(d1));
+ BOOST_TEST(fs::is_empty(d1));
+
+ // create an empty file named "d1f1"
+ d1f1 = d1 / "d1f1";
+ create_file(d1f1, "");
+ BOOST_TEST(fs::exists(d1f1));
+ BOOST_TEST(!fs::is_directory(d1f1));
+ BOOST_TEST(fs::is_regular_file(d1f1));
+ BOOST_TEST(fs::is_empty(d1f1));
+ BOOST_TEST(fs::file_size(d1f1) == 0);
+ BOOST_TEST(fs::hard_link_count(d1f1) == 1);
+
+ // create an empty file named "f0"
+ f0 = dir / "f0";
+ create_file(f0, "");
+ BOOST_TEST(fs::exists(f0));
+ BOOST_TEST(!fs::is_directory(f0));
+ BOOST_TEST(fs::is_regular_file(f0));
+ BOOST_TEST(fs::is_empty(f0));
+ BOOST_TEST(fs::file_size(f0) == 0);
+ BOOST_TEST(fs::hard_link_count(f0) == 1);
+
+ // create a file named "f1"
+ f1 = dir / "f1";
+ create_file(f1, "file-f1");
+ BOOST_TEST(fs::exists(f1));
+ BOOST_TEST(!fs::is_directory(f1));
+ BOOST_TEST(fs::is_regular_file(f1));
+ BOOST_TEST(fs::file_size(f1) == 7);
+ verify_file(f1, "file-f1");
+}
+
+// directory_iterator_tests --------------------------------------------------------//
+
+void directory_iterator_tests()
+{
+ cout << "directory_iterator_tests..." << endl;
+
+ bool dir_itr_exception(false);
+ try
+ {
+ fs::directory_iterator it("");
+ }
+ catch (const fs::filesystem_error&)
+ {
+ dir_itr_exception = true;
+ }
+ BOOST_TEST(dir_itr_exception);
+
+ error_code ec;
+
+ BOOST_TEST(!ec);
+ fs::directory_iterator it("", ec);
+ BOOST_TEST(ec);
+
+ dir_itr_exception = false;
+ try
+ {
+ fs::directory_iterator itx("nosuchdirectory");
+ }
+ catch (const fs::filesystem_error&)
+ {
+ dir_itr_exception = true;
+ }
+ BOOST_TEST(dir_itr_exception);
+
+ ec.clear();
+ fs::directory_iterator it2x("nosuchdirectory", ec);
+ BOOST_TEST(ec);
+
+ dir_itr_exception = false;
+ try
+ {
+ error_code ecx;
+ fs::directory_iterator itx("nosuchdirectory", ecx);
+ BOOST_TEST(ecx);
+ BOOST_TEST(ecx == boost::system::errc::no_such_file_or_directory);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ dir_itr_exception = true;
+ }
+ BOOST_TEST(!dir_itr_exception);
+
+ // create a second directory named d2
+ d2 = dir / "d2";
+ fs::create_directory(d2);
+ BOOST_TEST(fs::exists(d2));
+ BOOST_TEST(fs::is_directory(d2));
+
+ // test the basic operation of directory_iterators, and test that
+ // stepping one iterator doesn't affect a different iterator.
+ {
+ typedef std::vector< fs::directory_entry > vec_type;
+ vec_type vec;
+
+ fs::directory_iterator it1(dir);
+ BOOST_TEST(it1 != fs::directory_iterator());
+ BOOST_TEST(fs::exists(it1->status()));
+ vec.push_back(*it1);
+ BOOST_TEST(*it1 == vec[0]);
+
+ fs::directory_iterator it2(dir);
+ BOOST_TEST(it2 != fs::directory_iterator());
+ BOOST_TEST(*it1 == *it2);
+
+ ++it1;
+ BOOST_TEST(it1 != fs::directory_iterator());
+ BOOST_TEST(fs::exists(it1->status()));
+ BOOST_TEST(it1 != it2);
+ BOOST_TEST(*it1 != vec[0]);
+ BOOST_TEST(*it2 == vec[0]);
+ vec.push_back(*it1);
+
+ ++it1;
+ BOOST_TEST(it1 != fs::directory_iterator());
+ BOOST_TEST(fs::exists(it1->status()));
+ BOOST_TEST(it1 != it2);
+ BOOST_TEST(*it2 == vec[0]);
+ vec.push_back(*it1);
+
+ ++it1;
+ BOOST_TEST(it1 != fs::directory_iterator());
+ BOOST_TEST(fs::exists(it1->status()));
+ BOOST_TEST(it1 != it2);
+ BOOST_TEST(*it2 == vec[0]);
+ vec.push_back(*it1);
+
+ ++it1;
+ BOOST_TEST(it1 == fs::directory_iterator());
+
+ BOOST_TEST(*it2 == vec[0]);
+ ec.clear();
+ it2.increment(ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(it2 != fs::directory_iterator());
+ BOOST_TEST(it1 == fs::directory_iterator());
+ BOOST_TEST(*it2 == vec[1]);
+ ++it2;
+ BOOST_TEST(*it2 == vec[2]);
+ BOOST_TEST(it1 == fs::directory_iterator());
+ ++it2;
+ BOOST_TEST(*it2 == vec[3]);
+ ++it2;
+ BOOST_TEST(it1 == fs::directory_iterator());
+ BOOST_TEST(it2 == fs::directory_iterator());
+
+ // sort vec and check that the right directory entries were found
+ std::sort(vec.begin(), vec.end());
+
+ BOOST_TEST_EQ(vec[0].path().filename().string(), std::string("d1"));
+ BOOST_TEST_EQ(vec[1].path().filename().string(), std::string("d2"));
+ BOOST_TEST_EQ(vec[2].path().filename().string(), std::string("f0"));
+ BOOST_TEST_EQ(vec[3].path().filename().string(), std::string("f1"));
+ }
+
+ { // *i++ must meet the standard's InputIterator requirements
+ fs::directory_iterator dir_itr(dir);
+ BOOST_TEST(dir_itr != fs::directory_iterator());
+ fs::path p = dir_itr->path();
+ BOOST_TEST((*dir_itr++).path() == p);
+ BOOST_TEST(dir_itr != fs::directory_iterator());
+ BOOST_TEST(dir_itr->path() != p);
+
+ // test case reported in comment to SourceForge bug tracker [937606]
+ // augmented to test single pass semantics of a copied iterator [#12578]
+ fs::directory_iterator itx(dir);
+ fs::directory_iterator itx2(itx);
+ BOOST_TEST(itx == itx2);
+ const fs::path p1 = (*itx++).path();
+ BOOST_TEST(itx == itx2);
+ BOOST_TEST(itx != fs::directory_iterator());
+ const fs::path p2 = (*itx++).path();
+ BOOST_TEST(itx == itx2);
+ BOOST_TEST(p1 != p2);
+ ++itx;
+ BOOST_TEST(itx == itx2);
+ ++itx;
+ BOOST_TEST(itx == itx2);
+ BOOST_TEST(itx == fs::directory_iterator());
+ BOOST_TEST(itx2 == fs::directory_iterator());
+ }
+
+ // Windows has a tricky special case when just the root-name is given,
+ // causing the rest of the path to default to the current directory.
+ // Reported as S/F bug [ 1259176 ]
+ if (platform == "Windows")
+ {
+ fs::path root_name_path(fs::current_path().root_name());
+ fs::directory_iterator itx(root_name_path);
+ BOOST_TEST(itx != fs::directory_iterator());
+ // BOOST_TEST(fs::exists((*itx).path()));
+ BOOST_TEST(fs::exists(itx->path()));
+ BOOST_TEST(itx->path().parent_path() == root_name_path);
+ bool found(false);
+ do
+ {
+ if (itx->path().filename() == temp_dir.filename())
+ found = true;
+ } while (++itx != fs::directory_iterator());
+ BOOST_TEST(found);
+ }
+
+ // there was an inital bug in directory_iterator that caused premature
+ // close of an OS handle. This block will detect regression.
+ {
+ fs::directory_iterator di;
+ {
+ di = fs::directory_iterator(dir);
+ }
+ BOOST_TEST(++di != fs::directory_iterator());
+ }
+
+ cout << " directory_iterator_tests complete" << endl;
+}
+
+// recursive_directory_iterator_tests ----------------------------------------------//
+
+int walk_tree(bool recursive)
+{
+ //cout << " walk_tree" << endl;
+ error_code ec;
+ int d1f1_count = 0;
+ for (fs::recursive_directory_iterator it(dir, recursive ? (fs::directory_options::follow_directory_symlink | fs::directory_options::skip_dangling_symlinks) : fs::directory_options::none);
+ it != fs::recursive_directory_iterator();
+ it.increment(ec))
+ {
+ //cout << " " << it->path() << " : " << ec << endl;
+ if (it->path().filename() == "d1f1")
+ ++d1f1_count;
+ }
+ //cout << " last error : " << ec << endl;
+ return d1f1_count;
+}
+
+void recursive_directory_iterator_tests()
+{
+ cout << "recursive_directory_iterator_tests..." << endl;
+ BOOST_TEST_EQ(walk_tree(false), 1);
+ if (create_symlink_ok)
+ BOOST_TEST(walk_tree(true) > 1);
+
+ // test iterator increment with error_code argument
+ cout << " with error_code argument" << endl;
+ boost::system::error_code ec;
+ int d1f1_count = 0;
+ fs::recursive_directory_iterator it(dir, fs::directory_options::none);
+ fs::recursive_directory_iterator it2(it); // test single pass shallow copy semantics
+ for (;
+ it != fs::recursive_directory_iterator();
+ it.increment(ec))
+ {
+ if (it->path().filename() == "d1f1")
+ ++d1f1_count;
+ BOOST_TEST(it == it2); // verify single pass shallow copy semantics
+ }
+ BOOST_TEST(!ec);
+ BOOST_TEST_EQ(d1f1_count, 1);
+ BOOST_TEST(it == it2); // verify single pass shallow copy semantics
+
+ cout << " recursive_directory_iterator_tests complete" << endl;
+}
+
+// iterator_status_tests -----------------------------------------------------------//
+
+void iterator_status_tests()
+{
+ cout << "iterator_status_tests..." << endl;
+
+ error_code ec;
+ // harmless if these fail:
+ fs::create_symlink(dir / "f0", dir / "f0_symlink", ec);
+ fs::create_symlink(dir / "no such file", dir / "dangling_symlink", ec);
+ fs::create_directory_symlink(dir / "d1", dir / "d1_symlink", ec);
+ fs::create_directory_symlink(dir / "no such directory", dir / "dangling_directory_symlink", ec);
+
+ for (fs::directory_iterator it(dir);
+ it != fs::directory_iterator(); ++it)
+ {
+ BOOST_TEST(fs::status(it->path()).type() == it->status().type());
+ BOOST_TEST(fs::symlink_status(it->path()).type() == it->symlink_status().type());
+ if (it->path().filename() == "d1")
+ {
+ BOOST_TEST(fs::is_directory(it->status()));
+ BOOST_TEST(fs::is_directory(it->symlink_status()));
+ }
+ else if (it->path().filename() == "d2")
+ {
+ BOOST_TEST(fs::is_directory(it->status()));
+ BOOST_TEST(fs::is_directory(it->symlink_status()));
+ }
+ else if (it->path().filename() == "f0")
+ {
+ BOOST_TEST(fs::is_regular_file(it->status()));
+ BOOST_TEST(fs::is_regular_file(it->symlink_status()));
+ }
+ else if (it->path().filename() == "f1")
+ {
+ BOOST_TEST(fs::is_regular_file(it->status()));
+ BOOST_TEST(fs::is_regular_file(it->symlink_status()));
+ }
+ else if (it->path().filename() == "f0_symlink")
+ {
+ BOOST_TEST(fs::is_regular_file(it->status()));
+ BOOST_TEST(fs::is_symlink(it->symlink_status()));
+ BOOST_TEST(fs::is_symlink(*it));
+ }
+ else if (it->path().filename() == "dangling_symlink")
+ {
+ BOOST_TEST(it->status().type() == fs::file_not_found);
+ BOOST_TEST(fs::is_symlink(it->symlink_status()));
+ }
+ else if (it->path().filename() == "d1_symlink")
+ {
+ BOOST_TEST(fs::is_directory(it->status()));
+ BOOST_TEST(fs::is_symlink(it->symlink_status()));
+ }
+ else if (it->path().filename() == "dangling_directory_symlink")
+ {
+ BOOST_TEST(it->status().type() == fs::file_not_found);
+ BOOST_TEST(fs::is_symlink(it->symlink_status()));
+ }
+ //else
+ // cout << " Note: unexpected directory entry " << it->path().filename() << endl;
+ }
+}
+
+// recursive_iterator_status_tests -------------------------------------------------//
+
+void recursive_iterator_status_tests()
+{
+ cout << "recursive_iterator_status_tests..." << endl;
+ for (fs::recursive_directory_iterator it(dir);
+ it != fs::recursive_directory_iterator();
+ ++it)
+ {
+ BOOST_TEST(fs::status(it->path()).type() == it->status().type());
+ BOOST_TEST(fs::symlink_status(it->path()).type() == it->symlink_status().type());
+ }
+}
+
+// create_hard_link_tests ----------------------------------------------------------//
+
+void create_hard_link_tests()
+{
+ cout << "create_hard_link_tests..." << endl;
+
+ fs::path from_ph(dir / "f3");
+ fs::path f1x(dir / "f1");
+
+ BOOST_TEST(!fs::exists(from_ph));
+ BOOST_TEST(fs::exists(f1x));
+ bool create_hard_link_ok(true);
+ try
+ {
+ fs::create_hard_link(f1x, from_ph);
+ }
+ catch (const fs::filesystem_error& ex)
+ {
+ create_hard_link_ok = false;
+ cout
+ << " *** For information only ***\n"
+ " create_hard_link() attempt failed\n"
+ " filesystem_error.what() reports: "
+ << ex.what() << "\n"
+ " create_hard_link() may not be supported on this file system\n";
+ }
+
+ if (create_hard_link_ok)
+ {
+ cout
+ << " *** For information only ***\n"
+ " create_hard_link() succeeded\n";
+ BOOST_TEST(fs::exists(from_ph));
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(fs::equivalent(from_ph, f1x));
+ BOOST_TEST(fs::hard_link_count(from_ph) == 2);
+ BOOST_TEST(fs::hard_link_count(f1x) == 2);
+ }
+
+ // Although tests may be running on a FAT or other file system that does
+ // not support hard links, that is unusual enough that it is considered
+ // a test failure.
+ BOOST_TEST(create_hard_link_ok);
+
+ error_code ec;
+ fs::create_hard_link(fs::path("doesnotexist"), fs::path("shouldnotwork"), ec);
+ BOOST_TEST(ec);
+}
+
+// create_symlink_tests ------------------------------------------------------------//
+
+void create_symlink_tests()
+{
+ cout << "create_symlink_tests..." << endl;
+
+ fs::path from_ph(dir / "f4");
+ fs::path f1x(dir / "f1");
+ BOOST_TEST(!fs::exists(from_ph));
+ BOOST_TEST(fs::exists(f1x));
+ try
+ {
+ fs::create_symlink(f1x, from_ph);
+ }
+ catch (const fs::filesystem_error& ex)
+ {
+ create_symlink_ok = false;
+ cout
+ << " *** For information only ***\n"
+ " create_symlink() attempt failed\n"
+ " filesystem_error.what() reports: "
+ << ex.what() << "\n"
+ " create_symlink() may not be supported on this operating system or file system\n";
+ }
+
+ if (create_symlink_ok)
+ {
+ cout
+ << " *** For information only ***\n"
+ " create_symlink() succeeded\n";
+ BOOST_TEST(fs::exists(from_ph));
+ BOOST_TEST(fs::is_symlink(from_ph));
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(fs::equivalent(from_ph, f1x));
+ BOOST_TEST(fs::read_symlink(from_ph) == f1x);
+
+ fs::file_status stat = fs::symlink_status(from_ph);
+ BOOST_TEST(fs::exists(stat));
+ BOOST_TEST(!fs::is_directory(stat));
+ BOOST_TEST(!fs::is_regular_file(stat));
+ BOOST_TEST(!fs::is_other(stat));
+ BOOST_TEST(fs::is_symlink(stat));
+
+ stat = fs::status(from_ph);
+ BOOST_TEST(fs::exists(stat));
+ BOOST_TEST(!fs::is_directory(stat));
+ BOOST_TEST(fs::is_regular_file(stat));
+ BOOST_TEST(!fs::is_other(stat));
+ BOOST_TEST(!fs::is_symlink(stat));
+
+ // since create_symlink worked, copy_symlink should also work
+ fs::path symlink2_ph(dir / "symlink2");
+ fs::copy_symlink(from_ph, symlink2_ph);
+ stat = fs::symlink_status(symlink2_ph);
+ BOOST_TEST(fs::is_symlink(stat));
+ BOOST_TEST(fs::exists(stat));
+ BOOST_TEST(!fs::is_directory(stat));
+ BOOST_TEST(!fs::is_regular_file(stat));
+ BOOST_TEST(!fs::is_other(stat));
+ }
+
+ error_code ec = error_code();
+ fs::create_symlink("doesnotexist", "", ec);
+ BOOST_TEST(ec);
+}
+
+// permissions_tests ---------------------------------------------------------------//
+
+void permissions_tests()
+{
+ cout << "permissions_tests..." << endl;
+
+ fs::path p(dir / "permissions.txt");
+ create_file(p);
+
+ if (platform == "POSIX")
+ {
+ cout << " fs::status(p).permissions() " << std::oct << fs::status(p).permissions()
+ << std::dec << endl;
+ BOOST_TEST((fs::status(p).permissions() & 0600) == 0600); // 0644, 0664 sometimes returned
+
+ fs::permissions(p, fs::owner_all);
+ BOOST_TEST(fs::status(p).permissions() == fs::owner_all);
+
+ fs::permissions(p, fs::add_perms | fs::group_all);
+ BOOST_TEST(fs::status(p).permissions() == (fs::owner_all | fs::group_all));
+
+ fs::permissions(p, fs::remove_perms | fs::group_all);
+ BOOST_TEST(fs::status(p).permissions() == fs::owner_all);
+
+ // some POSIX platforms cache permissions during directory iteration, some don't
+ // so test that iteration finds the correct permissions
+ for (fs::directory_iterator itr(dir); itr != fs::directory_iterator(); ++itr)
+ if (itr->path().filename() == fs::path("permissions.txt"))
+ BOOST_TEST(itr->status().permissions() == fs::owner_all);
+
+ if (create_symlink_ok) // only if symlinks supported
+ {
+ BOOST_TEST(fs::status(p).permissions() == fs::owner_all);
+ fs::path p2(dir / "permissions-symlink.txt");
+ fs::create_symlink(p, p2);
+ cout << std::oct;
+ cout << " status(p).permissions() " << fs::status(p).permissions() << endl;
+ cout << " status(p2).permissions() " << fs::status(p).permissions() << endl;
+ fs::permissions(p2, fs::add_perms | fs::others_read);
+ cout << " status(p).permissions(): " << fs::status(p).permissions() << endl;
+ cout << " status(p2).permissions(): " << fs::status(p2).permissions() << endl;
+ cout << std::dec;
+ }
+ }
+ else // Windows
+ {
+ BOOST_TEST(fs::status(p).permissions() == 0666);
+ fs::permissions(p, fs::remove_perms | fs::group_write);
+ BOOST_TEST(fs::status(p).permissions() == 0444);
+ fs::permissions(p, fs::add_perms | fs::group_write);
+ BOOST_TEST(fs::status(p).permissions() == 0666);
+ }
+}
+
+// rename_tests --------------------------------------------------------------------//
+
+void rename_tests()
+{
+ cout << "rename_tests..." << endl;
+
+ fs::path f1x(dir / "f1");
+ BOOST_TEST(fs::exists(f1x));
+
+ // error: rename a non-existent old file
+ BOOST_TEST(!fs::exists(d1 / "f99"));
+ BOOST_TEST(!fs::exists(d1 / "f98"));
+ renamer n1a(d1 / "f99", d1 / "f98");
+ BOOST_TEST(CHECK_EXCEPTION(n1a, ENOENT));
+ renamer n1b(fs::path(""), d1 / "f98");
+ BOOST_TEST(CHECK_EXCEPTION(n1b, ENOENT));
+
+ // error: rename an existing file to ""
+ renamer n2(f1x, "");
+ BOOST_TEST(CHECK_EXCEPTION(n2, ENOENT));
+
+ // rename an existing file to an existent file
+ create_file(dir / "ff1", "ff1");
+ create_file(dir / "ff2", "ff2");
+ fs::rename(dir / "ff2", dir / "ff1");
+ BOOST_TEST(fs::exists(dir / "ff1"));
+ verify_file(dir / "ff1", "ff2");
+ BOOST_TEST(!fs::exists(dir / "ff2"));
+
+ // rename an existing file to itself
+ BOOST_TEST(fs::exists(dir / "f1"));
+ fs::rename(dir / "f1", dir / "f1");
+ BOOST_TEST(fs::exists(dir / "f1"));
+
+ // error: rename an existing directory to an existing non-empty directory
+ BOOST_TEST(fs::exists(dir / "f1"));
+ BOOST_TEST(fs::exists(d1 / "f2"));
+ // several POSIX implementations (cygwin, openBSD) report ENOENT instead of EEXIST,
+ // so we don't verify error type on the following test.
+ renamer n3b(dir, d1);
+ BOOST_TEST(CHECK_EXCEPTION(n3b, 0));
+
+ // error: move existing file to a nonexistent parent directory
+ BOOST_TEST(!fs::is_directory(dir / "f1"));
+ BOOST_TEST(!fs::exists(dir / "d3/f3"));
+ renamer n4a(dir / "f1", dir / "d3/f3");
+ BOOST_TEST(CHECK_EXCEPTION(n4a, ENOENT));
+
+ // rename existing file in same directory
+ BOOST_TEST(fs::exists(d1 / "f2"));
+ BOOST_TEST(!fs::exists(d1 / "f50"));
+ fs::rename(d1 / "f2", d1 / "f50");
+ BOOST_TEST(!fs::exists(d1 / "f2"));
+ BOOST_TEST(fs::exists(d1 / "f50"));
+ fs::rename(d1 / "f50", d1 / "f2");
+ BOOST_TEST(fs::exists(d1 / "f2"));
+ BOOST_TEST(!fs::exists(d1 / "f50"));
+
+ // move and rename an existing file to a different directory
+ fs::rename(d1 / "f2", d2 / "f3");
+ BOOST_TEST(!fs::exists(d1 / "f2"));
+ BOOST_TEST(!fs::exists(d2 / "f2"));
+ BOOST_TEST(fs::exists(d2 / "f3"));
+ BOOST_TEST(!fs::is_directory(d2 / "f3"));
+ verify_file(d2 / "f3", "file-f1");
+ fs::rename(d2 / "f3", d1 / "f2");
+ BOOST_TEST(fs::exists(d1 / "f2"));
+
+ // error: move existing directory to nonexistent parent directory
+ BOOST_TEST(fs::exists(d1));
+ BOOST_TEST(!fs::exists(dir / "d3/d5"));
+ BOOST_TEST(!fs::exists(dir / "d3"));
+ renamer n5a(d1, dir / "d3/d5");
+ BOOST_TEST(CHECK_EXCEPTION(n5a, ENOENT));
+
+ // rename existing directory
+ fs::path d3(dir / "d3");
+ BOOST_TEST(fs::exists(d1));
+ BOOST_TEST(fs::exists(d1 / "f2"));
+ BOOST_TEST(!fs::exists(d3));
+ fs::rename(d1, d3);
+ BOOST_TEST(!fs::exists(d1));
+ BOOST_TEST(fs::exists(d3));
+ BOOST_TEST(fs::is_directory(d3));
+ BOOST_TEST(!fs::exists(d1 / "f2"));
+ BOOST_TEST(fs::exists(d3 / "f2"));
+ fs::rename(d3, d1);
+ BOOST_TEST(fs::exists(d1));
+ BOOST_TEST(fs::exists(d1 / "f2"));
+ BOOST_TEST(!fs::exists(d3));
+
+ // rename and move d1 to d2 / "d20"
+ BOOST_TEST(fs::exists(d1));
+ BOOST_TEST(!fs::exists(d2 / "d20"));
+ BOOST_TEST(fs::exists(d1 / "f2"));
+ fs::rename(d1, d2 / "d20");
+ BOOST_TEST(!fs::exists(d1));
+ BOOST_TEST(fs::exists(d2 / "d20"));
+ BOOST_TEST(fs::exists(d2 / "d20" / "f2"));
+ fs::rename(d2 / "d20", d1);
+ BOOST_TEST(fs::exists(d1));
+ BOOST_TEST(!fs::exists(d2 / "d20"));
+ BOOST_TEST(fs::exists(d1 / "f2"));
+}
+
+// predicate_and_status_tests ------------------------------------------------------//
+
+void predicate_and_status_tests()
+{
+ cout << "predicate_and_status_tests..." << endl;
+
+ BOOST_TEST(!fs::exists(ng));
+ BOOST_TEST(!fs::is_directory(ng));
+ BOOST_TEST(!fs::is_regular_file(ng));
+ BOOST_TEST(!fs::is_symlink(ng));
+ fs::file_status stat(fs::status(ng));
+ BOOST_TEST(fs::type_present(stat));
+ BOOST_TEST(fs::permissions_present(stat));
+ BOOST_TEST(fs::status_known(stat));
+ BOOST_TEST(!fs::exists(stat));
+ BOOST_TEST(!fs::is_directory(stat));
+ BOOST_TEST(!fs::is_regular_file(stat));
+ BOOST_TEST(!fs::is_other(stat));
+ BOOST_TEST(!fs::is_symlink(stat));
+ stat = fs::status("");
+ BOOST_TEST(fs::type_present(stat));
+ BOOST_TEST(fs::permissions_present(stat));
+ BOOST_TEST(fs::status_known(stat));
+ BOOST_TEST(!fs::exists(stat));
+ BOOST_TEST(!fs::is_directory(stat));
+ BOOST_TEST(!fs::is_regular_file(stat));
+ BOOST_TEST(!fs::is_other(stat));
+ BOOST_TEST(!fs::is_symlink(stat));
+}
+
+// create_directory_tests ----------------------------------------------------------//
+
+void create_directory_tests()
+{
+ cout << "create_directory_tests..." << endl;
+
+ error_code ec;
+ BOOST_TEST(!fs::create_directory("", ec));
+ BOOST_TEST(ec);
+
+#ifdef BOOST_WINDOWS_API
+ ec.clear();
+ BOOST_TEST(!fs::create_directory(" ", ec)); // OK on Linux
+ BOOST_TEST(ec);
+#endif
+
+ ec.clear();
+ BOOST_TEST(!fs::create_directory("/", ec));
+ BOOST_TEST(!ec);
+ BOOST_TEST(fs::is_directory("/")); // this is a post-condition
+
+ ec.clear();
+ BOOST_TEST(!fs::create_directory(".", ec));
+ BOOST_TEST(!ec);
+
+ ec.clear();
+ BOOST_TEST(!fs::create_directory("..", ec));
+ BOOST_TEST(!ec);
+
+ // create a directory, then check it for consistency
+ // take extra care to report problems, since if this fails
+ // many subsequent tests will fail
+ try
+ {
+ fs::create_directory(dir);
+ }
+
+ catch (const fs::filesystem_error& x)
+ {
+ cout << x.what() << "\n\n"
+ "***** Creating directory "
+ << dir << " failed. *****\n"
+ "***** This is a serious error that will prevent further tests *****\n"
+ "***** from returning useful results. Further testing is aborted. *****\n\n";
+ std::exit(1);
+ }
+
+ catch (...)
+ {
+ cout << "\n\n"
+ "***** Creating directory "
+ << dir << " failed. *****\n"
+ "***** This is a serious error that will prevent further tests *****\n"
+ "***** from returning useful results. Further testing is aborted. *****\n\n";
+ std::exit(1);
+ }
+
+ BOOST_TEST(fs::exists(dir));
+ BOOST_TEST(fs::is_empty(dir));
+ BOOST_TEST(fs::is_directory(dir));
+ BOOST_TEST(!fs::is_regular_file(dir));
+ BOOST_TEST(!fs::is_other(dir));
+ BOOST_TEST(!fs::is_symlink(dir));
+ fs::file_status stat = fs::status(dir);
+ BOOST_TEST(fs::exists(stat));
+ BOOST_TEST(fs::is_directory(stat));
+ BOOST_TEST(!fs::is_regular_file(stat));
+ BOOST_TEST(!fs::is_other(stat));
+ BOOST_TEST(!fs::is_symlink(stat));
+
+ cout << " create_directory_tests complete" << endl;
+}
+
+// current_directory_tests ---------------------------------------------------------//
+
+void current_directory_tests()
+{
+ cout << "current_directory_tests..." << endl;
+
+ // set the current directory, then check it for consistency
+ fs::path original_dir = fs::current_path();
+ BOOST_TEST(dir != original_dir);
+ fs::current_path(dir);
+ BOOST_TEST(fs::current_path() == dir);
+ BOOST_TEST(fs::current_path() != original_dir);
+ fs::current_path(original_dir);
+ BOOST_TEST(fs::current_path() == original_dir);
+ BOOST_TEST(fs::current_path() != dir);
+
+ // make sure the overloads work
+ fs::current_path(dir.c_str());
+ BOOST_TEST(fs::current_path() == dir);
+ BOOST_TEST(fs::current_path() != original_dir);
+ fs::current_path(original_dir.string());
+ BOOST_TEST(fs::current_path() == original_dir);
+ BOOST_TEST(fs::current_path() != dir);
+}
+
+// create_directories_tests --------------------------------------------------------//
+
+void create_directories_tests()
+{
+ cout << "create_directories_tests..." << endl;
+
+ error_code ec;
+ BOOST_TEST(!fs::create_directories("", ec));
+ BOOST_TEST(ec);
+
+#ifdef BOOST_WINDOWS_API
+ // Windows only test, since " " is OK on Linux as a directory name
+ ec.clear();
+ BOOST_TEST(!fs::create_directories(" ", ec));
+ BOOST_TEST(ec);
+#endif
+
+ ec.clear();
+ BOOST_TEST(!fs::create_directories("/", ec));
+ BOOST_TEST(!ec);
+
+ ec.clear();
+ BOOST_TEST(!fs::create_directories(".", ec));
+ BOOST_TEST(!ec);
+
+ ec.clear();
+ BOOST_TEST(!fs::create_directories("..", ec));
+ BOOST_TEST(!ec);
+
+#ifdef BOOST_POSIX_API
+ if (geteuid() > 0)
+ {
+ ec.clear();
+ BOOST_TEST(!fs::create_directories("/foo", ec)); // may be OK on Windows
+ // but unlikely to be OK on POSIX, unless running as root
+ BOOST_TEST(ec);
+ }
+#endif
+
+ fs::path p = dir / "level1/." / "level2/./.." / "level3/";
+ // trailing "/.", "/./..", and "/" in the above elements test ticket #7258 and
+ // related issues
+
+ cout << " p is " << p << endl;
+ BOOST_TEST(!fs::exists(p));
+ BOOST_TEST(fs::create_directories(p));
+ BOOST_TEST(fs::exists(p));
+ BOOST_TEST(fs::is_directory(p));
+
+ if (fs::exists("/permissions_test"))
+ {
+ BOOST_TEST(!fs::create_directories("/permissions_test", ec));
+ BOOST_TEST(!fs::create_directories("/permissions_test/another_directory", ec));
+ BOOST_TEST(ec);
+ }
+}
+
+// resize_file_tests ---------------------------------------------------------------//
+
+void resize_file_tests()
+{
+ cout << "resize_file_tests..." << endl;
+
+ fs::path p(dir / "resize_file_test.txt");
+
+ fs::remove(p);
+ create_file(p, "1234567890");
+
+ BOOST_TEST(fs::exists(p));
+ BOOST_TEST_EQ(fs::file_size(p), 10U);
+ fs::resize_file(p, 5);
+ BOOST_TEST(fs::exists(p));
+ BOOST_TEST_EQ(fs::file_size(p), 5U);
+ fs::resize_file(p, 15);
+ BOOST_TEST(fs::exists(p));
+ BOOST_TEST_EQ(fs::file_size(p), 15U);
+
+ error_code ec;
+ fs::resize_file("no such file", 15, ec);
+ BOOST_TEST(ec);
+}
+
+// status_of_nonexistent_tests -----------------------------------------------------//
+
+void status_of_nonexistent_tests()
+{
+ cout << "status_of_nonexistent_tests..." << endl;
+ fs::path p("nosuch");
+ BOOST_TEST(!fs::exists(p));
+ BOOST_TEST(!fs::is_regular_file(p));
+ BOOST_TEST(!fs::is_directory(p));
+ BOOST_TEST(!fs::is_symlink(p));
+ BOOST_TEST(!fs::is_other(p));
+
+ fs::file_status s = fs::status(p);
+ BOOST_TEST(!fs::exists(s));
+ BOOST_TEST_EQ(s.type(), fs::file_not_found);
+ BOOST_TEST(fs::type_present(s));
+ BOOST_TEST(!fs::is_regular_file(s));
+ BOOST_TEST(!fs::is_directory(s));
+ BOOST_TEST(!fs::is_symlink(s));
+ BOOST_TEST(!fs::is_other(s));
+
+ // ticket #12574 was just user confusion, but are the tests are worth keeping
+ error_code ec;
+ BOOST_TEST(!fs::is_directory(dir / "no-such-directory", ec));
+ BOOST_TEST(ec);
+ //cout << "error_code value: " << ec.value() << endl;
+ ec.clear();
+ BOOST_TEST(!fs::is_directory(dir / "no-such-directory" / "bar", ec));
+ BOOST_TEST(ec);
+ //cout << "error_code value: " << ec.value() << endl;
+}
+
+// status_error_reporting_tests ----------------------------------------------------//
+
+void status_error_reporting_tests()
+{
+ cout << "status_error_reporting_tests..." << endl;
+
+ error_code ec;
+
+ // test status, ec, for existing file
+ ec.assign(-1, poison_category());
+ BOOST_TEST(ec.value() == -1);
+ BOOST_TEST(&ec.category() == &poison_category());
+ fs::file_status s = fs::status(".", ec);
+ BOOST_TEST(ec.value() == 0);
+ BOOST_TEST(ec.category() == system_category());
+ BOOST_TEST(fs::exists(s));
+ BOOST_TEST(fs::is_directory(s));
+
+ // test status, ec, for non-existing file
+ fs::path p("nosuch");
+ ec.assign(-1, poison_category());
+ s = fs::status(p, ec);
+ BOOST_TEST(ec.value() != 0);
+ BOOST_TEST(ec.category() == system_category());
+
+ BOOST_TEST(!fs::exists(s));
+ BOOST_TEST_EQ(s.type(), fs::file_not_found);
+ BOOST_TEST(fs::type_present(s));
+ BOOST_TEST(!fs::is_regular_file(s));
+ BOOST_TEST(!fs::is_directory(s));
+ BOOST_TEST(!fs::is_symlink(s));
+ BOOST_TEST(!fs::is_other(s));
+
+ // test queries, ec, for existing file
+ ec.assign(-1, poison_category());
+ BOOST_TEST(fs::exists(".", ec));
+ BOOST_TEST(ec.value() == 0);
+ BOOST_TEST(ec.category() == system_category());
+ ec.assign(-1, poison_category());
+ BOOST_TEST(!fs::is_regular_file(".", ec));
+ BOOST_TEST(ec.value() == 0);
+ BOOST_TEST(ec.category() == system_category());
+ ec.assign(-1, poison_category());
+ BOOST_TEST(fs::is_directory(".", ec));
+ BOOST_TEST(ec.value() == 0);
+ BOOST_TEST(ec.category() == system_category());
+
+ // test queries, ec, for non-existing file
+ ec.assign(-1, poison_category());
+ BOOST_TEST(!fs::exists(p, ec));
+ BOOST_TEST(ec.value() != 0);
+ BOOST_TEST(ec.category() == system_category());
+ ec.assign(-1, poison_category());
+ BOOST_TEST(!fs::is_regular_file(p, ec));
+ BOOST_TEST(ec.value() != 0);
+ BOOST_TEST(ec.category() == system_category());
+ ec.assign(-1, poison_category());
+ BOOST_TEST(!fs::is_directory(p, ec));
+ BOOST_TEST(ec.value() != 0);
+ BOOST_TEST(ec.category() == system_category());
+}
+
+// remove_tests --------------------------------------------------------------------//
+
+void remove_tests(const fs::path& dirx)
+{
+ cout << "remove_tests..." << endl;
+
+ // remove() file
+ fs::path f1x = dirx / "shortlife";
+ BOOST_TEST(!fs::exists(f1x));
+ create_file(f1x, "");
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(!fs::is_directory(f1x));
+ BOOST_TEST(fs::remove(f1x));
+ BOOST_TEST(!fs::exists(f1x));
+ BOOST_TEST(!fs::remove("no-such-file"));
+ BOOST_TEST(!fs::remove("no-such-directory/no-such-file"));
+
+#if defined(BOOST_WINDOWS_API)
+ // remove() read-only file
+ BOOST_TEST(!fs::exists(f1x));
+ create_file(f1x, "");
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(!fs::is_directory(f1x));
+ set_read_only(f1x);
+ BOOST_TEST(fs::remove(f1x));
+ BOOST_TEST(!fs::exists(f1x));
+#endif // defined(BOOST_WINDOWS_API)
+
+ // remove() directory
+ fs::path d1x = dirx / "shortlife_dir";
+ BOOST_TEST(!fs::exists(d1x));
+ fs::create_directory(d1x);
+ BOOST_TEST(fs::exists(d1x));
+ BOOST_TEST(fs::is_directory(d1x));
+ BOOST_TEST(fs::is_empty(d1x));
+ bad_remove_dir = dirx;
+ BOOST_TEST(CHECK_EXCEPTION(bad_remove, ENOTEMPTY));
+ BOOST_TEST(fs::remove(d1x));
+ BOOST_TEST(!fs::exists(d1x));
+}
+
+// remove_symlink_tests ------------------------------------------------------------//
+
+void remove_symlink_tests()
+{
+ cout << "remove_symlink_tests..." << endl;
+
+ // remove() dangling symbolic link
+ fs::path link = dir / "dangling_link";
+ fs::remove(link); // remove any residue from past tests
+ BOOST_TEST(!fs::is_symlink(link));
+ BOOST_TEST(!fs::exists(link));
+ fs::create_symlink("nowhere", link);
+ BOOST_TEST(!fs::exists(link));
+ BOOST_TEST(fs::is_symlink(link));
+ BOOST_TEST(fs::remove(link));
+ BOOST_TEST(!fs::is_symlink(link));
+
+ // remove() self-refering symbolic link
+ link = dir / "link_to_self";
+ fs::remove(link); // remove any residue from past tests
+ BOOST_TEST(!fs::is_symlink(link));
+ BOOST_TEST(!fs::exists(link));
+ fs::create_symlink(link, link);
+ BOOST_TEST(fs::remove(link));
+ BOOST_TEST(!fs::exists(link));
+ BOOST_TEST(!fs::is_symlink(link));
+
+ // remove() cyclic symbolic link
+ link = dir / "link_to_a";
+ fs::path link2 = dir / "link_to_b";
+ fs::remove(link); // remove any residue from past tests
+ fs::remove(link2); // remove any residue from past tests
+ BOOST_TEST(!fs::is_symlink(link));
+ BOOST_TEST(!fs::exists(link));
+ fs::create_symlink(link, link2);
+ fs::create_symlink(link2, link);
+ BOOST_TEST(fs::remove(link));
+ BOOST_TEST(fs::remove(link2));
+ BOOST_TEST(!fs::exists(link));
+ BOOST_TEST(!fs::exists(link2));
+ BOOST_TEST(!fs::is_symlink(link));
+
+ // remove() symbolic link to file
+ fs::path f1x = dir / "link_target";
+ fs::remove(f1x); // remove any residue from past tests
+ BOOST_TEST(!fs::exists(f1x));
+ create_file(f1x, "");
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(!fs::is_directory(f1x));
+ BOOST_TEST(fs::is_regular_file(f1x));
+ link = dir / "non_dangling_link";
+ fs::create_symlink(f1x, link);
+ BOOST_TEST(fs::exists(link));
+ BOOST_TEST(!fs::is_directory(link));
+ BOOST_TEST(fs::is_regular_file(link));
+ BOOST_TEST(fs::is_symlink(link));
+ BOOST_TEST(fs::remove(link));
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(!fs::exists(link));
+ BOOST_TEST(!fs::is_symlink(link));
+ BOOST_TEST(fs::remove(f1x));
+ BOOST_TEST(!fs::exists(f1x));
+}
+
+// remove_all_tests ----------------------------------------------------------------//
+
+void remove_all_tests(const fs::path& dirx)
+{
+ cout << "remove_all_tests..." << endl;
+
+ // remove_all() file
+ {
+ fs::path f1x = dirx / "shortlife";
+ BOOST_TEST(!fs::exists(f1x));
+ create_file(f1x, "");
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(!fs::is_directory(f1x));
+ BOOST_TEST_EQ(fs::remove_all(f1x), 1u);
+ BOOST_TEST(!fs::exists(f1x));
+ BOOST_TEST_EQ(fs::remove_all("no-such-file"), 0u);
+ BOOST_TEST_EQ(fs::remove_all("no-such-directory/no-such-file"), 0u);
+ }
+
+ // remove_all() directory tree
+ {
+ unsigned int created_count = 0u;
+ fs::path d1x = dirx / "shortlife_dir";
+ BOOST_TEST(!fs::exists(d1x));
+ fs::create_directory(d1x);
+ ++created_count;
+ BOOST_TEST(fs::exists(d1x));
+ BOOST_TEST(fs::is_directory(d1x));
+
+ fs::path d2x = d1x / "nested_dir";
+ BOOST_TEST(!fs::exists(d2x));
+ fs::create_directory(d2x);
+ ++created_count;
+ BOOST_TEST(fs::exists(d2x));
+ BOOST_TEST(fs::is_directory(d2x));
+
+ fs::path f1x = d1x / "shortlife";
+ BOOST_TEST(!fs::exists(f1x));
+ create_file(f1x, "");
+ ++created_count;
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(!fs::is_directory(f1x));
+
+#if defined(BOOST_WINDOWS_API)
+ // read-only file
+ fs::path f2x = d1x / "shortlife_ro";
+ BOOST_TEST(!fs::exists(f2x));
+ create_file(f2x, "");
+ ++created_count;
+ BOOST_TEST(fs::exists(f2x));
+ BOOST_TEST(!fs::is_directory(f2x));
+ set_read_only(f2x);
+#endif // defined(BOOST_WINDOWS_API)
+
+ boost::uintmax_t removed_count = fs::remove_all(d1x);
+ BOOST_TEST_EQ(removed_count, created_count);
+
+ BOOST_TEST(!fs::exists(d1x));
+ }
+}
+
+// remove_all_symlink_tests --------------------------------------------------------//
+
+void remove_all_symlink_tests(const fs::path& dirx)
+{
+ cout << "remove_all_symlink_tests..." << endl;
+
+ // External directory tree
+ fs::path d1x = dirx / "shortlife_dir1";
+ BOOST_TEST(!fs::exists(d1x));
+ fs::create_directory(d1x);
+ BOOST_TEST(fs::exists(d1x));
+ BOOST_TEST(fs::is_directory(d1x));
+
+ fs::path f1x = d1x / "shortlife1";
+ BOOST_TEST(!fs::exists(f1x));
+ create_file(f1x, "");
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(!fs::is_directory(f1x));
+
+ fs::path f2x = d1x / "shortlife2";
+ BOOST_TEST(!fs::exists(f2x));
+ create_file(f2x, "");
+ BOOST_TEST(fs::exists(f2x));
+ BOOST_TEST(!fs::is_directory(f2x));
+
+ // remove_all() directory tree that has symlinks to external directories
+ unsigned int created_count = 0u;
+ fs::path d2x = dirx / "shortlife_dir2";
+ BOOST_TEST(!fs::exists(d2x));
+ fs::create_directory(d2x);
+ ++created_count;
+ BOOST_TEST(fs::exists(d2x));
+ BOOST_TEST(fs::is_directory(d2x));
+
+ fs::path f3x = d2x / "shortlife";
+ BOOST_TEST(!fs::exists(f3x));
+ create_file(f3x, "");
+ ++created_count;
+ BOOST_TEST(fs::exists(f3x));
+ BOOST_TEST(!fs::is_directory(f3x));
+
+ fs::path d3x = d2x / "symlink_dir";
+ BOOST_TEST(!fs::exists(d3x));
+ fs::create_directory_symlink(d1x, d3x);
+ ++created_count;
+ BOOST_TEST(fs::exists(d3x));
+ BOOST_TEST(fs::is_symlink(d3x));
+
+#if defined(BOOST_FILESYSTEM_HAS_MKLINK)
+ fs::path junc = d2x / "junc";
+ fs::path cur_path(fs::current_path());
+ fs::current_path(d2x);
+ BOOST_TEST(std::system("mklink /J junc ..\\shortlife_dir1") == 0);
+ fs::current_path(cur_path);
+ ++created_count;
+ BOOST_TEST(fs::exists(junc));
+#endif
+
+ fs::path f4x = d2x / "symlink";
+ BOOST_TEST(!fs::exists(f4x));
+ fs::create_symlink(f1x, f4x);
+ ++created_count;
+ BOOST_TEST(fs::exists(f4x));
+ BOOST_TEST(fs::is_symlink(f4x));
+
+ fs::path f5x = d2x / "hardlink";
+ BOOST_TEST(!fs::exists(f5x));
+ fs::create_hard_link(f2x, f5x);
+ ++created_count;
+ BOOST_TEST(fs::exists(f5x));
+ BOOST_TEST(!fs::is_directory(f5x));
+
+ boost::uintmax_t removed_count = fs::remove_all(d2x);
+ BOOST_TEST_EQ(removed_count, created_count);
+
+ BOOST_TEST(!fs::exists(d2x));
+
+ // Check that external directory and file are intact
+ BOOST_TEST(fs::exists(d1x));
+ BOOST_TEST(fs::is_directory(d1x));
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(!fs::is_directory(f1x));
+ BOOST_TEST(fs::exists(f2x));
+ BOOST_TEST(!fs::is_directory(f2x));
+
+ // Cleanup
+ fs::remove_all(d1x);
+}
+
+// absolute_tests -----------------------------------------------------------------//
+
+void absolute_tests()
+{
+ cout << "absolute_tests..." << endl;
+
+ BOOST_TEST_EQ(fs::absolute(""), fs::current_path());
+ BOOST_TEST_EQ(fs::absolute("", ""), fs::current_path());
+ BOOST_TEST_EQ(fs::absolute(fs::current_path() / "foo/bar"), fs::current_path() / "foo/bar");
+ BOOST_TEST_EQ(fs::absolute("foo"), fs::current_path() / "foo");
+ BOOST_TEST_EQ(fs::absolute("foo", fs::current_path()), fs::current_path() / "foo");
+ BOOST_TEST_EQ(fs::absolute("bar", "foo"), fs::current_path() / "foo" / "bar");
+ BOOST_TEST_EQ(fs::absolute("/foo"), fs::current_path().root_path().string() + "foo");
+
+#ifdef BOOST_WINDOWS_API
+ BOOST_TEST_EQ(fs::absolute("a:foo", "b:/bar"), fs::path(L"a:/bar/foo"));
+#endif
+
+ // these tests were moved from elsewhere, so may duplicate some of the above tests
+
+ // p.empty()
+ BOOST_TEST_EQ(fs::absolute(fs::path(), "//foo/bar"), fs::path("//foo/bar"));
+ if (platform == "Windows")
+ {
+ BOOST_TEST_EQ(fs::absolute(fs::path(), "a:/bar"), fs::path("a:/bar"));
+ }
+
+ // p.has_root_name()
+ // p.has_root_directory()
+ BOOST_TEST_EQ(fs::absolute(fs::path("//foo/bar"), "//uvw/xyz"), fs::path("//foo/bar"));
+ if (platform == "Windows")
+ {
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:/bar"), "b:/xyz"), fs::path("a:/bar"));
+ }
+ // !p.has_root_directory()
+ BOOST_TEST_EQ(fs::absolute(fs::path("//net"), "//xyz/"), fs::path("//net/"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("//net"), "//xyz/abc"), fs::path("//net/abc"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("//net"), "//xyz/abc/def"), fs::path("//net/abc/def"));
+ if (platform == "Windows")
+ {
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:"), "b:/"), fs::path("a:/"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:"), "b:/abc"), fs::path("a:/abc"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:"), "b:/abc/def"), fs::path("a:/abc/def"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:foo"), "b:/"), fs::path("a:/foo"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:foo"), "b:/abc"), fs::path("a:/abc/foo"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:foo"), "b:/abc/def"), fs::path("a:/abc/def/foo"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:foo/bar"), "b:/"), fs::path("a:/foo/bar"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:foo/bar"), "b:/abc"), fs::path("a:/abc/foo/bar"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("a:foo/bar"), "b:/abc/def"), fs::path("a:/abc/def/foo/bar"));
+ }
+ // !p.has_root_name()
+ // p.has_root_directory()
+#ifdef BOOST_WINDOWS_API
+ BOOST_TEST_EQ(fs::absolute(fs::path("/"), "//xyz/"), fs::path("//xyz/"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("/"), "//xyz/abc"), fs::path("//xyz/"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("/foo"), "//xyz/"), fs::path("//xyz/foo"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("/foo"), "//xyz/abc"), fs::path("//xyz/foo"));
+#else
+ BOOST_TEST_EQ(fs::absolute(fs::path("/"), "//xyz/"), fs::path("/"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("/"), "//xyz/abc"), fs::path("/"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("/foo"), "//xyz/"), fs::path("/foo"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("/foo"), "//xyz/abc"), fs::path("/foo"));
+#endif
+ // !p.has_root_directory()
+ BOOST_TEST_EQ(fs::absolute(fs::path("foo"), "//xyz/abc"), fs::path("//xyz/abc/foo"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("foo/bar"), "//xyz/abc"), fs::path("//xyz/abc/foo/bar"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("."), "//xyz/abc"), fs::path("//xyz/abc/."));
+ BOOST_TEST_EQ(fs::absolute(fs::path(".."), "//xyz/abc"), fs::path("//xyz/abc/.."));
+ BOOST_TEST_EQ(fs::absolute(fs::path("./foo"), "//xyz/abc"), fs::path("//xyz/abc/./foo"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("../foo"), "//xyz/abc"), fs::path("//xyz/abc/../foo"));
+ if (platform == "POSIX")
+ {
+ BOOST_TEST_EQ(fs::absolute(fs::path("foo"), "/abc"), fs::path("/abc/foo"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("foo/bar"), "/abc"), fs::path("/abc/foo/bar"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("."), "/abc"), fs::path("/abc/."));
+ BOOST_TEST_EQ(fs::absolute(fs::path(".."), "/abc"), fs::path("/abc/.."));
+ BOOST_TEST_EQ(fs::absolute(fs::path("./foo"), "/abc"), fs::path("/abc/./foo"));
+ BOOST_TEST_EQ(fs::absolute(fs::path("../foo"), "/abc"), fs::path("/abc/../foo"));
+ }
+}
+
+// canonical_basic_tests -----------------------------------------------------------//
+
+void canonical_basic_tests()
+{
+ cout << "canonical_basic_tests..." << endl;
+
+ // error handling
+ error_code ec;
+ ec.clear();
+ fs::canonical("no-such-file", ec);
+ BOOST_TEST(ec);
+ ec.clear();
+ fs::canonical("no-such-file", "x", ec);
+ BOOST_TEST(ec);
+ bool ok(false);
+ try
+ {
+ fs::canonical("no-such-file");
+ }
+ catch (const fs::filesystem_error&)
+ {
+ ok = true;
+ }
+ BOOST_TEST(ok);
+
+ // non-symlink tests; also see canonical_symlink_tests()
+ BOOST_TEST_EQ(fs::canonical(""), fs::current_path());
+ BOOST_TEST_EQ(fs::canonical("", fs::current_path()), fs::current_path());
+ BOOST_TEST_EQ(fs::canonical("", ""), fs::current_path());
+ BOOST_TEST_EQ(fs::canonical(fs::current_path()), fs::current_path());
+ BOOST_TEST_EQ(fs::canonical(fs::current_path(), ""), fs::current_path());
+ BOOST_TEST_EQ(fs::canonical(fs::current_path(), "no-such-file"), fs::current_path());
+
+ BOOST_TEST_EQ(fs::canonical("."), fs::current_path());
+ BOOST_TEST_EQ(fs::canonical(".."), fs::current_path().parent_path());
+ BOOST_TEST_EQ(fs::canonical("/"), fs::current_path().root_path());
+
+ fs::path relative_dir(dir.filename());
+ BOOST_TEST_EQ(fs::canonical(dir), dir);
+ BOOST_TEST_EQ(fs::canonical(relative_dir), dir);
+ BOOST_TEST_EQ(fs::canonical(dir / "f0"), dir / "f0");
+ BOOST_TEST_EQ(fs::canonical(relative_dir / "f0"), dir / "f0");
+ BOOST_TEST_EQ(fs::canonical(relative_dir / "./f0"), dir / "f0");
+ BOOST_TEST_EQ(fs::canonical(relative_dir / "d1/../f0"), dir / "f0");
+
+ // treat parent of root as itself on both POSIX and Windows
+ fs::path init(fs::initial_path());
+ fs::path root(init.root_path());
+ fs::path::const_iterator it(init.begin());
+ fs::path first; // relative first non-root directory
+#ifdef BOOST_WINDOWS_API
+ if (!init.empty())
+ ++it;
+#endif
+ if (++it != init.end())
+ first = *it;
+ fs::path expected(root / first);
+
+ cout << " init: " << init << endl;
+ cout << " root: " << root << endl;
+ cout << " first: " << first << endl;
+ cout << " expected: " << expected << endl;
+
+ // ticket 10187 tests
+ BOOST_TEST_EQ(fs::canonical(root / "../.." / first), expected);
+ BOOST_TEST_EQ(fs::canonical(fs::path("../..") / first, root), expected);
+ BOOST_TEST_EQ(fs::canonical(fs::path("/../..") / first, fs::current_path().root_name()), expected);
+
+ // ticket 9683 test
+ BOOST_TEST_EQ(fs::canonical(root / first / "../../../../.."), root);
+}
+
+// canonical_symlink_tests -----------------------------------------------------------//
+
+void canonical_symlink_tests()
+{
+ cout << "canonical_symlink_tests..." << endl;
+
+ fs::path relative_dir(dir.filename());
+ BOOST_TEST_EQ(fs::canonical(dir / "sym-d1/f2"), d1 / "f2");
+ BOOST_TEST_EQ(fs::canonical(relative_dir / "sym-d1/f2"), d1 / "f2");
+}
+
+// copy_file_tests ------------------------------------------------------------------//
+
+void copy_file_tests(const fs::path& f1x, const fs::path& d1x)
+{
+ cout << "copy_file_tests..." << endl;
+
+ BOOST_TEST(fs::exists(f1x));
+ fs::remove(d1x / "f2"); // remove possible residue from prior testing
+ BOOST_TEST(fs::exists(d1x));
+ BOOST_TEST(!fs::exists(d1x / "f2"));
+ cout << " copy " << f1x << " to " << d1x / "f2" << endl;
+ bool file_copied = fs::copy_file(f1x, d1x / "f2");
+ cout << " copy complete" << endl;
+ BOOST_TEST(file_copied);
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(fs::exists(d1x / "f2"));
+ BOOST_TEST(!fs::is_directory(d1x / "f2"));
+ verify_file(d1x / "f2", "file-f1");
+
+ bool copy_ex_ok = false;
+ file_copied = false;
+ try
+ {
+ file_copied = fs::copy_file(f1x, d1x / "f2");
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = true;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(!file_copied);
+
+ file_copied = false;
+ copy_ex_ok = false;
+ try
+ {
+ file_copied = fs::copy_file(f1x, d1x / "f2", fs::copy_options::none);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = true;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(!file_copied);
+
+ fs::remove(d1x / "f2");
+ create_file(d1x / "f2", "1234567890");
+ BOOST_TEST_EQ(fs::file_size(d1x / "f2"), 10U);
+ file_copied = false;
+ copy_ex_ok = true;
+ try
+ {
+ file_copied = fs::copy_file(f1x, d1x / "f2", fs::copy_options::skip_existing);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(!file_copied);
+ BOOST_TEST_EQ(fs::file_size(d1x / "f2"), 10U);
+ verify_file(d1x / "f2", "1234567890");
+
+ file_copied = false;
+ copy_ex_ok = true;
+ try
+ {
+ file_copied = fs::copy_file(f1x, d1x / "f2-non-existing", fs::copy_options::skip_existing);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(file_copied);
+ BOOST_TEST_EQ(fs::file_size(d1x / "f2-non-existing"), 7U);
+ verify_file(d1x / "f2-non-existing", "file-f1");
+ fs::remove(d1x / "f2-non-existing");
+
+ file_copied = false;
+ copy_ex_ok = true;
+ try
+ {
+ file_copied = fs::copy_file(f1x, d1x / "f2", fs::copy_options::update_existing);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(!file_copied);
+ BOOST_TEST_EQ(fs::file_size(d1x / "f2"), 10U);
+ verify_file(d1x / "f2", "1234567890");
+
+ // Sleep for a while so that the last modify time is more recent for new files
+#if defined(BOOST_POSIX_API)
+ sleep(2);
+#else
+ Sleep(2000);
+#endif
+
+ create_file(d1x / "f2-more-recent", "x");
+ BOOST_TEST_EQ(fs::file_size(d1x / "f2-more-recent"), 1U);
+ file_copied = false;
+ copy_ex_ok = true;
+ try
+ {
+ file_copied = fs::copy_file(d1x / "f2-more-recent", d1x / "f2", fs::copy_options::update_existing);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(file_copied);
+ BOOST_TEST_EQ(fs::file_size(d1x / "f2"), 1U);
+ verify_file(d1x / "f2", "x");
+ fs::remove(d1x / "f2-more-recent");
+
+ fs::remove(d1x / "f2");
+ create_file(d1x / "f2", "1234567890");
+ BOOST_TEST_EQ(fs::file_size(d1x / "f2"), 10U);
+ file_copied = false;
+ copy_ex_ok = true;
+ try
+ {
+ file_copied = fs::copy_file(f1x, d1x / "f2", fs::copy_options::overwrite_existing);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(file_copied);
+ BOOST_TEST_EQ(fs::file_size(d1x / "f2"), 7U);
+ verify_file(d1x / "f2", "file-f1");
+
+ fs::remove(d1x / "f2");
+ file_copied = false;
+ copy_ex_ok = true;
+ try
+ {
+ file_copied = fs::copy_file(f1x, d1x / "f2", fs::copy_options::synchronize_data);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(file_copied);
+ verify_file(d1x / "f2", "file-f1");
+
+ fs::remove(d1x / "f2");
+ file_copied = false;
+ copy_ex_ok = true;
+ try
+ {
+ file_copied = fs::copy_file(f1x, d1x / "f2", fs::copy_options::synchronize);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(file_copied);
+ verify_file(d1x / "f2", "file-f1");
+
+ // Test copy_file with special files with generated content. Such files have zero size,
+ // but have contents.
+ if (fs::is_regular_file("/proc/self/cmdline"))
+ {
+ file_copied = false;
+ copy_ex_ok = true;
+ try
+ {
+ file_copied = fs::copy_file("/proc/self/cmdline", d1x / "cmdline");
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(file_copied);
+ BOOST_TEST_GT(fs::file_size(d1x / "cmdline"), 0u);
+ }
+
+#ifdef BOOST_WINDOWS_API
+ // Test copying files with multiple NTFS streams
+ fs::path multi_stream_path = d1x / "multi-stream";
+ fs::path multi_stream_alt_path = d1x / "multi-stream:alt-stream";
+ fs::path multi_stream_copy_path = d1x / "multi-stream-copy";
+ fs::path multi_stream_alt_copy_path = d1x / "multi-stream-copy:alt-stream";
+ create_file(multi_stream_path, "multi-stream:default");
+ try
+ {
+ // Check that the filesystem supports alternate streams
+ create_file(multi_stream_alt_path, "multi-stream:alternate");
+ verify_file(multi_stream_alt_path, "multi-stream:alternate");
+
+ fs::remove(multi_stream_copy_path);
+ copy_ex_ok = true;
+ file_copied = false;
+ try
+ {
+ file_copied = fs::copy_file(multi_stream_path, multi_stream_copy_path);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(file_copied);
+ verify_file(multi_stream_copy_path, "multi-stream:default");
+ verify_file(multi_stream_alt_copy_path, "multi-stream:alternate");
+
+ fs::remove(multi_stream_copy_path);
+ copy_ex_ok = true;
+ file_copied = false;
+ try
+ {
+ file_copied = fs::copy_file(multi_stream_path, multi_stream_copy_path, fs::copy_options::synchronize_data);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(file_copied);
+ verify_file(multi_stream_copy_path, "multi-stream:default");
+ verify_file(multi_stream_alt_copy_path, "multi-stream:alternate");
+
+ fs::remove(multi_stream_copy_path);
+ copy_ex_ok = true;
+ file_copied = false;
+ try
+ {
+ file_copied = fs::copy_file(multi_stream_path, multi_stream_copy_path, fs::copy_options::synchronize);
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = false;
+ }
+ BOOST_TEST(copy_ex_ok);
+ BOOST_TEST(file_copied);
+ verify_file(multi_stream_copy_path, "multi-stream:default");
+ verify_file(multi_stream_alt_copy_path, "multi-stream:alternate");
+
+ fs::remove(multi_stream_copy_path);
+ }
+ catch (const fs::filesystem_error& e)
+ {
+ cout << "Multiple streams per file are not supported: " << e.what() << "\nSkipping multi-stream tests..." << endl;
+ }
+#endif // BOOST_WINDOWS_API
+}
+
+// symlink_status_tests -------------------------------------------------------------//
+
+void symlink_status_tests()
+{
+ cout << "symlink_status_tests..." << endl;
+
+ boost::system::error_code ec;
+
+ fs::path dangling_sym(dir / "dangling-sym");
+ fs::path dangling_directory_sym(dir / "dangling-directory-sym");
+ fs::path sym_d1(dir / "sym-d1");
+ fs::path symsym_d1(dir / "symsym-d1");
+ fs::path sym_f1(dir / "sym-f1");
+ fs::path symsym_f1(dir / "symsym-f1");
+ fs::create_symlink("does not exist", dangling_sym);
+ fs::create_directory_symlink("does not exist", dangling_directory_sym);
+ fs::create_directory_symlink(d1, sym_d1);
+ fs::create_directory_symlink(sym_d1, symsym_d1);
+ fs::create_symlink(f1, sym_f1);
+ fs::create_symlink(sym_f1, symsym_f1);
+
+ // verify all cases detected as symlinks
+ BOOST_TEST_EQ(fs::symlink_status(dangling_sym, ec).type(), fs::symlink_file);
+ BOOST_TEST_EQ(fs::symlink_status(dangling_directory_sym, ec).type(), fs::symlink_file);
+ BOOST_TEST_EQ(fs::symlink_status(sym_d1, ec).type(), fs::symlink_file);
+ BOOST_TEST_EQ(fs::symlink_status(symsym_d1, ec).type(), fs::symlink_file);
+ BOOST_TEST_EQ(fs::symlink_status(sym_f1, ec).type(), fs::symlink_file);
+ BOOST_TEST_EQ(fs::symlink_status(symsym_f1, ec).type(), fs::symlink_file);
+
+ // verify all cases resolve to the (possibly recursive) symlink target
+ BOOST_TEST_EQ(fs::status(dangling_sym, ec).type(), fs::file_not_found);
+ BOOST_TEST_EQ(fs::status(dangling_directory_sym, ec).type(), fs::file_not_found);
+
+ BOOST_TEST_EQ(fs::status(sym_d1, ec).type(), fs::directory_file);
+ BOOST_TEST_EQ(fs::status(sym_d1 / "d1f1", ec).type(), fs::regular_file);
+ BOOST_TEST_EQ(fs::status(symsym_d1, ec).type(), fs::directory_file);
+ BOOST_TEST_EQ(fs::status(symsym_d1 / "d1f1", ec).type(), fs::regular_file);
+ BOOST_TEST_EQ(fs::status(sym_f1, ec).type(), fs::regular_file);
+ BOOST_TEST_EQ(fs::status(symsym_f1, ec).type(), fs::regular_file);
+
+#ifdef BOOST_WINDOWS_API
+
+ // On Windows, telling if a filesystem entry is a symlink (or junction which is
+ // treated as a symlink), rather than some other kind of reparse point, requires some
+ // baroque code. See ticket #4663, filesystem objects falsely identified as symlinks.
+ // This test checks two directory entries created by Windows itself to verify
+ // is_symlink() works correctly. Try "dir /A %HOMEPATH%\.." from the command line to
+ // verify this test is valid on your version of Windows. It only works on Vista and
+ // later.
+
+ fs::path users(getenv("HOMEDRIVE"));
+ BOOST_TEST(!users.empty());
+ users /= "\\Users";
+ BOOST_TEST(fs::exists(users));
+ BOOST_TEST(fs::exists(users / "All Users"));
+ BOOST_TEST(fs::exists(users / "Default User"));
+ BOOST_TEST(fs::is_symlink(users / "All Users")); // dir /A reports <SYMLINKD>
+ BOOST_TEST(fs::is_symlink(users / "Default User")); // dir /A reports <JUNCTION>
+
+#endif
+}
+
+// copy_symlink_tests ---------------------------------------------------------------//
+
+void copy_symlink_tests(const fs::path& f1x, const fs::path& d1x)
+{
+ cout << "copy_symlink_tests..." << endl;
+
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(fs::exists(d1x));
+ fs::path sym1(d1x / "symlink1");
+ fs::remove(sym1); // remove possible residue from prior testing
+ fs::create_symlink(f1x, sym1);
+ BOOST_TEST(fs::exists(sym1));
+ BOOST_TEST(fs::is_symlink(sym1));
+ fs::path sym2(d1x / "symlink2");
+ fs::copy_symlink(sym1, sym2);
+ BOOST_TEST(fs::exists(sym2));
+ BOOST_TEST(fs::is_symlink(sym2));
+ //fs::path sym3(d1x / "symlink3");
+ //fs::copy(sym1, sym3);
+ //BOOST_TEST(fs::exists(sym3));
+ //BOOST_TEST(fs::is_symlink(sym3));
+
+ bool copy_ex_ok = false;
+ try
+ {
+ fs::copy_symlink("no-such-file", "new-symlink1");
+ }
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = true;
+ }
+ BOOST_TEST(copy_ex_ok);
+
+ copy_ex_ok = false;
+ try
+ {
+ fs::copy_symlink(f1x, "new-symlink2");
+ } // should fail; f1x not symlink
+ catch (const fs::filesystem_error&)
+ {
+ copy_ex_ok = true;
+ }
+ BOOST_TEST(copy_ex_ok);
+}
+
+// creation_time_tests -------------------------------------------------------------//
+
+void creation_time_tests(const fs::path& dirx)
+{
+ cout << "creation_time_tests..." << endl;
+
+ fs::path f1x = dirx / "creation_time_file";
+
+ std::time_t start = std::time(NULL);
+
+ // These pauses are inserted because the test spuriously fails on Windows, presumably because of
+ // different converting FILETIME to seconds in time() and Boost.Filesystem or some sort of quirk
+ // in the Windows implementation of filesystem API.
+#if defined(BOOST_POSIX_API)
+ sleep(1);
+#else
+ Sleep(1000);
+#endif
+ create_file(f1x, "creation_time_file");
+ BOOST_TEST(fs::is_regular_file(f1x));
+ try
+ {
+ std::time_t ft = fs::creation_time(f1x);
+#if defined(BOOST_POSIX_API)
+ sleep(1);
+#else
+ Sleep(1000);
+#endif
+ std::time_t finish = std::time(NULL);
+ cout << " start time: " << start << ", file creation time: " << ft << ", finish time: " << finish << endl;
+
+ BOOST_TEST(ft >= start && ft <= finish);
+ }
+ catch (fs::filesystem_error& e)
+ {
+ if (e.code() == make_error_condition(boost::system::errc::function_not_supported))
+ {
+ cout << "creation_time is not supported by the current system" << endl;
+ }
+ else
+ {
+ cout << "creation_time failed: " << e.what() << endl;
+ BOOST_TEST(false);
+ }
+ }
+
+ fs::remove(f1x);
+}
+
+// write_time_tests ----------------------------------------------------------------//
+
+void write_time_tests(const fs::path& dirx)
+{
+ cout << "write_time_tests..." << endl;
+
+ fs::path f1x = dirx / "foobar2";
+ create_file(f1x, "foobar2");
+ BOOST_TEST(fs::exists(f1x));
+ BOOST_TEST(!fs::is_directory(f1x));
+ BOOST_TEST(fs::is_regular_file(f1x));
+ BOOST_TEST(fs::file_size(f1x) == 7);
+ verify_file(f1x, "foobar2");
+
+ // Some file system report last write time as local (FAT), while
+ // others (NTFS) report it as UTC. The C standard does not specify
+ // if time_t is local or UTC.
+
+ std::time_t ft = fs::last_write_time(f1x);
+ cout << "\n UTC last_write_time() for a file just created is "
+ << std::asctime(std::gmtime(&ft)) << endl;
+
+ std::tm* tmp = std::localtime(&ft);
+ cout << "\n Year is " << tmp->tm_year << endl;
+ --tmp->tm_year;
+ cout << " Change year to " << tmp->tm_year << endl;
+ fs::last_write_time(f1x, std::mktime(tmp));
+ std::time_t ft2 = fs::last_write_time(f1x);
+ cout << " last_write_time() for the file is now "
+ << std::asctime(std::gmtime(&ft2)) << endl;
+ BOOST_TEST(ft != fs::last_write_time(f1x));
+
+ cout << "\n Reset to current time" << endl;
+ fs::last_write_time(f1x, ft);
+ double time_diff = std::difftime(ft, fs::last_write_time(f1x));
+ cout
+ << " original last_write_time() - current last_write_time() is "
+ << time_diff << " seconds" << endl;
+ BOOST_TEST(time_diff >= -60.0 && time_diff <= 60.0);
+}
+
+// platform_specific_tests ---------------------------------------------------------//
+
+void platform_specific_tests()
+{
+ // Windows only tests
+ if (platform == "Windows")
+ {
+ cout << "Windows specific tests..." << endl;
+ if (!skip_long_windows_tests)
+ {
+ cout << " (may take several seconds)" << endl;
+
+ BOOST_TEST(!fs::exists(fs::path("//share-not")));
+ BOOST_TEST(!fs::exists(fs::path("//share-not/")));
+ BOOST_TEST(!fs::exists(fs::path("//share-not/foo")));
+ }
+ cout << endl;
+
+ BOOST_TEST(!fs::exists("tools/jam/src/:sys:stat.h")); // !exists() if ERROR_INVALID_NAME
+ BOOST_TEST(!fs::exists(":sys:stat.h")); // !exists() if ERROR_INVALID_PARAMETER
+ BOOST_TEST(dir.string().size() > 1 && dir.string()[1] == ':'); // verify path includes drive
+
+ BOOST_TEST(fs::system_complete("").empty());
+ BOOST_TEST(fs::system_complete("/") == fs::initial_path().root_path());
+ BOOST_TEST(fs::system_complete("foo") == fs::initial_path() / "foo");
+
+ fs::path p1(fs::system_complete("/foo"));
+ BOOST_TEST_EQ(p1.string().size(), 6U); // this failed during v3 development due to bug
+ std::string s1(p1.string());
+ std::string s2(fs::initial_path().root_path().string() + "foo");
+ BOOST_TEST_EQ(s1, s2);
+
+ BOOST_TEST(fs::system_complete(fs::path(fs::initial_path().root_name())) == fs::initial_path());
+ BOOST_TEST(fs::system_complete(fs::path(fs::initial_path().root_name().string() + "foo")).string() == fs::initial_path() / "foo");
+ BOOST_TEST(fs::system_complete(fs::path("c:/")).generic_string() == "c:/");
+ BOOST_TEST(fs::system_complete(fs::path("c:/foo")).generic_string() == "c:/foo");
+ BOOST_TEST(fs::system_complete(fs::path("//share")).generic_string() == "//share");
+
+#if defined(BOOST_FILESYSTEM_HAS_MKLINK)
+ // Issue 9016 asked that NTFS directory junctions be recognized as directories.
+ // That is equivalent to recognizing them as symlinks, and then the normal symlink
+ // mechanism takes care of recognizing them as directories.
+ //
+ // Directory junctions are very similar to symlinks, but have some performance
+ // and other advantages over symlinks. They can be created from the command line
+ // with "mklink /J junction-name target-path".
+
+ {
+ cout << " directory junction tests..." << endl;
+ BOOST_TEST(fs::exists(dir));
+ BOOST_TEST(fs::exists(dir / "d1/d1f1"));
+ fs::path junc(dir / "junc");
+ if (fs::exists(junc))
+ fs::remove(junc);
+ fs::path new_junc(dir / "new-junc");
+ if (fs::exists(new_junc))
+ fs::remove(new_junc);
+
+ //cout << " dir is " << dir << endl;
+ //cout << " junc is " << junc << endl;
+ //cout << " new_junc is " << new_junc << endl;
+ //cout << " current_path() is " << fs::current_path() << endl;
+
+ fs::path cur_path(fs::current_path());
+ fs::current_path(dir);
+ //cout << " current_path() is " << fs::current_path() << endl;
+ BOOST_TEST(std::system("mklink /J junc d1") == 0);
+ //std::system("dir");
+ fs::current_path(cur_path);
+ //cout << " current_path() is " << fs::current_path() << endl;
+
+ BOOST_TEST(fs::exists(junc));
+ BOOST_TEST(fs::is_symlink(junc));
+ BOOST_TEST(fs::is_directory(junc));
+ BOOST_TEST(!fs::is_regular_file(junc));
+ BOOST_TEST(fs::exists(junc / "d1f1"));
+ BOOST_TEST(fs::is_regular_file(junc / "d1f1"));
+
+ int count = 0;
+ for (fs::directory_iterator itr(junc); itr != fs::directory_iterator(); ++itr)
+ {
+ //cout << itr->path() << endl;
+ ++count;
+ }
+ cout << " iteration count is " << count << endl;
+ BOOST_TEST(count > 0);
+
+ fs::rename(junc, new_junc);
+ BOOST_TEST(!fs::exists(junc));
+ BOOST_TEST(fs::exists(new_junc));
+ BOOST_TEST(fs::is_symlink(new_junc));
+ BOOST_TEST(fs::is_directory(new_junc));
+ BOOST_TEST(!fs::is_regular_file(new_junc));
+ BOOST_TEST(fs::exists(new_junc / "d1f1"));
+ BOOST_TEST(fs::is_regular_file(new_junc / "d1f1"));
+
+ fs::remove(new_junc);
+ BOOST_TEST(!fs::exists(new_junc / "d1f1"));
+ BOOST_TEST(!fs::exists(new_junc));
+ BOOST_TEST(fs::exists(dir));
+ BOOST_TEST(fs::exists(dir / "d1/d1f1"));
+ }
+#endif // defined(BOOST_FILESYSTEM_HAS_MKLINK)
+ } // Windows
+
+ else if (platform == "POSIX")
+ {
+ cout << "POSIX specific tests..." << endl;
+ BOOST_TEST(fs::system_complete("").empty());
+ BOOST_TEST(fs::initial_path().root_path().string() == "/");
+ BOOST_TEST(fs::system_complete("/").string() == "/");
+ BOOST_TEST(fs::system_complete("foo").string() == fs::initial_path().string() + "/foo");
+ BOOST_TEST(fs::system_complete("/foo").string() == fs::initial_path().root_path().string() + "foo");
+ } // POSIX
+}
+
+// initial_tests -------------------------------------------------------------------//
+
+void initial_tests()
+{
+ cout << "initial_tests..." << endl;
+
+ cout << " current_path().string() is\n \""
+ << fs::initial_path().string()
+ << "\"\n\n";
+ BOOST_TEST(fs::initial_path() == fs::current_path());
+ BOOST_TEST(fs::initial_path().is_absolute());
+ BOOST_TEST(fs::current_path().is_absolute());
+ BOOST_TEST(fs::initial_path().string() == fs::current_path().string());
+}
+
+// space_tests ---------------------------------------------------------------------//
+
+void space_tests()
+{
+ cout << "space_tests..." << endl;
+
+ // make some reasonable assuptions for testing purposes
+ fs::space_info spi(fs::space(dir));
+ BOOST_TEST(spi.capacity > 1000000);
+ BOOST_TEST(spi.free > 1000);
+ BOOST_TEST(spi.capacity > spi.free);
+ BOOST_TEST(spi.free >= spi.available);
+
+ // it is convenient to display space, but older VC++ versions choke
+#if !defined(BOOST_MSVC) || _MSC_VER >= 1300 // 1300 == VC++ 7.0
+ cout << " capacity = " << spi.capacity << '\n';
+ cout << " free = " << spi.free << '\n';
+ cout << " available = " << spi.available << '\n';
+#endif
+
+ // Test that we can specify path to file
+ fs::path file = dir / "file";
+ create_file(file);
+
+ fs::space_info spi_file(fs::space(file));
+ BOOST_TEST_EQ(spi_file.capacity, spi.capacity);
+
+ fs::remove(file);
+
+ // Test that an error is indicated if a path to a non-existing file is passed
+ BOOST_TEST(CHECK_EXCEPTION(bad_space, ENOENT));
+}
+
+// equivalent_tests ----------------------------------------------------------------//
+
+void equivalent_tests(const fs::path& f1x)
+{
+ cout << "equivalent_tests..." << endl;
+
+ BOOST_TEST(CHECK_EXCEPTION(bad_equivalent, ENOENT));
+ BOOST_TEST(fs::equivalent(f1x, dir / "f1"));
+ BOOST_TEST(fs::equivalent(dir, d1 / ".."));
+ BOOST_TEST(!fs::equivalent(f1x, dir));
+ BOOST_TEST(!fs::equivalent(dir, f1x));
+ BOOST_TEST(!fs::equivalent(d1, d2));
+ BOOST_TEST(!fs::equivalent(dir, ng));
+ BOOST_TEST(!fs::equivalent(ng, dir));
+ BOOST_TEST(!fs::equivalent(f1x, ng));
+ BOOST_TEST(!fs::equivalent(ng, f1x));
+}
+
+// temp_directory_path_tests -------------------------------------------------------//
+// contributed by Jeff Flinn
+
+struct guarded_env_var
+{
+ struct previous_value
+ {
+ std::string m_name;
+ std::string m_string;
+ bool m_empty;
+
+ previous_value(const char* name) :
+ m_name(name), m_empty(true)
+ {
+ if (const char* value = getenv(name))
+ {
+ m_string.assign(value);
+ m_empty = false;
+ }
+ else
+ {
+ m_empty = true;
+ }
+ }
+ ~previous_value()
+ {
+ m_empty ? unsetenv_(m_name.c_str()) : setenv_(m_name.c_str(), m_string.c_str(), 1);
+ }
+ };
+
+ previous_value m_previous_value;
+
+ guarded_env_var(const char* name, const char* value) :
+ m_previous_value(name)
+ {
+ // std::cout << name << " old value is \"" << getenv(name) << "\"" << std::endl;
+ value ? setenv_(name, value, 1) : unsetenv_(name);
+ // std::cout << name << " new value is \"" << getenv(name) << "\"" << std::endl;
+ }
+};
+
+void temp_directory_path_tests()
+{
+ {
+ cout << "temp_directory_path_tests..." << endl;
+ cout << " temp_directory_path() is " << fs::temp_directory_path() << endl;
+
+#if defined(BOOST_WINDOWS_API)
+
+ //**************************************************************************************//
+ // Bug in GCC 4.9 getenv() when !defined(__GXX_EXPERIMENTAL_CXX0X__) makes these
+ // tests meaningless, so skip them
+ //**************************************************************************************//
+
+#if defined(__CYGWIN__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ == 4
+ cout << "Bug in GCC 4.9 getenv() when !defined(__GXX_EXPERIMENTAL_CXX0X__) makes these"
+ "tests meaningless, so skip them"
+ << endl;
+ return;
+#endif
+ // Test ticket #5300, temp_directory_path failure on Windows with path length > 130.
+ // (This test failed prior to the fix being applied.)
+ {
+ const wchar_t long_name[] =
+ L"12345678901234567890123456789012345678901234567890"
+ L"12345678901234567890123456789012345678901234567890"
+ L"12345678901234567890123456789012345678901234567890#" // total 151 chars
+ ;
+ fs::path p(temp_dir);
+ p /= long_name;
+ fs::create_directory(p);
+
+ guarded_env_var tmp_guard("TMP", p.string().c_str());
+ error_code ec;
+ fs::path tmp_path = fs::temp_directory_path(ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST_EQ(p, tmp_path);
+ fs::remove(p);
+ }
+
+ // Test ticket #10388, null character at end of filesystem::temp_directory_path path
+ {
+ guarded_env_var tmp_guard("TMP", fs::initial_path().string().c_str());
+
+ error_code ec;
+ fs::path tmp_path = fs::temp_directory_path(ec);
+ BOOST_TEST_EQ(tmp_path, fs::initial_path());
+ }
+
+#endif
+ BOOST_TEST(!fs::temp_directory_path().empty());
+ BOOST_TEST(exists(fs::temp_directory_path()));
+ fs::path ph = fs::temp_directory_path() / fs::unique_path("temp_directory_path_test_%%%%_%%%%.txt");
+ {
+ if (exists(ph))
+ remove(ph);
+ std::ofstream f(BOOST_FILESYSTEM_C_STR(ph));
+ f << "passed";
+ }
+ BOOST_TEST(exists(ph));
+ {
+ std::ifstream f(BOOST_FILESYSTEM_C_STR(ph));
+ std::string s;
+ f >> s;
+ BOOST_TEST(s == "passed");
+ }
+ remove(ph);
+ BOOST_TEST(!exists(ph));
+ }
+
+ fs::path test_temp_dir = temp_dir;
+
+#if defined(BOOST_POSIX_API)
+ {
+ struct guarded_tmp_vars
+ {
+ guarded_env_var m_tmpdir;
+ guarded_env_var m_tmp;
+ guarded_env_var m_temp;
+ guarded_env_var m_tempdir;
+
+ guarded_tmp_vars(const fs::path::value_type* tmpdir, const fs::path::value_type* tmp, const fs::path::value_type* temp, const fs::path::value_type* tempdir) :
+ m_tmpdir("TMPDIR", tmpdir), m_tmp("TMP", tmp), m_temp("TEMP", temp), m_tempdir("TEMPDIR", tempdir)
+ {
+ }
+ };
+
+ {
+ guarded_tmp_vars vars(test_temp_dir.c_str(), 0, 0, 0);
+ fs::path ph = fs::temp_directory_path();
+ BOOST_TEST(equivalent(test_temp_dir, ph));
+ }
+ {
+ guarded_tmp_vars vars(0, test_temp_dir.c_str(), 0, 0);
+ fs::path ph = fs::temp_directory_path();
+ BOOST_TEST(equivalent(test_temp_dir, ph));
+ }
+ {
+ guarded_tmp_vars vars(0, 0, test_temp_dir.c_str(), 0);
+ fs::path ph = fs::temp_directory_path();
+ BOOST_TEST(equivalent(test_temp_dir, ph));
+ }
+ {
+ guarded_tmp_vars vars(0, 0, 0, test_temp_dir.c_str());
+ fs::path ph = fs::temp_directory_path();
+ BOOST_TEST(equivalent(test_temp_dir, ph));
+ }
+ }
+#endif
+
+#if defined(BOOST_WINDOWS_API)
+
+ struct guarded_tmp_vars
+ {
+ guarded_env_var m_tmp;
+ guarded_env_var m_temp;
+ guarded_env_var m_localappdata;
+ guarded_env_var m_userprofile;
+
+ guarded_tmp_vars(const char* tmp, const char* temp, const char* localappdata, const char* userprofile) :
+ m_tmp("TMP", tmp), m_temp("TEMP", temp), m_localappdata("LOCALAPPDATA", localappdata), m_userprofile("USERPROFILE", userprofile)
+ {
+ }
+ };
+
+ // test the GetWindowsDirectoryW()/Temp fallback
+ {
+ guarded_tmp_vars vars(0, 0, 0, 0);
+ error_code ec;
+ fs::path ph = fs::temp_directory_path(ec);
+ BOOST_TEST(!ec);
+ cout << "Fallback test, temp_directory_path() returned " << ph << endl;
+ }
+
+ {
+ guarded_tmp_vars vars(test_temp_dir.string().c_str(), 0, 0, 0);
+ fs::path ph = fs::temp_directory_path();
+ BOOST_TEST(equivalent(test_temp_dir, ph));
+ }
+ {
+ guarded_tmp_vars vars(0, test_temp_dir.string().c_str(), 0, 0);
+ fs::path ph = fs::temp_directory_path();
+ BOOST_TEST(equivalent(test_temp_dir, ph));
+ }
+
+ fs::create_directory(test_temp_dir / L"Temp");
+ {
+ guarded_tmp_vars vars(0, 0, test_temp_dir.string().c_str(), 0);
+ fs::path ph = fs::temp_directory_path();
+ BOOST_TEST(equivalent(test_temp_dir / L"Temp", ph));
+ cout << "temp_directory_path() returned " << ph << endl;
+ }
+ {
+ guarded_tmp_vars vars(0, 0, 0, test_temp_dir.string().c_str());
+ fs::path ph = fs::temp_directory_path();
+ BOOST_TEST(equivalent(test_temp_dir / L"Temp", ph));
+ cout << "temp_directory_path() returned " << ph << endl;
+ }
+#endif
+}
+
+// weakly_canonical_basic_tests ----------------------------------------------------//
+
+void weakly_canonical_basic_tests()
+{
+ cout << "weakly_canonical_basic_tests..." << endl;
+ cout << " dir is " << dir << endl;
+
+ BOOST_TEST_EQ(fs::weakly_canonical("no-such/foo/bar"), fs::path("no-such/foo/bar"));
+ BOOST_TEST_EQ(fs::weakly_canonical("no-such/foo/../bar"), fs::path("no-such/bar"));
+ BOOST_TEST_EQ(fs::weakly_canonical(dir), dir);
+ BOOST_TEST_EQ(fs::weakly_canonical(dir / "no-such/foo/bar"), dir / "no-such/foo/bar");
+ BOOST_TEST_EQ(fs::weakly_canonical(dir / "no-such/foo/../bar"), dir / "no-such/bar");
+ BOOST_TEST_EQ(fs::weakly_canonical(dir / "../no-such/foo/../bar"), dir.parent_path() / "no-such/bar");
+ BOOST_TEST_EQ(fs::weakly_canonical(dir / "no-such/../f0"), dir / "f0"); // dir / "f0" exists, dir / "no-such" does not
+ BOOST_TEST_EQ(fs::weakly_canonical("c:/no-such/foo/bar"), fs::path("c:/no-such/foo/bar"));
+}
+
+// weakly_canonical_symlink_tests --------------------------------------------------//
+
+void weakly_canonical_symlink_tests()
+{
+ cout << "weakly_canonical_symlink_tests..." << endl;
+ cout << " dir is " << dir << endl;
+
+ fs::create_directory_symlink(dir / "d1", dir / "sld1");
+ BOOST_TEST_EQ(fs::weakly_canonical(dir / "sld1/foo/bar"), dir / "d1/foo/bar");
+
+ BOOST_TEST_EQ(relative(dir / "sld1/foo/bar/baz", dir / "d1/foo"), fs::path("bar/baz"));
+}
+
+// _tests --------------------------------------------------------------------------//
+
+//void _tests()
+//{
+// cout << "_tests..." << endl;
+//}
+
+} // unnamed namespace
+
+//------------------------------------------------------------------------------------//
+// //
+// main //
+// //
+//------------------------------------------------------------------------------------//
+
+int cpp_main(int argc, char* argv[])
+{
+// document state of critical macros
+#ifdef BOOST_POSIX_API
+ cout << "BOOST_POSIX_API is defined\n";
+#endif
+#ifdef BOOST_WINDOWS_API
+ cout << "BOOST_WINDOWS_API is defined\n";
+#endif
+
+ for (; argc > 1; --argc, ++argv)
+ {
+ if (*argv[1] == '-' && *(argv[1] + 1) == 't')
+ report_throws = true;
+ else if (*argv[1] == '-' && *(argv[1] + 1) == 'x')
+ cleanup = false;
+ else if (*argv[1] == '-' && *(argv[1] + 1) == 'w')
+ skip_long_windows_tests = true;
+ }
+
+ // The choice of platform to test is made at runtime rather than compile-time
+ // so that compile errors for all platforms will be detected even though
+ // only the current platform is runtime tested.
+#if defined(BOOST_POSIX_API)
+ platform = "POSIX";
+#elif defined(BOOST_WINDOWS_API)
+ platform = "Windows";
+#else
+#error neither BOOST_POSIX_API nor BOOST_WINDOWS_API is defined. See boost/system/api_config.hpp
+#endif
+ cout << "API is " << platform << endl;
+ cout << "initial_path() is " << fs::initial_path() << endl;
+ fs::path ip = fs::initial_path();
+ do_the_right_thing_tests(); // compile-only tests, but call anyhow to suppress warnings
+
+ for (fs::path::const_iterator it = ip.begin(); it != ip.end(); ++it)
+ {
+ if (it != ip.begin())
+ cout << ", ";
+ cout << *it;
+ }
+ cout << endl;
+
+ dir = fs::initial_path() / temp_dir;
+
+ if (fs::exists(dir))
+ {
+ cout << "remove residue from prior failed tests..." << endl;
+ fs::remove_all(dir);
+ }
+ BOOST_TEST(!fs::exists(dir));
+
+ // several functions give unreasonable results if uintmax_t isn't 64-bits
+ cout << "sizeof(boost::uintmax_t) = " << sizeof(boost::uintmax_t) << '\n';
+ BOOST_TEST(sizeof(boost::uintmax_t) >= 8);
+
+ initial_tests();
+ predicate_and_status_tests();
+ exception_tests();
+ create_directory_tests();
+ current_directory_tests();
+ space_tests();
+
+ // create a directory tree that can be used by subsequent tests
+ //
+ // dir
+ // d1
+ // d1f1 // an empty file
+ // f0 // an empty file
+ // f1 // a file containing "file f1"
+ //
+ create_tree();
+
+ status_of_nonexistent_tests();
+ status_error_reporting_tests();
+ directory_iterator_tests();
+ create_directories_tests(); // must run AFTER directory_iterator_tests
+
+ bad_create_directory_path = f1;
+ BOOST_TEST(CHECK_EXCEPTION(bad_create_directory, EEXIST));
+ fs::file_status stat = fs::status(f1);
+ BOOST_TEST(fs::status_known(stat));
+ BOOST_TEST(fs::exists(stat));
+ BOOST_TEST(!fs::is_directory(stat));
+ BOOST_TEST(fs::is_regular_file(stat));
+ BOOST_TEST(!fs::is_other(stat));
+ BOOST_TEST(!fs::is_symlink(stat));
+
+ equivalent_tests(f1);
+ create_hard_link_tests();
+ create_symlink_tests();
+ resize_file_tests();
+ absolute_tests();
+ canonical_basic_tests();
+ weakly_canonical_basic_tests();
+ permissions_tests();
+ copy_file_tests(f1, d1);
+ if (create_symlink_ok) // only if symlinks supported
+ {
+ symlink_status_tests();
+ copy_symlink_tests(f1, d1);
+ canonical_symlink_tests();
+ weakly_canonical_symlink_tests();
+ }
+ iterator_status_tests(); // lots of cases by now, so a good time to test
+ // dump_tree(dir);
+ recursive_directory_iterator_tests();
+ recursive_iterator_status_tests(); // lots of cases by now, so a good time to test
+ rename_tests();
+ remove_tests(dir);
+ remove_all_tests(dir);
+ if (create_symlink_ok) // only if symlinks supported
+ {
+ remove_symlink_tests();
+ remove_all_symlink_tests(dir);
+ }
+ creation_time_tests(dir);
+ write_time_tests(dir);
+ temp_directory_path_tests();
+
+ platform_specific_tests(); // do these last since they take a lot of time on Windows,
+ // and that's a pain during manual testing
+
+ cout << "testing complete" << endl;
+
+ // post-test cleanup
+ if (cleanup)
+ {
+ cout << "post-test removal of " << dir << endl;
+ BOOST_TEST(fs::remove_all(dir) != 0);
+ // above was added just to simplify testing, but it ended up detecting
+ // a bug (failure to close an internal search handle).
+ cout << "post-test removal complete" << endl;
+ // BOOST_TEST(!fs::exists(dir)); // nice test, but doesn't play well with TortoiseGit cache
+ }
+
+ cout << "returning from main()" << endl;
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/operations_unit_test.cpp b/src/boost/libs/filesystem/test/operations_unit_test.cpp
new file mode 100644
index 000000000..1e94e6622
--- /dev/null
+++ b/src/boost/libs/filesystem/test/operations_unit_test.cpp
@@ -0,0 +1,380 @@
+// operations_unit_test.cpp ----------------------------------------------------------//
+
+// Copyright Beman Dawes 2008, 2009, 2015
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+// ------------------------------------------------------------------------------------//
+
+// This program is misnamed - it is really a smoke test rather than a unit test
+
+// ------------------------------------------------------------------------------------//
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#endif
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem.hpp> // make sure filesystem.hpp works
+
+#include <boost/system/error_code.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+#include <iostream>
+
+using namespace boost::filesystem;
+using namespace boost::system;
+using std::cout;
+using std::endl;
+using std::string;
+
+#define CHECK(x) check(x, __FILE__, __LINE__)
+
+namespace {
+bool cleanup = true;
+
+void check(bool ok, const char* file, int line)
+{
+ if (ok)
+ return;
+
+ ++::boost::detail::test_errors();
+
+ cout << file << '(' << line << "): test failed\n";
+}
+
+// file_status_test ----------------------------------------------------------------//
+
+void file_status_test()
+{
+ cout << "file_status test..." << endl;
+
+ file_status s = status(".");
+ int v = s.permissions();
+ cout << " status(\".\") permissions are "
+ << std::oct << (v & 0777) << std::dec << endl;
+ CHECK((v & 0400) == 0400);
+
+ s = symlink_status(".");
+ v = s.permissions();
+ cout << " symlink_status(\".\") permissions are "
+ << std::oct << (v & 0777) << std::dec << endl;
+ CHECK((v & 0400) == 0400);
+}
+
+// query_test ----------------------------------------------------------------------//
+
+void query_test()
+{
+ cout << "query test..." << endl;
+
+ error_code ec;
+
+ CHECK(file_size("no-such-file", ec) == static_cast< boost::uintmax_t >(-1));
+ CHECK(ec == errc::no_such_file_or_directory);
+
+ CHECK(status("no-such-file") == file_status(file_not_found, no_perms));
+
+ CHECK(exists("/"));
+ CHECK(is_directory("/"));
+ CHECK(!exists("no-such-file"));
+
+ exists("/", ec);
+ if (ec)
+ {
+ cout << "exists(\"/\", ec) resulted in non-zero ec.value()" << endl;
+ cout << "ec value: " << ec.value() << ", message: " << ec.message() << endl;
+ }
+ CHECK(!ec);
+
+ CHECK(exists("/"));
+ CHECK(is_directory("/"));
+ CHECK(!is_regular_file("/"));
+ CHECK(!boost::filesystem::is_empty("/"));
+ CHECK(!is_other("/"));
+}
+
+// directory_iterator_test -----------------------------------------------//
+
+void directory_iterator_test()
+{
+ cout << "directory_iterator_test..." << endl;
+
+ directory_iterator end;
+
+ directory_iterator it(".");
+
+ CHECK(!it->path().empty());
+
+ if (is_regular_file(it->status()))
+ {
+ CHECK(is_regular_file(it->symlink_status()));
+ CHECK(!is_directory(it->status()));
+ CHECK(!is_symlink(it->status()));
+ CHECK(!is_directory(it->symlink_status()));
+ CHECK(!is_symlink(it->symlink_status()));
+ }
+ else
+ {
+ CHECK(is_directory(it->status()));
+ CHECK(is_directory(it->symlink_status()));
+ CHECK(!is_regular_file(it->status()));
+ CHECK(!is_regular_file(it->symlink_status()));
+ CHECK(!is_symlink(it->status()));
+ CHECK(!is_symlink(it->symlink_status()));
+ }
+
+ for (; it != end; ++it)
+ {
+ //cout << " " << it->path() << "\n";
+ }
+
+ CHECK(directory_iterator(".") != directory_iterator());
+ CHECK(directory_iterator() == end);
+
+#ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
+ for (directory_entry& x : directory_iterator("."))
+ {
+ CHECK(!x.path().empty());
+ //cout << " " << x.path() << "\n";
+ }
+ const directory_iterator dir_itr(".");
+ for (directory_entry& x : dir_itr)
+ {
+ CHECK(!x.path().empty());
+ //cout << " " << x.path() << "\n";
+ }
+#endif
+
+ for (directory_iterator itr("."); itr != directory_iterator(); ++itr)
+ {
+ CHECK(!itr->path().empty());
+ //cout << " " << itr->path() << "\n";
+ }
+
+ cout << "directory_iterator_test complete" << endl;
+}
+
+// recursive_directory_iterator_test -----------------------------------------------//
+
+void recursive_directory_iterator_test()
+{
+ cout << "recursive_directory_iterator_test..." << endl;
+
+ recursive_directory_iterator end;
+
+ recursive_directory_iterator it(".");
+
+ CHECK(!it->path().empty());
+
+ if (is_regular_file(it->status()))
+ {
+ CHECK(is_regular_file(it->symlink_status()));
+ CHECK(!is_directory(it->status()));
+ CHECK(!is_symlink(it->status()));
+ CHECK(!is_directory(it->symlink_status()));
+ CHECK(!is_symlink(it->symlink_status()));
+ }
+ else
+ {
+ CHECK(is_directory(it->status()));
+ CHECK(is_directory(it->symlink_status()));
+ CHECK(!is_regular_file(it->status()));
+ CHECK(!is_regular_file(it->symlink_status()));
+ CHECK(!is_symlink(it->status()));
+ CHECK(!is_symlink(it->symlink_status()));
+ }
+
+ for (; it != end; ++it)
+ {
+ //cout << " " << it->path() << "\n";
+ }
+
+ CHECK(recursive_directory_iterator(".") != recursive_directory_iterator());
+ CHECK(recursive_directory_iterator() == end);
+
+#ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
+ for (directory_entry& x : recursive_directory_iterator("."))
+ {
+ CHECK(!x.path().empty());
+ //cout << " " << x.path() << "\n";
+ }
+ const recursive_directory_iterator dir_itr(".");
+ for (directory_entry& x : dir_itr)
+ {
+ CHECK(!x.path().empty());
+ //cout << " " << x.path() << "\n";
+ }
+#endif
+
+ for (recursive_directory_iterator itr(".");
+ itr != recursive_directory_iterator(); ++itr)
+ {
+ CHECK(!itr->path().empty());
+ //cout << " " << itr->path() << "\n";
+ }
+
+ cout << "recursive_directory_iterator_test complete" << endl;
+}
+
+// operations_test -------------------------------------------------------//
+
+void operations_test()
+{
+ cout << "operations test..." << endl;
+
+ error_code ec;
+
+ CHECK(!create_directory("/", ec));
+
+ CHECK(!boost::filesystem::remove("no-such-file-or-directory"));
+ CHECK(!remove_all("no-such-file-or-directory"));
+
+ space_info info = space("/");
+
+ CHECK(info.available <= info.capacity);
+
+ CHECK(equivalent("/", "/"));
+ CHECK(!equivalent("/", "."));
+
+ std::time_t ft = last_write_time(".");
+ ft = -1;
+ last_write_time(".", ft, ec);
+}
+
+// directory_entry_test ------------------------------------------------------------//
+
+void directory_entry_test()
+{
+ cout << "directory_entry test..." << endl;
+
+ directory_entry de("foo.bar", file_status(regular_file, owner_all), file_status(directory_file, group_all));
+
+ CHECK(de.path() == "foo.bar");
+ CHECK(de.status() == file_status(regular_file, owner_all));
+ CHECK(de.symlink_status() == file_status(directory_file, group_all));
+ CHECK(de < directory_entry("goo.bar"));
+ CHECK(de == directory_entry("foo.bar"));
+ CHECK(de != directory_entry("goo.bar"));
+ de.replace_filename("bar.foo");
+ CHECK(de.path() == "bar.foo");
+}
+
+// directory_entry_overload_test ---------------------------------------------------//
+
+void directory_entry_overload_test()
+{
+ cout << "directory_entry overload test..." << endl;
+
+ directory_iterator it(".");
+ path p(*it);
+}
+
+// error_handling_test -------------------------------------------------------------//
+
+void error_handling_test()
+{
+ cout << "error handling test..." << endl;
+
+ bool threw(false);
+ try
+ {
+ file_size("no-such-file");
+ }
+ catch (const boost::filesystem::filesystem_error& ex)
+ {
+ threw = true;
+ cout << "\nas expected, attempt to get size of non-existent file threw a filesystem_error\n"
+ "what() returns "
+ << ex.what() << "\n";
+ }
+ catch (...)
+ {
+ cout << "\nunexpected exception type caught" << endl;
+ }
+
+ CHECK(threw);
+
+ error_code ec;
+ CHECK(!create_directory("/", ec));
+}
+
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+// //
+// main //
+// //
+//--------------------------------------------------------------------------------------//
+
+int cpp_main(int argc, char* argv[])
+{
+// document state of critical macros
+#ifdef BOOST_POSIX_API
+ cout << "BOOST_POSIX_API is defined\n";
+#endif
+#ifdef BOOST_WINDOWS_API
+ cout << "BOOST_WINDOWS_API is defined\n";
+#endif
+ cout << "BOOST_FILESYSTEM_DECL" << BOOST_STRINGIZE(=BOOST_FILESYSTEM_DECL) << "\n";
+ cout << "BOOST_SYMBOL_VISIBLE" << BOOST_STRINGIZE(=BOOST_SYMBOL_VISIBLE) << "\n";
+
+ cout << "current_path() is " << current_path().string() << endl;
+
+ if (argc >= 2)
+ {
+ cout << "argv[1] is '" << argv[1] << "', changing current_path() to it" << endl;
+
+ error_code ec;
+ current_path(argv[1], ec);
+
+ if (ec)
+ {
+ cout << "current_path('" << argv[1] << "') failed: " << ec << ": " << ec.message() << endl;
+ }
+
+ cout << "current_path() is " << current_path().string() << endl;
+ }
+
+ const path temp_dir(current_path() / ".." / unique_path("op-unit_test-%%%%-%%%%-%%%%"));
+ cout << "temp_dir is " << temp_dir.string() << endl;
+
+ create_directory(temp_dir);
+
+ file_status_test();
+ query_test();
+ directory_iterator_test();
+ recursive_directory_iterator_test();
+ operations_test();
+ directory_entry_test();
+ directory_entry_overload_test();
+ error_handling_test();
+
+ cout << unique_path() << endl;
+ cout << unique_path("foo-%%%%%-%%%%%-bar") << endl;
+ cout << unique_path("foo-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%-bar") << endl;
+ cout << unique_path("foo-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-bar") << endl;
+
+ cout << "testing complete" << endl;
+
+ // post-test cleanup
+ if (cleanup)
+ {
+ cout << "post-test removal of " << temp_dir << endl;
+ BOOST_TEST(remove_all(temp_dir) != 0);
+ // above was added just to simplify testing, but it ended up detecting
+ // a bug (failure to close an internal search handle).
+ cout << "post-test removal complete" << endl;
+ // BOOST_TEST(!fs::exists(dir)); // nice test, but doesn't play well with TortoiseGit cache
+ }
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/path_test.cpp b/src/boost/libs/filesystem/test/path_test.cpp
new file mode 100644
index 000000000..727329814
--- /dev/null
+++ b/src/boost/libs/filesystem/test/path_test.cpp
@@ -0,0 +1,2667 @@
+// path_test program -----------------------------------------------------------------//
+
+// Copyright Beman Dawes 2002, 2008
+// Copyright Vladimir Prus 2002
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+// basic_path's stem(), extension(), and replace_extension() tests are based
+// on basename(), extension(), and change_extension() tests from the original
+// convenience_test.cpp by Vladimir Prus.
+
+//--------------------------------------------------------------------------------------//
+// //
+// Caution //
+// //
+// The class path relational operators (==, !=, <, etc.) on Windows treat slash and //
+// backslash as equal. Thus any tests on Windows where the difference between slash //
+// and backslash is significant should compare strings rather than paths. //
+// //
+// BOOST_TEST(path == path) // '\\' and '/' are equal //
+// BOOST_TEST(path == convertable to string) // '\\' and '/' are equal //
+// PATH_TEST_EQ(path, path) // '\\' and '/' are equal //
+// //
+// BOOST_TEST(path.string() == path.string()) // '\\' and '/' are not equal //
+// BOOST_TEST(path.string() == //
+// convertable to string) // '\\' and '/' are not equal //
+// PATH_TEST_EQ(path.string(), //
+// convertable to string) // '\\' and '/' are not equal //
+// //
+// The last of these is often what is needed, so the PATH_TEST_EQ macro is provided. //
+// It converts its first argument to a path, and then performs a .string() on it, //
+// eliminating much boilerplate .string() or even path(...).string() code. //
+// //
+// PATH_TEST_EQ(path, convertable to string) // '\\' and '/' are not equal //
+// //
+//--------------------------------------------------------------------------------------//
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#endif
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/exception.hpp>
+
+#include <boost/next_prior.hpp>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <cstring>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/detail/lightweight_main.hpp>
+
+namespace fs = boost::filesystem;
+using boost::filesystem::path;
+using boost::next;
+using boost::prior;
+
+#ifdef BOOST_WINDOWS_API
+#define BOOST_DIR_SEP "\\"
+#else
+#define BOOST_DIR_SEP "/"
+#endif
+
+#if BOOST_FILESYSTEM_VERSION == 3
+#define BOOST_FILESYSTEM_V3_TRAILING_DOT "."
+#else
+#define BOOST_FILESYSTEM_V3_TRAILING_DOT ""
+#endif
+
+#define PATH_TEST_EQ(a, b) check(a, b, __FILE__, __LINE__)
+
+namespace {
+
+class derived_from_path :
+ public fs::path
+{
+public:
+ derived_from_path() {}
+ derived_from_path(derived_from_path const& that) : fs::path(static_cast< fs::path const& >(that)) {}
+ template< typename T >
+ derived_from_path(T const& that) : fs::path(that) {}
+
+ derived_from_path& operator= (derived_from_path const& that)
+ {
+ *static_cast< fs::path* >(this) = that;
+ return *this;
+ }
+ template< typename T >
+ derived_from_path& operator= (T const& that)
+ {
+ *static_cast< fs::path* >(this) = that;
+ return *this;
+ }
+};
+
+class convertible_to_path
+{
+private:
+ fs::path m_path;
+
+public:
+ convertible_to_path() {}
+ convertible_to_path(convertible_to_path const& that) : m_path(that.m_path) {}
+ template< typename T >
+ convertible_to_path(T const& that) : m_path(that) {}
+
+ convertible_to_path& operator= (convertible_to_path const& that)
+ {
+ m_path = that.m_path;
+ return *this;
+ }
+ template< typename T >
+ convertible_to_path& operator= (T const& that)
+ {
+ m_path = that;
+ return *this;
+ }
+
+ operator fs::path() const { return m_path; }
+};
+
+
+std::string platform(BOOST_PLATFORM);
+
+void check(const fs::path& source, const std::string& expected, const char* file, int line)
+{
+ if (source.string() == expected)
+ return;
+
+ std::cout << file
+ << '(' << line << "): source: \"" << source.string()
+ << "\" != expected: \"" << expected
+ << "\"" << std::endl;
+
+ ++::boost::detail::test_errors();
+}
+
+path p1("fe/fi/fo/fum");
+path p2(p1);
+path p3;
+path p4("foobar");
+path p5;
+
+// exception_tests -----------------------------------------------------------------//
+
+void exception_tests()
+{
+ std::cout << "exception_tests..." << std::endl;
+ const std::string str_1("string-1");
+ boost::system::error_code ec(12345, boost::system::system_category());
+ try
+ {
+ throw fs::filesystem_error(str_1, ec);
+ }
+ catch (const fs::filesystem_error& ex)
+ {
+ //std::cout << ex.what() << "*" << std::endl;
+ //BOOST_TEST(std::strcmp(ex.what(),
+ // "string-1: Unknown error") == 0);
+ BOOST_TEST(ex.code() == ec);
+ }
+
+ try
+ {
+ throw fs::filesystem_error(str_1, "p1", "p2", ec);
+ }
+ catch (const fs::filesystem_error& ex)
+ {
+ //std::cout << ex.what() << "*" << std::endl;
+ //BOOST_TEST(std::strcmp(ex.what(),
+ // "string-1: Unknown error: \"p1\", \"p2\"") == 0);
+ BOOST_TEST(ex.code() == ec);
+ BOOST_TEST(ex.path1() == "p1");
+ BOOST_TEST(ex.path2() == "p2");
+ }
+}
+
+// overload_tests ------------------------------------------------------------------//
+
+// These verify various overloads don't cause compiler errors
+// They pre-date operations_unit_test.cpp
+
+void overload_tests()
+{
+ std::cout << "overload_tests..." << std::endl;
+
+ fs::exists(p1);
+ fs::exists("foo");
+ fs::exists(std::string("foo"));
+
+ fs::exists(p1 / path("foo"));
+ fs::exists(p1 / "foo");
+ fs::exists(p1 / std::string("foo"));
+
+ fs::exists("foo" / p1);
+ fs::exists(std::string("foo") / p1);
+
+ p4 /= path("foo");
+ p4 /= "foo";
+ p4 /= std::string("foo");
+}
+
+// iterator_tests ------------------------------------------------------------------//
+
+void iterator_tests()
+{
+ std::cout << "iterator_tests..." << std::endl;
+
+ path itr_ck = "";
+ path::const_iterator itr = itr_ck.begin();
+ BOOST_TEST(itr == itr_ck.end());
+
+ itr_ck = "/";
+ itr = itr_ck.begin();
+ BOOST_TEST(itr->string() == "/");
+ BOOST_TEST(++itr == itr_ck.end());
+ BOOST_TEST((--itr)->string() == "/");
+
+ itr_ck = "foo";
+ BOOST_TEST(*itr_ck.begin() == std::string("foo"));
+ BOOST_TEST(boost::next(itr_ck.begin()) == itr_ck.end());
+ BOOST_TEST(*boost::prior(itr_ck.end()) == std::string("foo"));
+ BOOST_TEST(boost::prior(itr_ck.end()) == itr_ck.begin());
+
+ itr_ck = path("/foo");
+ BOOST_TEST((itr_ck.begin())->string() == "/");
+ BOOST_TEST(*boost::next(itr_ck.begin()) == std::string("foo"));
+ BOOST_TEST(boost::next(boost::next(itr_ck.begin())) == itr_ck.end());
+ BOOST_TEST(boost::next(itr_ck.begin()) == boost::prior(itr_ck.end()));
+ BOOST_TEST(*boost::prior(itr_ck.end()) == std::string("foo"));
+ BOOST_TEST(*boost::prior(boost::prior(itr_ck.end())) == std::string("/"));
+ BOOST_TEST(boost::prior(boost::prior(itr_ck.end())) == itr_ck.begin());
+
+ itr_ck = "/foo/bar";
+ itr = itr_ck.begin();
+ path::const_iterator itr_begin = itr;
+ BOOST_TEST(itr->string() == "/");
+ BOOST_TEST(*++itr == std::string("foo"));
+ BOOST_TEST(*++itr == std::string("bar"));
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, "bar");
+ PATH_TEST_EQ(*--itr, "foo");
+ PATH_TEST_EQ(*--itr, "/");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "../f"; // previously failed due to short name bug
+ itr_begin = itr = itr_ck.begin();
+ PATH_TEST_EQ(itr->string(), "..");
+ PATH_TEST_EQ(*++itr, "f");
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, "f");
+ PATH_TEST_EQ(*--itr, "..");
+ BOOST_TEST(itr == itr_begin);
+
+ // POSIX says treat "/foo/bar/" as "/foo/bar/."
+ itr_ck = "/foo/bar/";
+ itr_begin = itr = itr_ck.begin();
+ PATH_TEST_EQ(itr->string(), "/");
+ PATH_TEST_EQ(*++itr, "foo");
+ BOOST_TEST(itr != itr_ck.end());
+ PATH_TEST_EQ(*++itr, "bar");
+ BOOST_TEST(itr != itr_ck.end());
+ PATH_TEST_EQ(*++itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ BOOST_TEST(itr != itr_ck.end()); // verify the . isn't also seen as end()
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(*--itr, "bar");
+ PATH_TEST_EQ(*--itr, "foo");
+ PATH_TEST_EQ(*--itr, "/");
+ BOOST_TEST(itr == itr_begin);
+
+ // POSIX says treat "/f/b/" as "/f/b/."
+ itr_ck = "/f/b/";
+ itr_begin = itr = itr_ck.begin();
+ PATH_TEST_EQ(itr->string(), "/");
+ PATH_TEST_EQ(*++itr, "f");
+ PATH_TEST_EQ(*++itr, "b");
+ PATH_TEST_EQ(*++itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ BOOST_TEST(itr != itr_ck.end()); // verify the . isn't also seen as end()
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(*--itr, "b");
+ PATH_TEST_EQ(*--itr, "f");
+ PATH_TEST_EQ(*--itr, "/");
+ BOOST_TEST(itr == itr_begin);
+
+ // POSIX says treat "a/b/" as "a/b/."
+ // Although similar to the prior test case, this failed the ". isn't end" test due to
+ // a bug while the prior case did not fail.
+ itr_ck = "a/b/";
+ itr_begin = itr = itr_ck.begin();
+ PATH_TEST_EQ(*itr, "a");
+ PATH_TEST_EQ(*++itr, "b");
+ PATH_TEST_EQ(*++itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ BOOST_TEST(itr != itr_ck.end()); // verify the . isn't also seen as end()
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(*--itr, "b");
+ PATH_TEST_EQ(*--itr, "a");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "//net";
+ itr_begin = itr = itr_ck.begin();
+ // two leading slashes are permitted by POSIX (as implementation defined),
+ // while for Windows it is always well defined (as a network name)
+ PATH_TEST_EQ(itr->string(), "//net");
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, "//net");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "//net/";
+ itr_begin = itr = itr_ck.begin();
+ PATH_TEST_EQ(itr->string(), "//net");
+ PATH_TEST_EQ(*++itr, "/");
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, "/");
+ PATH_TEST_EQ(*--itr, "//net");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "//foo///bar///";
+ itr_begin = itr = itr_ck.begin();
+ PATH_TEST_EQ(itr->string(), "//foo");
+ PATH_TEST_EQ(*++itr, "/");
+ PATH_TEST_EQ(*++itr, "bar");
+ PATH_TEST_EQ(*++itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(*--itr, "bar");
+ PATH_TEST_EQ(*--itr, "/");
+ PATH_TEST_EQ(*--itr, "//foo");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "///foo///bar///";
+ itr_begin = itr = itr_ck.begin();
+ // three or more leading slashes are to be treated as a single slash
+ PATH_TEST_EQ(itr->string(), "/");
+ PATH_TEST_EQ(*++itr, "foo");
+ PATH_TEST_EQ(*++itr, "bar");
+ PATH_TEST_EQ(*++itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(*--itr, "bar");
+ PATH_TEST_EQ(*--itr, "foo");
+ PATH_TEST_EQ(*--itr, "/");
+ BOOST_TEST(itr == itr_begin);
+
+ if (platform == "Windows")
+ {
+ itr_ck = "c:/";
+ itr_begin = itr = itr_ck.begin();
+ PATH_TEST_EQ(itr->string(), "c:");
+ PATH_TEST_EQ(*++itr, std::string("/"));
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, "/");
+ PATH_TEST_EQ(*--itr, "c:");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "c:\\";
+ itr_begin = itr = itr_ck.begin();
+ PATH_TEST_EQ(itr->string(), "c:");
+ PATH_TEST_EQ(*++itr, "/"); // test that iteration returns generic format
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, "/"); // test that iteration returns generic format
+ PATH_TEST_EQ(*--itr, "c:");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "c:/foo";
+ itr_begin = itr = itr_ck.begin();
+ PATH_TEST_EQ(*itr, "c:");
+ PATH_TEST_EQ(*++itr, "/");
+ PATH_TEST_EQ(*++itr, "foo");
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, "foo");
+ PATH_TEST_EQ(*--itr, "/");
+ PATH_TEST_EQ(*--itr, "c:");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "c:\\foo";
+ itr_begin = itr = itr_ck.begin();
+ BOOST_TEST_EQ(*itr, "c:");
+ BOOST_TEST_EQ(*++itr, "\\");
+ BOOST_TEST_EQ(*++itr, "foo");
+ BOOST_TEST(++itr == itr_ck.end());
+ BOOST_TEST_EQ(*--itr, "foo");
+ BOOST_TEST_EQ(*--itr, "\\");
+ BOOST_TEST_EQ(*--itr, "c:");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "\\\\?\\c:\\foo";
+ itr_begin = itr = itr_ck.begin();
+ BOOST_TEST_EQ(*itr, "\\\\?\\c:");
+ BOOST_TEST_EQ(*++itr, "\\");
+ BOOST_TEST_EQ(*++itr, "foo");
+ BOOST_TEST(++itr == itr_ck.end());
+ BOOST_TEST_EQ(*--itr, "foo");
+ BOOST_TEST_EQ(*--itr, "\\");
+ BOOST_TEST_EQ(*--itr, "\\\\?\\c:");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "\\\\.\\c:\\foo";
+ itr_begin = itr = itr_ck.begin();
+ BOOST_TEST_EQ(*itr, "\\\\.\\c:");
+ BOOST_TEST_EQ(*++itr, "\\");
+ BOOST_TEST_EQ(*++itr, "foo");
+ BOOST_TEST(++itr == itr_ck.end());
+ BOOST_TEST_EQ(*--itr, "foo");
+ BOOST_TEST_EQ(*--itr, "\\");
+ BOOST_TEST_EQ(*--itr, "\\\\.\\c:");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "\\??\\c:\\foo";
+ itr_begin = itr = itr_ck.begin();
+ BOOST_TEST_EQ(*itr, "\\??\\c:");
+ BOOST_TEST_EQ(*++itr, "\\");
+ BOOST_TEST_EQ(*++itr, "foo");
+ BOOST_TEST(++itr == itr_ck.end());
+ BOOST_TEST_EQ(*--itr, "foo");
+ BOOST_TEST_EQ(*--itr, "\\");
+ BOOST_TEST_EQ(*--itr, "\\??\\c:");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "\\\\\\foo\\\\\\bar\\\\\\";
+ itr_begin = itr = itr_ck.begin();
+ // three or more leading slashes are to be treated as a single slash
+ PATH_TEST_EQ(itr->string(), "/");
+ PATH_TEST_EQ(*++itr, "foo");
+ PATH_TEST_EQ(*++itr, "bar");
+ PATH_TEST_EQ(*++itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ BOOST_TEST(++itr == itr_ck.end());
+ PATH_TEST_EQ(*--itr, BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(*--itr, "bar");
+ PATH_TEST_EQ(*--itr, "foo");
+ PATH_TEST_EQ(*--itr, "/");
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "c:foo";
+ itr_begin = itr = itr_ck.begin();
+ BOOST_TEST(*itr == std::string("c:"));
+ BOOST_TEST(*++itr == std::string("foo"));
+ BOOST_TEST(++itr == itr_ck.end());
+ BOOST_TEST(*--itr == std::string("foo"));
+ BOOST_TEST(*--itr == std::string("c:"));
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = "c:foo/";
+ itr_begin = itr = itr_ck.begin();
+ BOOST_TEST(*itr == std::string("c:"));
+ BOOST_TEST(*++itr == std::string("foo"));
+ BOOST_TEST(*++itr == std::string(BOOST_FILESYSTEM_V3_TRAILING_DOT));
+ BOOST_TEST(++itr == itr_ck.end());
+ BOOST_TEST(*--itr == std::string(BOOST_FILESYSTEM_V3_TRAILING_DOT));
+ BOOST_TEST(*--itr == std::string("foo"));
+ BOOST_TEST(*--itr == std::string("c:"));
+ BOOST_TEST(itr == itr_begin);
+
+ itr_ck = path("c:");
+ BOOST_TEST(*itr_ck.begin() == std::string("c:"));
+ BOOST_TEST(next(itr_ck.begin()) == itr_ck.end());
+ BOOST_TEST(prior(itr_ck.end()) == itr_ck.begin());
+ BOOST_TEST(*prior(itr_ck.end()) == std::string("c:"));
+
+ itr_ck = path("c:/");
+ BOOST_TEST(*itr_ck.begin() == std::string("c:"));
+ BOOST_TEST(*next(itr_ck.begin()) == std::string("/"));
+ BOOST_TEST(next(next(itr_ck.begin())) == itr_ck.end());
+ BOOST_TEST(prior(prior(itr_ck.end())) == itr_ck.begin());
+ BOOST_TEST(*prior(itr_ck.end()) == std::string("/"));
+ BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("c:"));
+
+ itr_ck = path("c:foo");
+ BOOST_TEST(*itr_ck.begin() == std::string("c:"));
+ BOOST_TEST(*next(itr_ck.begin()) == std::string("foo"));
+ BOOST_TEST(next(next(itr_ck.begin())) == itr_ck.end());
+ BOOST_TEST(prior(prior(itr_ck.end())) == itr_ck.begin());
+ BOOST_TEST(*prior(itr_ck.end()) == std::string("foo"));
+ BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("c:"));
+
+ itr_ck = path("c:/foo");
+ BOOST_TEST(*itr_ck.begin() == std::string("c:"));
+ BOOST_TEST(*next(itr_ck.begin()) == std::string("/"));
+ BOOST_TEST(*next(next(itr_ck.begin())) == std::string("foo"));
+ BOOST_TEST(next(next(next(itr_ck.begin()))) == itr_ck.end());
+ BOOST_TEST(prior(prior(prior(itr_ck.end()))) == itr_ck.begin());
+ BOOST_TEST(*prior(itr_ck.end()) == std::string("foo"));
+ BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("/"));
+ BOOST_TEST(*prior(prior(prior(itr_ck.end()))) == std::string("c:"));
+
+ itr_ck = path("//net");
+ BOOST_TEST(*itr_ck.begin() == std::string("//net"));
+ BOOST_TEST(next(itr_ck.begin()) == itr_ck.end());
+ BOOST_TEST(prior(itr_ck.end()) == itr_ck.begin());
+ BOOST_TEST(*prior(itr_ck.end()) == std::string("//net"));
+
+ itr_ck = path("//net/");
+ PATH_TEST_EQ(itr_ck.begin()->string(), "//net");
+ PATH_TEST_EQ(next(itr_ck.begin())->string(), "/");
+ BOOST_TEST(next(next(itr_ck.begin())) == itr_ck.end());
+ BOOST_TEST(prior(prior(itr_ck.end())) == itr_ck.begin());
+ PATH_TEST_EQ(prior(itr_ck.end())->string(), "/");
+ PATH_TEST_EQ(prior(prior(itr_ck.end()))->string(), "//net");
+
+ itr_ck = path("//net/foo");
+ BOOST_TEST(*itr_ck.begin() == std::string("//net"));
+ BOOST_TEST(*next(itr_ck.begin()) == std::string("/"));
+ BOOST_TEST(*next(next(itr_ck.begin())) == std::string("foo"));
+ BOOST_TEST(next(next(next(itr_ck.begin()))) == itr_ck.end());
+ BOOST_TEST(prior(prior(prior(itr_ck.end()))) == itr_ck.begin());
+ BOOST_TEST(*prior(itr_ck.end()) == std::string("foo"));
+ BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("/"));
+ BOOST_TEST(*prior(prior(prior(itr_ck.end()))) == std::string("//net"));
+
+ itr_ck = path("prn:");
+ BOOST_TEST(*itr_ck.begin() == std::string("prn:"));
+ BOOST_TEST(next(itr_ck.begin()) == itr_ck.end());
+ BOOST_TEST(prior(itr_ck.end()) == itr_ck.begin());
+ BOOST_TEST(*prior(itr_ck.end()) == std::string("prn:"));
+ }
+ else
+ {
+ itr_ck = "///";
+ itr = itr_ck.begin();
+ PATH_TEST_EQ(itr->string(), "/");
+ BOOST_TEST(++itr == itr_ck.end());
+ }
+}
+
+// non_member_tests ----------------------------------------------------------------//
+
+void non_member_tests()
+{
+ std::cout << "non_member_tests..." << std::endl;
+
+ // test non-member functions, particularly operator overloads
+
+ path e, e2;
+ std::string es, es2;
+ char ecs[] = "";
+ char ecs2[] = "";
+
+ char acs[] = "a";
+ std::string as(acs);
+ path a(as);
+
+ char acs2[] = "a";
+ std::string as2(acs2);
+ path a2(as2);
+
+ char bcs[] = "b";
+ std::string bs(bcs);
+ path b(bs);
+
+ // swap
+ a.swap(b);
+ BOOST_TEST(a.string() == "b");
+ BOOST_TEST(b.string() == "a");
+ fs::swap(a, b);
+ BOOST_TEST(a.string() == "a");
+ BOOST_TEST(b.string() == "b");
+
+ // probe operator /
+ PATH_TEST_EQ(path("") / ".", ".");
+ PATH_TEST_EQ(path("") / "..", "..");
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("/") / "/", "//");
+ PATH_TEST_EQ(path("/") / "/foo", "//foo");
+ PATH_TEST_EQ(path("/foo") / "/bar", "/foo/bar");
+#else
+ PATH_TEST_EQ(path("/") / "/", "/");
+ PATH_TEST_EQ(path("/") / "/foo", "/foo");
+ PATH_TEST_EQ(path("/foo") / "/bar", "/bar");
+#endif
+
+ if (platform == "Windows")
+ {
+ BOOST_TEST(path("foo\\bar") == "foo/bar");
+ BOOST_TEST((b / a).native() == path("b\\a").native());
+ BOOST_TEST((bs / a).native() == path("b\\a").native());
+ BOOST_TEST((bcs / a).native() == path("b\\a").native());
+ BOOST_TEST((b / as).native() == path("b\\a").native());
+ BOOST_TEST((b / acs).native() == path("b\\a").native());
+ PATH_TEST_EQ(path("a") / "b", "a\\b");
+ PATH_TEST_EQ(path("foo") / path("bar"), "foo\\bar"); // path arg
+ PATH_TEST_EQ(path("foo") / "bar", "foo\\bar"); // const char* arg
+ PATH_TEST_EQ(path("foo") / path("woo/bar").filename(), "foo\\bar"); // const std::string & arg
+ PATH_TEST_EQ("foo" / path("bar"), "foo\\bar");
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("..") / "", "..");
+#else
+ PATH_TEST_EQ(path("..") / "", "..\\");
+#endif
+ PATH_TEST_EQ(path("..") / "..", "..\\..");
+ PATH_TEST_EQ(path("/") / "..", "/..");
+ PATH_TEST_EQ(path("/..") / "..", "/..\\..");
+ PATH_TEST_EQ(path("..") / "foo", "..\\foo");
+ PATH_TEST_EQ(path("foo") / "..", "foo\\..");
+ PATH_TEST_EQ(path("..") / "f", "..\\f");
+ PATH_TEST_EQ(path("/..") / "f", "/..\\f");
+ PATH_TEST_EQ(path("f") / "..", "f\\..");
+ PATH_TEST_EQ(path("foo") / ".." / "..", "foo\\..\\..");
+ PATH_TEST_EQ(path("foo") / ".." / ".." / "..", "foo\\..\\..\\..");
+ PATH_TEST_EQ(path("f") / ".." / "b", "f\\..\\b");
+ PATH_TEST_EQ(path("foo") / ".." / "bar", "foo\\..\\bar");
+ PATH_TEST_EQ(path("foo") / "bar" / "..", "foo\\bar\\..");
+ PATH_TEST_EQ(path("foo") / "bar" / ".." / "..", "foo\\bar\\..\\..");
+ PATH_TEST_EQ(path("foo") / "bar" / ".." / "blah", "foo\\bar\\..\\blah");
+ PATH_TEST_EQ(path("f") / "b" / "..", "f\\b\\..");
+ PATH_TEST_EQ(path("f") / "b" / ".." / "a", "f\\b\\..\\a");
+ PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / "..", "foo\\bar\\blah\\..\\..");
+ PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo\\bar\\blah\\..\\..\\bletch");
+
+ PATH_TEST_EQ(path(".") / "foo", ".\\foo");
+ PATH_TEST_EQ(path(".") / "..", ".\\..");
+ PATH_TEST_EQ(path("foo") / ".", "foo\\.");
+ PATH_TEST_EQ(path("..") / ".", "..\\.");
+ PATH_TEST_EQ(path(".") / ".", ".\\.");
+ PATH_TEST_EQ(path(".") / "." / ".", ".\\.\\.");
+ PATH_TEST_EQ(path(".") / "foo" / ".", ".\\foo\\.");
+ PATH_TEST_EQ(path("foo") / "." / "bar", "foo\\.\\bar");
+ PATH_TEST_EQ(path("foo") / "." / ".", "foo\\.\\.");
+ PATH_TEST_EQ(path("foo") / "." / "..", "foo\\.\\..");
+ PATH_TEST_EQ(path(".") / "." / "..", ".\\.\\..");
+ PATH_TEST_EQ(path(".") / ".." / ".", ".\\..\\.");
+ PATH_TEST_EQ(path("..") / "." / ".", "..\\.\\.");
+
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("\\\\net1\\foo") / "\\\\net2\\bar", "\\\\net1\\foo\\\\net2\\bar");
+ PATH_TEST_EQ(path("\\\\net1\\foo") / "\\bar", "\\\\net1\\foo\\bar");
+ PATH_TEST_EQ(path("c:\\foo") / "d:\\bar", "c:\\foo\\d:\\bar");
+ PATH_TEST_EQ(path("c:\\foo") / "\\bar", "c:\\foo\\bar");
+ PATH_TEST_EQ(path("c:foo") / "\\bar", "c:foo\\bar");
+#else
+ PATH_TEST_EQ(path("\\\\net1\\foo") / "\\\\net2\\bar", "\\\\net2\\bar");
+ PATH_TEST_EQ(path("\\\\net1\\foo") / "\\bar", "\\\\net1\\bar");
+ PATH_TEST_EQ(path("c:\\foo") / "d:\\bar", "d:\\bar");
+ PATH_TEST_EQ(path("c:\\foo") / "\\bar", "c:\\bar");
+ PATH_TEST_EQ(path("c:foo") / "\\bar", "c:\\bar");
+#endif
+ PATH_TEST_EQ(path("c:foo") / "bar", "c:foo\\bar");
+ }
+ else // POSIX
+ {
+ PATH_TEST_EQ(b / a, "b/a");
+ PATH_TEST_EQ(bs / a, "b/a");
+ PATH_TEST_EQ(bcs / a, "b/a");
+ PATH_TEST_EQ(b / as, "b/a");
+ PATH_TEST_EQ(b / acs, "b/a");
+ PATH_TEST_EQ(path("a") / "b", "a/b");
+ PATH_TEST_EQ(path("") / "..", "..");
+ PATH_TEST_EQ(path("foo") / path("bar"), "foo/bar"); // path arg
+ PATH_TEST_EQ(path("foo") / "bar", "foo/bar"); // const char* arg
+ PATH_TEST_EQ(path("foo") / path("woo/bar").filename(), "foo/bar"); // const std::string & arg
+ PATH_TEST_EQ("foo" / path("bar"), "foo/bar");
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("..") / "", "..");
+#else
+ PATH_TEST_EQ(path("..") / "", "../");
+#endif
+ PATH_TEST_EQ(path("..") / "..", "../..");
+ PATH_TEST_EQ(path("/") / "..", "/..");
+ PATH_TEST_EQ(path("/..") / "..", "/../..");
+ PATH_TEST_EQ(path("..") / "foo", "../foo");
+ PATH_TEST_EQ(path("foo") / "..", "foo/..");
+ PATH_TEST_EQ(path("..") / "f", "../f");
+ PATH_TEST_EQ(path("/..") / "f", "/../f");
+ PATH_TEST_EQ(path("f") / "..", "f/..");
+ PATH_TEST_EQ(path("foo") / ".." / "..", "foo/../..");
+ PATH_TEST_EQ(path("foo") / ".." / ".." / "..", "foo/../../..");
+ PATH_TEST_EQ(path("f") / ".." / "b", "f/../b");
+ PATH_TEST_EQ(path("foo") / ".." / "bar", "foo/../bar");
+ PATH_TEST_EQ(path("foo") / "bar" / "..", "foo/bar/..");
+ PATH_TEST_EQ(path("foo") / "bar" / ".." / "..", "foo/bar/../..");
+ PATH_TEST_EQ(path("foo") / "bar" / ".." / "blah", "foo/bar/../blah");
+ PATH_TEST_EQ(path("f") / "b" / "..", "f/b/..");
+ PATH_TEST_EQ(path("f") / "b" / ".." / "a", "f/b/../a");
+ PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / "..", "foo/bar/blah/../..");
+ PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo/bar/blah/../../bletch");
+
+ PATH_TEST_EQ(path(".") / "foo", "./foo");
+ PATH_TEST_EQ(path(".") / "..", "./..");
+ PATH_TEST_EQ(path("foo") / ".", "foo/.");
+ PATH_TEST_EQ(path("..") / ".", "../.");
+ PATH_TEST_EQ(path(".") / ".", "./.");
+ PATH_TEST_EQ(path(".") / "." / ".", "././.");
+ PATH_TEST_EQ(path(".") / "foo" / ".", "./foo/.");
+ PATH_TEST_EQ(path("foo") / "." / "bar", "foo/./bar");
+ PATH_TEST_EQ(path("foo") / "." / ".", "foo/./.");
+ PATH_TEST_EQ(path("foo") / "." / "..", "foo/./..");
+ PATH_TEST_EQ(path(".") / "." / "..", "././..");
+ PATH_TEST_EQ(path(".") / ".." / ".", "./../.");
+ PATH_TEST_EQ(path("..") / "." / ".", ".././.");
+
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("//net1/foo") / "//net2/bar", "//net1/foo//net2/bar");
+ PATH_TEST_EQ(path("//net1/foo") / "/bar", "//net1/foo/bar");
+#else
+ PATH_TEST_EQ(path("//net1/foo") / "//net2/bar", "//net2/bar");
+ PATH_TEST_EQ(path("//net1/foo") / "/bar", "/bar");
+#endif
+ PATH_TEST_EQ(path("//net1/foo") / "bar", "//net1/foo/bar");
+ }
+
+ // probe operator <
+ BOOST_TEST(!(e < e2));
+ BOOST_TEST(!(es < e2));
+ BOOST_TEST(!(ecs < e2));
+ BOOST_TEST(!(e < es2));
+ BOOST_TEST(!(e < ecs2));
+
+ BOOST_TEST(e < a);
+ BOOST_TEST(es < a);
+ BOOST_TEST(ecs < a);
+ BOOST_TEST(e < as);
+ BOOST_TEST(e < acs);
+
+ BOOST_TEST(a < b);
+ BOOST_TEST(as < b);
+ BOOST_TEST(acs < b);
+ BOOST_TEST(a < bs);
+ BOOST_TEST(a < bcs);
+
+ BOOST_TEST(!(a < a2));
+ BOOST_TEST(!(as < a2));
+ BOOST_TEST(!(acs < a2));
+ BOOST_TEST(!(a < as2));
+ BOOST_TEST(!(a < acs2));
+
+ // make sure basic_path overloads don't conflict with std::string overloads
+
+ BOOST_TEST(!(as < as));
+ BOOST_TEST(!(as < acs));
+ BOOST_TEST(!(acs < as));
+
+ // character set reality check before lexicographical tests
+ BOOST_TEST(std::string("a.b") < std::string("a/b"));
+ // verify compare is actually lexicographical
+ BOOST_TEST(path("a/b") < path("a.b"));
+ BOOST_TEST(path("a/b") == path("a///b"));
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(path("a/b/") == path("a/b/."));
+#else
+ BOOST_TEST(path("a/b/") != path("a/b/."));
+#endif
+ BOOST_TEST(path("a/b") != path("a/b/"));
+
+ // make sure the derivative operators also work
+
+ BOOST_TEST(b > a);
+ BOOST_TEST(b > as);
+ BOOST_TEST(b > acs);
+ BOOST_TEST(bs > a);
+ BOOST_TEST(bcs > a);
+
+ BOOST_TEST(!(a2 > a));
+ BOOST_TEST(!(a2 > as));
+ BOOST_TEST(!(a2 > acs));
+ BOOST_TEST(!(as2 > a));
+ BOOST_TEST(!(acs2 > a));
+
+ BOOST_TEST(a <= b);
+ BOOST_TEST(as <= b);
+ BOOST_TEST(acs <= b);
+ BOOST_TEST(a <= bs);
+ BOOST_TEST(a <= bcs);
+
+ BOOST_TEST(a <= a2);
+ BOOST_TEST(as <= a2);
+ BOOST_TEST(acs <= a2);
+ BOOST_TEST(a <= as2);
+ BOOST_TEST(a <= acs2);
+
+ BOOST_TEST(b >= a);
+ BOOST_TEST(bs >= a);
+ BOOST_TEST(bcs >= a);
+ BOOST_TEST(b >= as);
+ BOOST_TEST(b >= acs);
+
+ BOOST_TEST(a2 >= a);
+ BOOST_TEST(as2 >= a);
+ BOOST_TEST(acs2 >= a);
+ BOOST_TEST(a2 >= as);
+ BOOST_TEST(a2 >= acs);
+
+ // operator == and != are implemented separately, so test separately
+
+ path p101("fe/fi/fo/fum");
+ path p102(p101);
+ path p103("fe/fi/fo/fumm");
+ BOOST_TEST(p101.string() != p103.string());
+
+ // check each overload
+ BOOST_TEST(p101 != p103);
+ BOOST_TEST(p101 != p103.string());
+ BOOST_TEST(p101 != p103.string().c_str());
+ BOOST_TEST(p101.string() != p103);
+ BOOST_TEST(p101.string().c_str() != p103);
+
+ p103 = p102;
+ BOOST_TEST(p101.string() == p103.string());
+
+ // check each overload
+ BOOST_TEST(p101 == p103);
+ BOOST_TEST(p101 == p103.string());
+ BOOST_TEST(p101 == p103.string().c_str());
+ BOOST_TEST(p101.string() == p103);
+ BOOST_TEST(p101.string().c_str() == p103);
+
+ if (platform == "Windows")
+ {
+ std::cout << " Windows relational tests..." << std::endl;
+ path p10("c:\\file");
+ path p11("c:/file");
+ // check each overload
+ BOOST_TEST(p10.generic_string() == p11.generic_string());
+ BOOST_TEST(p10 == p11);
+ BOOST_TEST(p10 == p11.string());
+ BOOST_TEST(p10 == p11.string().c_str());
+ BOOST_TEST(p10.string() == p11);
+ BOOST_TEST(p10.string().c_str() == p11);
+ BOOST_TEST(p10 == L"c:\\file");
+ BOOST_TEST(p10 == L"c:/file");
+ BOOST_TEST(p11 == L"c:\\file");
+ BOOST_TEST(p11 == L"c:/file");
+ BOOST_TEST(L"c:\\file" == p10);
+ BOOST_TEST(L"c:/file" == p10);
+ BOOST_TEST(L"c:\\file" == p11);
+ BOOST_TEST(L"c:/file" == p11);
+
+ BOOST_TEST(!(p10.generic_string() != p11.generic_string()));
+ BOOST_TEST(!(p10 != p11));
+ BOOST_TEST(!(p10 != p11.string()));
+ BOOST_TEST(!(p10 != p11.string().c_str()));
+ BOOST_TEST(!(p10.string() != p11));
+ BOOST_TEST(!(p10.string().c_str() != p11));
+ BOOST_TEST(!(p10 != L"c:\\file"));
+ BOOST_TEST(!(p10 != L"c:/file"));
+ BOOST_TEST(!(p11 != L"c:\\file"));
+ BOOST_TEST(!(p11 != L"c:/file"));
+ BOOST_TEST(!(L"c:\\file" != p10));
+ BOOST_TEST(!(L"c:/file" != p10));
+ BOOST_TEST(!(L"c:\\file" != p11));
+ BOOST_TEST(!(L"c:/file" != p11));
+
+ BOOST_TEST(!(p10.string() < p11.string()));
+ BOOST_TEST(!(p10 < p11));
+ BOOST_TEST(!(p10 < p11.string()));
+ BOOST_TEST(!(p10 < p11.string().c_str()));
+ BOOST_TEST(!(p10.string() < p11));
+ BOOST_TEST(!(p10.string().c_str() < p11));
+ BOOST_TEST(!(p10 < L"c:\\file"));
+ BOOST_TEST(!(p10 < L"c:/file"));
+ BOOST_TEST(!(p11 < L"c:\\file"));
+ BOOST_TEST(!(p11 < L"c:/file"));
+ BOOST_TEST(!(L"c:\\file" < p10));
+ BOOST_TEST(!(L"c:/file" < p10));
+ BOOST_TEST(!(L"c:\\file" < p11));
+ BOOST_TEST(!(L"c:/file" < p11));
+
+ BOOST_TEST(!(p10.generic_string() > p11.generic_string()));
+ BOOST_TEST(!(p10 > p11));
+ BOOST_TEST(!(p10 > p11.string()));
+ BOOST_TEST(!(p10 > p11.string().c_str()));
+ BOOST_TEST(!(p10.string() > p11));
+ BOOST_TEST(!(p10.string().c_str() > p11));
+ BOOST_TEST(!(p10 > L"c:\\file"));
+ BOOST_TEST(!(p10 > L"c:/file"));
+ BOOST_TEST(!(p11 > L"c:\\file"));
+ BOOST_TEST(!(p11 > L"c:/file"));
+ BOOST_TEST(!(L"c:\\file" > p10));
+ BOOST_TEST(!(L"c:/file" > p10));
+ BOOST_TEST(!(L"c:\\file" > p11));
+ BOOST_TEST(!(L"c:/file" > p11));
+ }
+
+ // relative
+
+ BOOST_TEST(fs::relative("/abc/def", "/abc") == path("def"));
+ BOOST_TEST(fs::relative("abc/def", "abc") == path("def"));
+ BOOST_TEST(fs::relative("/abc/xyz/def", "/abc") == path("xyz/def"));
+ BOOST_TEST(fs::relative("abc/xyz/def", "abc") == path("xyz/def"));
+
+ if (platform == "Windows")
+ {
+ std::cout << " Windows relatie tests..." << std::endl;
+ BOOST_TEST(fs::relative("\\abc\\xyz\\def", "/abc") == path("xyz/def"));
+ std::cout << " fs::relative(\"/abc/xyz/def\", \"/abc\") is "
+ << fs::relative("/abc/xyz/def", "/abc") << std::endl;
+ BOOST_TEST(fs::relative("abc\\xyz\\def", "abc") == path("xyz/def"));
+ }
+}
+
+// query_and_decomposition_tests ---------------------------------------------------//
+//
+// remove_filename() is also tested here, because its specification depends on
+// a decomposition function.
+
+void query_and_decomposition_tests()
+{
+ std::cout << "query_and_decomposition_tests..." << std::endl;
+
+ // these are the examples given in reference docs, so check they work
+ BOOST_TEST(path("/foo/bar.txt").parent_path() == "/foo");
+ BOOST_TEST(path("/foo/bar").parent_path() == "/foo");
+ BOOST_TEST(path("/foo/bar/").parent_path() == "/foo/bar");
+ BOOST_TEST(path("/").parent_path() == "");
+ BOOST_TEST(path(".").parent_path() == "");
+ BOOST_TEST(path("..").parent_path() == "");
+ BOOST_TEST(path("/foo/bar.txt").filename() == "bar.txt");
+ BOOST_TEST(path("/foo/bar").filename() == "bar");
+ BOOST_TEST(path("/foo/bar/").filename() == BOOST_FILESYSTEM_V3_TRAILING_DOT);
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(path("/").filename() == "/");
+#else
+ BOOST_TEST(path("/").filename() == "");
+#endif
+ BOOST_TEST(path(".").filename() == ".");
+ BOOST_TEST(path("..").filename() == "..");
+
+ // stem() tests not otherwise covered
+ BOOST_TEST(path(".").stem() == ".");
+ BOOST_TEST(path("..").stem() == "..");
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(path(".a").stem() == "");
+#else
+ BOOST_TEST(path(".a").stem() == ".a");
+#endif
+ BOOST_TEST(path("b").stem() == "b");
+ BOOST_TEST(path("a/b.txt").stem() == "b");
+ BOOST_TEST(path("a/b.").stem() == "b");
+ BOOST_TEST(path("a.b.c").stem() == "a.b");
+ BOOST_TEST(path("a.b.c.").stem() == "a.b.c");
+
+ // extension() tests not otherwise covered
+ BOOST_TEST(path(".").extension() == "");
+ BOOST_TEST(path("..").extension() == "");
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(path(".a").extension() == ".a");
+#else
+ BOOST_TEST(path(".a").extension() == "");
+#endif
+ BOOST_TEST(path("a/b").extension() == "");
+ BOOST_TEST(path("a.b/c").extension() == "");
+ BOOST_TEST(path("a/b.txt").extension() == ".txt");
+ BOOST_TEST(path("a/b.").extension() == ".");
+ BOOST_TEST(path("a.b.c").extension() == ".c");
+ BOOST_TEST(path("a.b.c.").extension() == ".");
+ BOOST_TEST(path("a/").extension() == "");
+
+ // main q & d test sequence
+ path p;
+ path q;
+
+ p = q = "";
+ BOOST_TEST(p.relative_path().string() == "");
+ BOOST_TEST(p.parent_path().string() == "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ BOOST_TEST(p.filename() == "");
+ BOOST_TEST(p.stem() == "");
+ BOOST_TEST(p.extension() == "");
+ BOOST_TEST(p.root_name() == "");
+ BOOST_TEST(p.root_directory() == "");
+ BOOST_TEST(p.root_path().string() == "");
+ BOOST_TEST(!p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+ BOOST_TEST(!p.has_filename());
+ BOOST_TEST(!p.has_stem());
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "/";
+ BOOST_TEST(p.relative_path().string() == "");
+ BOOST_TEST(p.parent_path().string() == "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.filename() == "/");
+ BOOST_TEST(p.stem() == "/");
+#else
+ BOOST_TEST(p.filename() == "");
+ BOOST_TEST(p.stem() == "");
+#endif
+ BOOST_TEST(p.extension() == "");
+ BOOST_TEST(p.root_name() == "");
+ BOOST_TEST(p.root_directory() == "/");
+ BOOST_TEST(p.root_path().string() == "/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+#else
+ BOOST_TEST(!p.has_filename());
+ BOOST_TEST(!p.has_stem());
+#endif
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(!p.has_parent_path());
+ if (platform == "POSIX")
+ BOOST_TEST(p.is_absolute());
+ else
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "//";
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "//");
+ PATH_TEST_EQ(p.stem(), "//");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+ PATH_TEST_EQ(p.stem(), "");
+#endif
+ PATH_TEST_EQ(p.extension(), "");
+ PATH_TEST_EQ(p.root_name(), "//");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "//");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+#else
+ BOOST_TEST(!p.has_filename());
+ BOOST_TEST(!p.has_stem());
+#endif
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "///";
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "/");
+ PATH_TEST_EQ(p.stem(), "/");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+ PATH_TEST_EQ(p.stem(), "");
+#endif
+ PATH_TEST_EQ(p.extension(), "");
+ PATH_TEST_EQ(p.root_name(), "");
+ PATH_TEST_EQ(p.root_directory(), "/");
+ PATH_TEST_EQ(p.root_path().string(), "/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+#else
+ BOOST_TEST(!p.has_filename());
+ BOOST_TEST(!p.has_stem());
+#endif
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(!p.has_parent_path());
+ if (platform == "POSIX")
+ BOOST_TEST(p.is_absolute());
+ else
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = ".";
+ BOOST_TEST(p.relative_path().string() == ".");
+ BOOST_TEST(p.parent_path().string() == "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ BOOST_TEST(p.filename() == ".");
+ BOOST_TEST(p.stem() == ".");
+ BOOST_TEST(p.extension() == "");
+ BOOST_TEST(p.root_name() == "");
+ BOOST_TEST(p.root_directory() == "");
+ BOOST_TEST(p.root_path().string() == "");
+ BOOST_TEST(!p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "..";
+ BOOST_TEST(p.relative_path().string() == "..");
+ BOOST_TEST(p.parent_path().string() == "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ BOOST_TEST(p.filename() == "..");
+ BOOST_TEST(p.stem() == "..");
+ BOOST_TEST(p.extension() == "");
+ BOOST_TEST(p.root_name() == "");
+ BOOST_TEST(p.root_directory() == "");
+ BOOST_TEST(p.root_path().string() == "");
+ BOOST_TEST(!p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "foo";
+ BOOST_TEST(p.relative_path().string() == "foo");
+ BOOST_TEST(p.parent_path().string() == "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ BOOST_TEST(p.filename() == "foo");
+ BOOST_TEST(p.stem() == "foo");
+ BOOST_TEST(p.extension() == "");
+ BOOST_TEST(p.root_name() == "");
+ BOOST_TEST(p.root_directory() == "");
+ BOOST_TEST(p.root_path().string() == "");
+ BOOST_TEST(!p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "/foo";
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "/");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.stem(), "foo");
+ PATH_TEST_EQ(p.extension(), "");
+ PATH_TEST_EQ(p.root_name(), "");
+ PATH_TEST_EQ(p.root_directory(), "/");
+ PATH_TEST_EQ(p.root_path().string(), "/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(p.has_parent_path());
+ if (platform == "POSIX")
+ BOOST_TEST(p.is_absolute());
+ else
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "/foo/";
+ PATH_TEST_EQ(p.relative_path().string(), "foo/");
+ PATH_TEST_EQ(p.parent_path().string(), "/foo");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(p.stem(), BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(p.extension(), "");
+ PATH_TEST_EQ(p.root_name(), "");
+ PATH_TEST_EQ(p.root_directory(), "/");
+ PATH_TEST_EQ(p.root_path().string(), "/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+#else
+ BOOST_TEST(!p.has_filename());
+ BOOST_TEST(!p.has_stem());
+#endif
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(p.has_parent_path());
+ if (platform == "POSIX")
+ BOOST_TEST(p.is_absolute());
+ else
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "///foo";
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "/");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "");
+ PATH_TEST_EQ(p.root_directory(), "/");
+ PATH_TEST_EQ(p.root_path().string(), "/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ if (platform == "POSIX")
+ BOOST_TEST(p.is_absolute());
+ else
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "foo/bar";
+ BOOST_TEST(p.relative_path().string() == "foo/bar");
+ BOOST_TEST(p.parent_path().string() == "foo");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ BOOST_TEST(p.filename() == "bar");
+ BOOST_TEST(p.stem() == "bar");
+ BOOST_TEST(p.extension() == "");
+ BOOST_TEST(p.root_name() == "");
+ BOOST_TEST(p.root_directory() == "");
+ BOOST_TEST(p.root_path().string() == "");
+ BOOST_TEST(!p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "../foo";
+ BOOST_TEST(p.relative_path().string() == "../foo");
+ BOOST_TEST(p.parent_path().string() == "..");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ BOOST_TEST(p.filename() == "foo");
+ BOOST_TEST(p.root_name() == "");
+ BOOST_TEST(p.root_directory() == "");
+ BOOST_TEST(p.root_path().string() == "");
+ BOOST_TEST(!p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "..///foo";
+ PATH_TEST_EQ(p.relative_path().string(), "..///foo");
+ PATH_TEST_EQ(p.parent_path().string(), "..");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "");
+ BOOST_TEST(!p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = "/foo/bar";
+ BOOST_TEST(p.relative_path().string() == "foo/bar");
+ BOOST_TEST(p.parent_path().string() == "/foo");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ BOOST_TEST(p.filename() == "bar");
+ BOOST_TEST(p.root_name() == "");
+ BOOST_TEST(p.root_directory() == "/");
+ BOOST_TEST(p.root_path().string() == "/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(!p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ if (platform == "POSIX")
+ BOOST_TEST(p.is_absolute());
+ else
+ BOOST_TEST(!p.is_absolute());
+
+ // Both POSIX and Windows allow two leading slashs
+ // (POSIX meaning is implementation defined)
+ PATH_TEST_EQ(path("//resource"), "//resource");
+ PATH_TEST_EQ(path("//resource/"), "//resource/");
+ PATH_TEST_EQ(path("//resource/foo"), "//resource/foo");
+
+ p = q = path("//net");
+ PATH_TEST_EQ(p.string(), "//net");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.parent_path().string(), "");
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "//net");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "//net");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "//net");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("//net/");
+ BOOST_TEST(p.relative_path().string() == "");
+ BOOST_TEST(p.parent_path().string() == "//net");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.filename() == "/");
+#else
+ BOOST_TEST(p.filename() == "");
+#endif
+ BOOST_TEST(p.root_name() == "//net");
+ BOOST_TEST(p.root_directory() == "/");
+ BOOST_TEST(p.root_path().string() == "//net/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("//net/foo");
+ BOOST_TEST(p.relative_path().string() == "foo");
+ BOOST_TEST(p.parent_path().string() == "//net/");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ BOOST_TEST(p.filename() == "foo");
+ BOOST_TEST(p.root_name() == "//net");
+ BOOST_TEST(p.root_directory() == "/");
+ BOOST_TEST(p.root_path().string() == "//net/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("//net///foo");
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "//net/");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "//net");
+ PATH_TEST_EQ(p.root_directory(), "/");
+ PATH_TEST_EQ(p.root_path().string(), "//net/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ // ticket 2739, infinite recursion leading to stack overflow, was caused
+ // by failure to handle this case correctly on Windows.
+ p = path(":");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(p.filename(), ":");
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(p.has_filename());
+
+
+ // Windows specific tests
+ if (platform == "Windows")
+ {
+ p = q = path("\\\\?\\");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "\\\\?\\");
+ PATH_TEST_EQ(p.stem(), "\\\\?\\");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+ PATH_TEST_EQ(p.stem(), "");
+#endif
+ PATH_TEST_EQ(p.extension(), "");
+ PATH_TEST_EQ(p.root_name(), "\\\\?\\");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\?\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+#else
+ BOOST_TEST(!p.has_filename());
+ BOOST_TEST(!p.has_stem());
+#endif
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("\\\\.\\");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "\\\\.\\");
+ PATH_TEST_EQ(p.stem(), "\\\\");
+ PATH_TEST_EQ(p.extension(), ".\\");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+ PATH_TEST_EQ(p.stem(), "");
+ PATH_TEST_EQ(p.extension(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "\\\\.\\");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\.\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+ BOOST_TEST(p.has_extension());
+#else
+ BOOST_TEST(!p.has_filename());
+ BOOST_TEST(!p.has_stem());
+ BOOST_TEST(!p.has_extension());
+#endif
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("\\??\\");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "\\??\\");
+ PATH_TEST_EQ(p.stem(), "\\??\\");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+ PATH_TEST_EQ(p.stem(), "");
+#endif
+ PATH_TEST_EQ(p.extension(), "");
+ PATH_TEST_EQ(p.root_name(), "\\??\\");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "\\??\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_stem());
+#else
+ BOOST_TEST(!p.has_filename());
+ BOOST_TEST(!p.has_stem());
+#endif
+ BOOST_TEST(!p.has_extension());
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("c:");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "c:");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "c:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "c:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("\\\\?\\c:");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "\\\\?\\c:");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "\\\\?\\c:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\?\\c:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("\\\\.\\c:");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "\\\\.\\c:");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "\\\\.\\c:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\.\\c:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("\\??\\c:");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "\\??\\c:");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "\\??\\c:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "\\??\\c:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("c:foo");
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "c:");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "c:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "c:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("\\\\?\\c:foo");
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "\\\\?\\c:");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "\\\\?\\c:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\?\\c:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("\\\\.\\c:foo");
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "\\\\.\\c:");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "\\\\.\\c:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\.\\c:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("\\??\\c:foo");
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "\\??\\c:");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "\\??\\c:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "\\??\\c:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("c:/");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "c:");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "/");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "c:");
+ PATH_TEST_EQ(p.root_directory(), "/");
+ PATH_TEST_EQ(p.root_path().string(), "c:/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("\\\\?\\c:\\");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "\\\\?\\c:");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "\\");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "\\\\?\\c:");
+ PATH_TEST_EQ(p.root_directory(), "\\");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\?\\c:\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("\\\\.\\c:\\");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "\\\\.\\c:");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "\\");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "\\\\.\\c:");
+ PATH_TEST_EQ(p.root_directory(), "\\");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\.\\c:\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("\\??\\c:\\");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "\\??\\c:");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "\\");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "\\??\\c:");
+ PATH_TEST_EQ(p.root_directory(), "\\");
+ PATH_TEST_EQ(p.root_path().string(), "\\??\\c:\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("c:..");
+ PATH_TEST_EQ(p.relative_path().string(), "..");
+ PATH_TEST_EQ(p.parent_path().string(), "c:");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "..");
+ PATH_TEST_EQ(p.root_name(), "c:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "c:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("c:/foo");
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "c:/");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "c:");
+ PATH_TEST_EQ(p.root_directory(), "/");
+ PATH_TEST_EQ(p.root_path().string(), "c:/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("c://foo");
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "c:/");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "c:");
+ PATH_TEST_EQ(p.root_directory(), "/");
+ PATH_TEST_EQ(p.root_path().string(), "c:/");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("c:\\foo\\bar");
+ PATH_TEST_EQ(p.relative_path().string(), "foo\\bar");
+ PATH_TEST_EQ(p.parent_path().string(), "c:\\foo");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "bar");
+ PATH_TEST_EQ(p.root_name(), "c:");
+ PATH_TEST_EQ(p.root_directory(), "\\");
+ PATH_TEST_EQ(p.root_path().string(), "c:\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("\\\\?\\c:\\foo\\bar");
+ PATH_TEST_EQ(p.relative_path().string(), "foo\\bar");
+ PATH_TEST_EQ(p.parent_path().string(), "\\\\?\\c:\\foo");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "bar");
+ PATH_TEST_EQ(p.root_name(), "\\\\?\\c:");
+ PATH_TEST_EQ(p.root_directory(), "\\");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\?\\c:\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("\\\\.\\c:\\foo\\bar");
+ PATH_TEST_EQ(p.relative_path().string(), "foo\\bar");
+ PATH_TEST_EQ(p.parent_path().string(), "\\\\.\\c:\\foo");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "bar");
+ PATH_TEST_EQ(p.root_name(), "\\\\.\\c:");
+ PATH_TEST_EQ(p.root_directory(), "\\");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\.\\c:\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("\\??\\c:\\foo\\bar");
+ PATH_TEST_EQ(p.relative_path().string(), "foo\\bar");
+ PATH_TEST_EQ(p.parent_path().string(), "\\??\\c:\\foo");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "bar");
+ PATH_TEST_EQ(p.root_name(), "\\??\\c:");
+ PATH_TEST_EQ(p.root_directory(), "\\");
+ PATH_TEST_EQ(p.root_path().string(), "\\??\\c:\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+
+ p = q = path("prn:");
+ PATH_TEST_EQ(p.relative_path().string(), "");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(p.filename(), "prn:");
+#else
+ PATH_TEST_EQ(p.filename(), "");
+#endif
+ PATH_TEST_EQ(p.root_name(), "prn:");
+ PATH_TEST_EQ(p.root_directory(), "");
+ PATH_TEST_EQ(p.root_path().string(), "prn:");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(!p.has_root_directory());
+ BOOST_TEST(!p.has_relative_path());
+#if BOOST_FILESYSTEM_VERSION == 3
+ BOOST_TEST(p.has_filename());
+#else
+ BOOST_TEST(!p.has_filename());
+#endif
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(!p.is_absolute());
+
+ p = q = path("\\\\net\\\\\\foo");
+ PATH_TEST_EQ(p.relative_path().string(), "foo");
+ PATH_TEST_EQ(p.parent_path().string(), "\\\\net\\");
+ PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
+ PATH_TEST_EQ(p.filename(), "foo");
+ PATH_TEST_EQ(p.root_name(), "\\\\net");
+ PATH_TEST_EQ(p.root_directory(), "\\");
+ PATH_TEST_EQ(p.root_path().string(), "\\\\net\\");
+ BOOST_TEST(p.has_root_path());
+ BOOST_TEST(p.has_root_name());
+ BOOST_TEST(p.has_root_directory());
+ BOOST_TEST(p.has_relative_path());
+ BOOST_TEST(p.has_filename());
+ BOOST_TEST(p.has_parent_path());
+ BOOST_TEST(p.is_absolute());
+ } // Windows
+
+ else
+ { // POSIX
+ p = path("c:");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(p.filename(), "c:");
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(p.has_filename());
+
+ p = path("cc:");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(p.filename(), "cc:");
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(p.has_filename());
+
+ PATH_TEST_EQ(path("/foo/bar/"), "/foo/bar/");
+ PATH_TEST_EQ(path("//foo//bar//"), "//foo//bar//");
+ PATH_TEST_EQ(path("///foo///bar///"), "///foo///bar///");
+
+ p = path("/usr/local/bin:/usr/bin:/bin");
+ BOOST_TEST(p.string() == "/usr/local/bin:/usr/bin:/bin");
+ } // POSIX
+}
+
+// composition_tests ----------------------------------------------------------------//
+
+void composition_tests()
+{
+ std::cout << "composition_tests..." << std::endl;
+}
+
+// construction_tests ---------------------------------------------------------------//
+
+void construction_tests()
+{
+ std::cout << "construction_tests..." << std::endl;
+
+ PATH_TEST_EQ("", "");
+
+ PATH_TEST_EQ("foo", "foo");
+ PATH_TEST_EQ("f", "f");
+
+ PATH_TEST_EQ("foo/", "foo/");
+ PATH_TEST_EQ("f/", "f/");
+ PATH_TEST_EQ("foo/..", "foo/..");
+ PATH_TEST_EQ("foo/../", "foo/../");
+ PATH_TEST_EQ("foo/bar/../..", "foo/bar/../..");
+ PATH_TEST_EQ("foo/bar/../../", "foo/bar/../../");
+ PATH_TEST_EQ("/", "/");
+ PATH_TEST_EQ("/f", "/f");
+
+ PATH_TEST_EQ("/foo", "/foo");
+ PATH_TEST_EQ("/foo/bar/", "/foo/bar/");
+ PATH_TEST_EQ("//foo//bar//", "//foo//bar//");
+ PATH_TEST_EQ("///foo///bar///", "///foo///bar///");
+ PATH_TEST_EQ("\\/foo\\/bar\\/", "\\/foo\\/bar\\/");
+ PATH_TEST_EQ("\\//foo\\//bar\\//", "\\//foo\\//bar\\//");
+
+ if (platform == "Windows")
+ {
+ PATH_TEST_EQ(path("c:") / "foo", "c:foo");
+ PATH_TEST_EQ(path("c:") / "/foo", "c:/foo");
+
+ PATH_TEST_EQ("\\foo\\bar\\", "\\foo\\bar\\");
+ PATH_TEST_EQ("\\\\foo\\\\bar\\\\", "\\\\foo\\\\bar\\\\");
+ PATH_TEST_EQ("\\\\\\foo\\\\\\bar\\\\\\", "\\\\\\foo\\\\\\bar\\\\\\");
+
+ PATH_TEST_EQ("\\", "\\");
+ PATH_TEST_EQ("\\f", "\\f");
+ PATH_TEST_EQ("\\foo", "\\foo");
+ PATH_TEST_EQ("foo\\bar", "foo\\bar");
+ PATH_TEST_EQ("foo bar", "foo bar");
+ PATH_TEST_EQ("c:", "c:");
+ PATH_TEST_EQ("c:/", "c:/");
+ PATH_TEST_EQ("c:.", "c:.");
+ PATH_TEST_EQ("c:./foo", "c:./foo");
+ PATH_TEST_EQ("c:.\\foo", "c:.\\foo");
+ PATH_TEST_EQ("c:..", "c:..");
+ PATH_TEST_EQ("c:/.", "c:/.");
+ PATH_TEST_EQ("c:/..", "c:/..");
+ PATH_TEST_EQ("c:/../", "c:/../");
+ PATH_TEST_EQ("c:\\..\\", "c:\\..\\");
+ PATH_TEST_EQ("c:/../..", "c:/../..");
+ PATH_TEST_EQ("c:/../foo", "c:/../foo");
+ PATH_TEST_EQ("c:\\..\\foo", "c:\\..\\foo");
+ PATH_TEST_EQ("c:../foo", "c:../foo");
+ PATH_TEST_EQ("c:..\\foo", "c:..\\foo");
+ PATH_TEST_EQ("c:/../../foo", "c:/../../foo");
+ PATH_TEST_EQ("c:\\..\\..\\foo", "c:\\..\\..\\foo");
+ PATH_TEST_EQ("c:foo/..", "c:foo/..");
+ PATH_TEST_EQ("c:/foo/..", "c:/foo/..");
+ PATH_TEST_EQ("c:/..foo", "c:/..foo");
+ PATH_TEST_EQ("c:foo", "c:foo");
+ PATH_TEST_EQ("c:/foo", "c:/foo");
+ PATH_TEST_EQ("\\\\netname", "\\\\netname");
+ PATH_TEST_EQ("\\\\netname\\", "\\\\netname\\");
+ PATH_TEST_EQ("\\\\netname\\foo", "\\\\netname\\foo");
+ PATH_TEST_EQ("c:/foo", "c:/foo");
+ PATH_TEST_EQ("prn:", "prn:");
+ }
+ else
+ {
+ }
+
+ PATH_TEST_EQ("foo/bar", "foo/bar");
+ PATH_TEST_EQ("a/b", "a/b"); // probe for length effects
+ PATH_TEST_EQ("..", "..");
+ PATH_TEST_EQ("../..", "../..");
+ PATH_TEST_EQ("/..", "/..");
+ PATH_TEST_EQ("/../..", "/../..");
+ PATH_TEST_EQ("../foo", "../foo");
+ PATH_TEST_EQ("foo/..", "foo/..");
+ PATH_TEST_EQ("foo/..bar", "foo/..bar");
+ PATH_TEST_EQ("../f", "../f");
+ PATH_TEST_EQ("/../f", "/../f");
+ PATH_TEST_EQ("f/..", "f/..");
+ PATH_TEST_EQ("foo/../..", "foo/../..");
+ PATH_TEST_EQ("foo/../../..", "foo/../../..");
+ PATH_TEST_EQ("foo/../bar", "foo/../bar");
+ PATH_TEST_EQ("foo/bar/..", "foo/bar/..");
+ PATH_TEST_EQ("foo/bar/../..", "foo/bar/../..");
+ PATH_TEST_EQ("foo/bar/../blah", "foo/bar/../blah");
+ PATH_TEST_EQ("f/../b", "f/../b");
+ PATH_TEST_EQ("f/b/..", "f/b/..");
+ PATH_TEST_EQ("f/b/../a", "f/b/../a");
+ PATH_TEST_EQ("foo/bar/blah/../..", "foo/bar/blah/../..");
+ PATH_TEST_EQ("foo/bar/blah/../../bletch", "foo/bar/blah/../../bletch");
+ PATH_TEST_EQ("...", "...");
+ PATH_TEST_EQ("....", "....");
+ PATH_TEST_EQ("foo/...", "foo/...");
+ PATH_TEST_EQ("abc.", "abc.");
+ PATH_TEST_EQ("abc..", "abc..");
+ PATH_TEST_EQ("foo/abc.", "foo/abc.");
+ PATH_TEST_EQ("foo/abc..", "foo/abc..");
+
+ PATH_TEST_EQ(".abc", ".abc");
+ PATH_TEST_EQ("a.c", "a.c");
+ PATH_TEST_EQ("..abc", "..abc");
+ PATH_TEST_EQ("a..c", "a..c");
+ PATH_TEST_EQ("foo/.abc", "foo/.abc");
+ PATH_TEST_EQ("foo/a.c", "foo/a.c");
+ PATH_TEST_EQ("foo/..abc", "foo/..abc");
+ PATH_TEST_EQ("foo/a..c", "foo/a..c");
+
+ PATH_TEST_EQ(".", ".");
+ PATH_TEST_EQ("./foo", "./foo");
+ PATH_TEST_EQ("./..", "./..");
+ PATH_TEST_EQ("./../foo", "./../foo");
+ PATH_TEST_EQ("foo/.", "foo/.");
+ PATH_TEST_EQ("../.", "../.");
+ PATH_TEST_EQ("./.", "./.");
+ PATH_TEST_EQ("././.", "././.");
+ PATH_TEST_EQ("./foo/.", "./foo/.");
+ PATH_TEST_EQ("foo/./bar", "foo/./bar");
+ PATH_TEST_EQ("foo/./.", "foo/./.");
+ PATH_TEST_EQ("foo/./..", "foo/./..");
+ PATH_TEST_EQ("foo/./../bar", "foo/./../bar");
+ PATH_TEST_EQ("foo/../.", "foo/../.");
+ PATH_TEST_EQ("././..", "././..");
+ PATH_TEST_EQ("./../.", "./../.");
+ PATH_TEST_EQ(".././.", ".././.");
+}
+
+// append_tests --------------------------------------------------------------------//
+
+#define APPEND_TEST(pth, appnd, expected)\
+ {\
+ const path p(pth);\
+ const std::string s(appnd);\
+ PATH_TEST_EQ(p / appnd, expected);\
+ PATH_TEST_EQ((p / path(s)).string(), expected);\
+ PATH_TEST_EQ((p / s.c_str()).string(), expected);\
+ PATH_TEST_EQ((p / s).string(), expected);\
+ path p1(p);\
+ p1 /= appnd;\
+ PATH_TEST_EQ(p1, expected);\
+ path p2(p);\
+ p2 /= derived_from_path(appnd);\
+ PATH_TEST_EQ(p2, expected);\
+ path p3(p);\
+ p3 /= convertible_to_path(appnd);\
+ PATH_TEST_EQ(p3, expected);\
+ path p4(p);\
+ p4.append(s.begin(), s.end());\
+ PATH_TEST_EQ(p4.string(), expected);\
+ }
+
+void append_tests()
+{
+ std::cout << "append_tests..." << std::endl;
+
+ // There are many control paths to be exercised, since empty paths and arguments,
+ // paths with trailing separators, arguments with leading separators, with or without
+ // other characters being present, are all separate cases that need to be tested.
+ // Furthermore, some of the code to be tested is specific to argument categories,
+ // so that results in further permutations to be tested.
+
+ //// code to generate test cases
+ ////
+ //// expected results must be checked by hand
+ //// "foo\bar" expected result must be edited by hand and moved for Windows/POSIX
+ ////
+ //const char* x[] = { "", "/", "foo", "foo/" };
+ //const char* y[] = { "", "/", "bar", "/bar" };
+
+ //for (int i = 0; i < sizeof(x)/sizeof(char*); ++i)
+ // for (int j = 0; j < sizeof(y)/sizeof(char*); ++j)
+ // {
+ // std::cout << " APPEND_TEST(\"" << x[i] << "\", \"" << y[j] << "\", \""
+ // << path(x[i]) / y[j] << "\");\n";
+ // }
+
+ APPEND_TEST("", "", "");
+ APPEND_TEST("", "/", "/");
+ APPEND_TEST("", "bar", "bar");
+ APPEND_TEST("", "/bar", "/bar");
+
+ APPEND_TEST("/", "", "/");
+#if BOOST_FILESYSTEM_VERSION == 3
+ APPEND_TEST("/", "/", "//");
+#else
+ APPEND_TEST("/", "/", "/");
+#endif
+ APPEND_TEST("/", "bar", "/bar");
+#if BOOST_FILESYSTEM_VERSION == 3
+ APPEND_TEST("/", "/bar", "//bar");
+#else
+ APPEND_TEST("/", "/bar", "/bar");
+#endif
+
+#if BOOST_FILESYSTEM_VERSION == 3
+ APPEND_TEST("foo", "/", "foo/");
+#else
+ APPEND_TEST("foo", "/", "/");
+#endif
+#if BOOST_FILESYSTEM_VERSION == 3
+ APPEND_TEST("foo", "/bar", "foo/bar");
+#else
+ APPEND_TEST("foo", "/bar", "/bar");
+#endif
+
+ APPEND_TEST("foo/", "", "foo/");
+#if BOOST_FILESYSTEM_VERSION == 3
+ APPEND_TEST("foo/", "/", "foo//");
+#else
+ APPEND_TEST("foo/", "/", "/");
+#endif
+ APPEND_TEST("foo/", "bar", "foo/bar");
+
+ if (platform == "Windows")
+ {
+#if BOOST_FILESYSTEM_VERSION == 3
+ APPEND_TEST("foo", "", "foo");
+#else
+ APPEND_TEST("foo", "", "foo\\");
+#endif
+ APPEND_TEST("foo", "bar", "foo\\bar");
+
+#if BOOST_FILESYSTEM_VERSION == 3
+ APPEND_TEST("foo\\", "\\bar", "foo\\\\bar");
+#else
+ APPEND_TEST("foo\\", "\\bar", "\\bar");
+#endif
+
+ // hand created test case specific to Windows
+ APPEND_TEST("c:", "bar", "c:bar");
+ }
+ else
+ {
+#if BOOST_FILESYSTEM_VERSION == 3
+ APPEND_TEST("foo", "", "foo");
+#else
+ APPEND_TEST("foo", "", "foo/");
+#endif
+ APPEND_TEST("foo", "bar", "foo/bar");
+ }
+
+ // ticket #6819
+ union
+ {
+ char a[1];
+ char b[3];
+ } u;
+
+ u.b[0] = 'a';
+ u.b[1] = 'b';
+ u.b[2] = '\0';
+
+ path p6819;
+ p6819 /= u.a;
+ BOOST_TEST_EQ(p6819, path("ab"));
+}
+
+// concat_tests --------------------------------------------------------------------//
+
+#define CONCAT_TEST(pth, appnd, expected)\
+ {\
+ const path p(pth);\
+ const std::string s(appnd);\
+ path p1(p);\
+ p1 += appnd;\
+ PATH_TEST_EQ(p1.string(), expected);\
+ path p2(p);\
+ p2 += path(appnd);\
+ PATH_TEST_EQ(p2.string(), expected);\
+ path p3(p);\
+ p3 += s;\
+ PATH_TEST_EQ(p3.string(), expected);\
+ path p4(p);\
+ p4 += s.c_str();\
+ PATH_TEST_EQ(p4.string(), expected);\
+ path p5(p);\
+ p5 += derived_from_path(appnd);\
+ PATH_TEST_EQ(p5, expected);\
+ path p6(p);\
+ p6 += convertible_to_path(appnd);\
+ PATH_TEST_EQ(p6, expected);\
+ path p7(p);\
+ p7.concat(s.begin(), s.end());\
+ PATH_TEST_EQ(p7.string(), expected);\
+ }
+
+void concat_tests()
+{
+ std::cout << "concat_tests..." << std::endl;
+
+ CONCAT_TEST("", "", "");
+ CONCAT_TEST("", "/", "/");
+ CONCAT_TEST("", "bar", "bar");
+ CONCAT_TEST("", "/bar", "/bar");
+
+ CONCAT_TEST("/", "", "/");
+ CONCAT_TEST("/", "/", "//");
+ CONCAT_TEST("/", "bar", "/bar");
+ CONCAT_TEST("/", "/bar", "//bar");
+
+ CONCAT_TEST("foo", "/", "foo/");
+ CONCAT_TEST("foo", "/bar", "foo/bar");
+
+ CONCAT_TEST("foo/", "", "foo/");
+ CONCAT_TEST("foo/", "/", "foo//");
+ CONCAT_TEST("foo/", "bar", "foo/bar");
+
+ CONCAT_TEST("foo", "", "foo");
+ CONCAT_TEST("foo", "bar", "foobar");
+ CONCAT_TEST("foo\\", "\\bar", "foo\\\\bar");
+ CONCAT_TEST("c:", "bar", "c:bar");
+}
+
+// self_assign_append_concat_tests -------------------------------------------------//
+
+void self_assign_append_concat_tests()
+{
+ std::cout << "self_assign_append_concat_tests..." << std::endl;
+
+ path p;
+
+ p = "snafubar";
+ PATH_TEST_EQ(p = p, "snafubar");
+
+ p = "snafubar";
+ p = p.c_str();
+ PATH_TEST_EQ(p, "snafubar");
+
+ p = "snafubar";
+ p.assign(p.c_str(), path::codecvt());
+ PATH_TEST_EQ(p, "snafubar");
+
+ p = "snafubar";
+ PATH_TEST_EQ(p = p.c_str() + 5, "bar");
+
+ p = "snafubar";
+ PATH_TEST_EQ(p.assign(p.c_str() + 5, p.c_str() + 7), "ba");
+
+ p = "snafubar";
+ p /= p;
+ PATH_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
+
+ p = "snafubar";
+ p /= p.c_str();
+ PATH_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
+
+ p = "snafubar";
+ p.append(p.c_str(), path::codecvt());
+ PATH_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
+
+ p = "snafubar";
+ PATH_TEST_EQ(p.append(p.c_str() + 5, p.c_str() + 7), "snafubar" BOOST_DIR_SEP "ba");
+
+ p = "snafubar";
+ p += p;
+ PATH_TEST_EQ(p, "snafubarsnafubar");
+
+ p = "snafubar";
+ p += p.c_str();
+ PATH_TEST_EQ(p, "snafubarsnafubar");
+
+ p = "snafubar";
+ p.concat(p.c_str(), path::codecvt());
+ PATH_TEST_EQ(p, "snafubarsnafubar");
+
+ p = "snafubar";
+ PATH_TEST_EQ(p.concat(p.c_str() + 5, p.c_str() + 7), "snafubarba");
+}
+
+// name_function_tests -------------------------------------------------------------//
+
+void name_function_tests()
+{
+ std::cout << "name_function_tests..." << std::endl;
+
+ BOOST_TEST(fs::portable_posix_name(std::string("x")));
+ BOOST_TEST(fs::windows_name(std::string("x")));
+ BOOST_TEST(fs::portable_name(std::string("x")));
+ BOOST_TEST(fs::portable_directory_name(std::string("x")));
+ BOOST_TEST(fs::portable_file_name(std::string("x")));
+
+ BOOST_TEST(fs::portable_posix_name(std::string(".")));
+ BOOST_TEST(fs::windows_name(std::string(".")));
+ BOOST_TEST(fs::portable_name(std::string(".")));
+ BOOST_TEST(fs::portable_directory_name(std::string(".")));
+ BOOST_TEST(!fs::portable_file_name(std::string(".")));
+
+ BOOST_TEST(fs::portable_posix_name(std::string("..")));
+ BOOST_TEST(fs::windows_name(std::string("..")));
+ BOOST_TEST(fs::portable_name(std::string("..")));
+ BOOST_TEST(fs::portable_directory_name(std::string("..")));
+ BOOST_TEST(!fs::portable_file_name(std::string("..")));
+
+ BOOST_TEST(!fs::native(std::string("")));
+ BOOST_TEST(!fs::portable_posix_name(std::string("")));
+ BOOST_TEST(!fs::windows_name(std::string("")));
+ BOOST_TEST(!fs::portable_name(std::string("")));
+ BOOST_TEST(!fs::portable_directory_name(std::string("")));
+ BOOST_TEST(!fs::portable_file_name(std::string("")));
+
+ BOOST_TEST(!fs::native(std::string(" ")));
+ BOOST_TEST(!fs::portable_posix_name(std::string(" ")));
+ BOOST_TEST(!fs::windows_name(std::string(" ")));
+ BOOST_TEST(!fs::portable_name(std::string(" ")));
+ BOOST_TEST(!fs::portable_directory_name(std::string(" ")));
+ BOOST_TEST(!fs::portable_file_name(std::string(" ")));
+
+ BOOST_TEST(!fs::portable_posix_name(std::string(":")));
+ BOOST_TEST(!fs::windows_name(std::string(":")));
+ BOOST_TEST(!fs::portable_name(std::string(":")));
+ BOOST_TEST(!fs::portable_directory_name(std::string(":")));
+ BOOST_TEST(!fs::portable_file_name(std::string(":")));
+
+ BOOST_TEST(fs::portable_posix_name(std::string("-")));
+ BOOST_TEST(fs::windows_name(std::string("-")));
+ BOOST_TEST(!fs::portable_name(std::string("-")));
+ BOOST_TEST(!fs::portable_directory_name(std::string("-")));
+ BOOST_TEST(!fs::portable_file_name(std::string("-")));
+
+ BOOST_TEST(!fs::portable_posix_name(std::string("foo bar")));
+ BOOST_TEST(fs::windows_name(std::string("foo bar")));
+ BOOST_TEST(!fs::windows_name(std::string(" bar")));
+ BOOST_TEST(!fs::windows_name(std::string("foo ")));
+ BOOST_TEST(!fs::portable_name(std::string("foo bar")));
+ BOOST_TEST(!fs::portable_directory_name(std::string("foo bar")));
+ BOOST_TEST(!fs::portable_file_name(std::string("foo bar")));
+
+ BOOST_TEST(fs::portable_posix_name(std::string("foo.bar")));
+ BOOST_TEST(fs::windows_name(std::string("foo.bar")));
+ BOOST_TEST(fs::portable_name(std::string("foo.bar")));
+ BOOST_TEST(!fs::portable_directory_name(std::string("foo.bar")));
+ BOOST_TEST(fs::portable_file_name(std::string("foo.bar")));
+
+ BOOST_TEST(fs::portable_posix_name(std::string("foo.barf")));
+ BOOST_TEST(fs::windows_name(std::string("foo.barf")));
+ BOOST_TEST(fs::portable_name(std::string("foo.barf")));
+ BOOST_TEST(!fs::portable_directory_name(std::string("foo.barf")));
+ BOOST_TEST(!fs::portable_file_name(std::string("foo.barf")));
+
+ BOOST_TEST(fs::portable_posix_name(std::string(".foo")));
+ BOOST_TEST(fs::windows_name(std::string(".foo")));
+ BOOST_TEST(!fs::portable_name(std::string(".foo")));
+ BOOST_TEST(!fs::portable_directory_name(std::string(".foo")));
+ BOOST_TEST(!fs::portable_file_name(std::string(".foo")));
+
+ BOOST_TEST(fs::portable_posix_name(std::string("foo.")));
+ BOOST_TEST(!fs::windows_name(std::string("foo.")));
+ BOOST_TEST(!fs::portable_name(std::string("foo.")));
+ BOOST_TEST(!fs::portable_directory_name(std::string("foo.")));
+ BOOST_TEST(!fs::portable_file_name(std::string("foo.")));
+}
+
+// replace_extension_tests ---------------------------------------------------------//
+
+void replace_extension_tests()
+{
+ std::cout << "replace_extension_tests..." << std::endl;
+
+ BOOST_TEST(path().replace_extension().empty());
+ BOOST_TEST(path().replace_extension("a") == ".a");
+ BOOST_TEST(path().replace_extension("a.") == ".a.");
+ BOOST_TEST(path().replace_extension(".a") == ".a");
+ BOOST_TEST(path().replace_extension("a.txt") == ".a.txt");
+ // see the rationale in html docs for explanation why this works:
+ BOOST_TEST(path().replace_extension(".txt") == ".txt");
+
+ BOOST_TEST(path("a.txt").replace_extension() == "a");
+ BOOST_TEST(path("a.txt").replace_extension("") == "a");
+ BOOST_TEST(path("a.txt").replace_extension(".") == "a.");
+ BOOST_TEST(path("a.txt").replace_extension(".tex") == "a.tex");
+ BOOST_TEST(path("a.txt").replace_extension("tex") == "a.tex");
+ BOOST_TEST(path("a.").replace_extension(".tex") == "a.tex");
+ BOOST_TEST(path("a.").replace_extension("tex") == "a.tex");
+ BOOST_TEST(path("a").replace_extension(".txt") == "a.txt");
+ BOOST_TEST(path("a").replace_extension("txt") == "a.txt");
+ BOOST_TEST(path("a.b.txt").replace_extension(".tex") == "a.b.tex");
+ BOOST_TEST(path("a.b.txt").replace_extension("tex") == "a.b.tex");
+ BOOST_TEST(path("a/b").replace_extension(".c") == "a/b.c");
+ PATH_TEST_EQ(path("a.txt/b").replace_extension(".c"), "a.txt/b.c"); // ticket 4702
+ BOOST_TEST(path("foo.txt").replace_extension("exe") == "foo.exe"); // ticket 5118
+ BOOST_TEST(path("foo.txt").replace_extension(".tar.bz2") == "foo.tar.bz2"); // ticket 5118
+}
+
+// make_preferred_tests ------------------------------------------------------------//
+
+void make_preferred_tests()
+{
+ std::cout << "make_preferred_tests..." << std::endl;
+
+ if (platform == "Windows")
+ {
+ BOOST_TEST(path("//abc\\def/ghi").make_preferred().native() == path("\\\\abc\\def\\ghi").native());
+ }
+ else
+ {
+ BOOST_TEST(path("//abc\\def/ghi").make_preferred().native() == path("//abc\\def/ghi").native());
+ }
+}
+
+// lexically_normal_tests ----------------------------------------------------------//
+
+void lexically_normal_tests()
+{
+ std::cout << "lexically_normal_tests..." << std::endl;
+
+ // Note: lexically_normal() uses /= to build up some results, so these results will
+ // have the platform's preferred separator. Since that is immaterial to the correct
+ // functioning of lexically_normal(), the test results are converted to generic form,
+ // and the expected results are also given in generic form. Otherwise many of the
+ // tests would incorrectly be reported as failing on Windows.
+
+ PATH_TEST_EQ(path("").lexically_normal().generic_path(), "");
+ PATH_TEST_EQ(path("/").lexically_normal().generic_path(), "/");
+ PATH_TEST_EQ(path("//").lexically_normal().generic_path(), "//");
+ PATH_TEST_EQ(path("///").lexically_normal().generic_path(), "/");
+ PATH_TEST_EQ(path("f").lexically_normal().generic_path(), "f");
+ PATH_TEST_EQ(path("foo").lexically_normal().generic_path(), "foo");
+ PATH_TEST_EQ(path("foo/").lexically_normal().generic_path(), "foo/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("f/").lexically_normal().generic_path(), "f/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("/foo").lexically_normal().generic_path(), "/foo");
+ PATH_TEST_EQ(path("/./foo").lexically_normal().generic_path(), "/foo");
+ PATH_TEST_EQ(path("/./foo/.").lexically_normal().generic_path(), "/foo/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("foo/bar").lexically_normal().generic_path(), "foo/bar");
+ PATH_TEST_EQ(path("..").lexically_normal().generic_path(), "..");
+ PATH_TEST_EQ(path("../..").lexically_normal().generic_path(), "../..");
+ PATH_TEST_EQ(path("/..").lexically_normal().generic_path(), "/..");
+ PATH_TEST_EQ(path("/../..").lexically_normal().generic_path(), "/../..");
+ PATH_TEST_EQ(path("../foo").lexically_normal().generic_path(), "../foo");
+ PATH_TEST_EQ(path("foo/..").lexically_normal().generic_path(), ".");
+ PATH_TEST_EQ(path("foo/../").lexically_normal().generic_path(), ".");
+ PATH_TEST_EQ((path("foo") / "..").lexically_normal().generic_path(), ".");
+ PATH_TEST_EQ(path("foo/...").lexically_normal().generic_path(), "foo/...");
+ PATH_TEST_EQ(path("foo/.../").lexically_normal().generic_path(), "foo/.../" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("foo/..bar").lexically_normal().generic_path(), "foo/..bar");
+ PATH_TEST_EQ(path("../f").lexically_normal().generic_path(), "../f");
+ PATH_TEST_EQ(path("/../f").lexically_normal().generic_path(), "/../f");
+ PATH_TEST_EQ(path("f/..").lexically_normal().generic_path(), ".");
+ PATH_TEST_EQ((path("f") / "..").lexically_normal().generic_path(), ".");
+ PATH_TEST_EQ(path("foo/../..").lexically_normal().generic_path(), "..");
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("foo/../../").lexically_normal().generic_path(), "../.");
+#else
+ PATH_TEST_EQ(path("foo/../../").lexically_normal().generic_path(), "..");
+#endif
+ PATH_TEST_EQ(path("foo/../../..").lexically_normal().generic_path(), "../..");
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("foo/../../../").lexically_normal().generic_path(), "../../.");
+#else
+ PATH_TEST_EQ(path("foo/../../../").lexically_normal().generic_path(), "../..");
+#endif
+ PATH_TEST_EQ(path("foo/../bar").lexically_normal().generic_path(), "bar");
+ PATH_TEST_EQ(path("foo/../bar/").lexically_normal().generic_path(), "bar/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("foo/bar/..").lexically_normal().generic_path(), "foo");
+ PATH_TEST_EQ(path("foo/./bar/..").lexically_normal().generic_path(), "foo");
+ std::cout << path("foo/./bar/..").lexically_normal() << std::endl; // outputs "foo"
+ PATH_TEST_EQ(path("foo/bar/../").lexically_normal().generic_path(), "foo/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("foo/./bar/../").lexically_normal().generic_path(), "foo/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ std::cout << path("foo/./bar/../").lexically_normal() << std::endl; // POSIX: "foo/", Windows: "foo\" (with a trailing dot for v3)
+ PATH_TEST_EQ(path("foo/bar/../..").lexically_normal().generic_path(), ".");
+ PATH_TEST_EQ(path("foo/bar/../../").lexically_normal().generic_path(), ".");
+ PATH_TEST_EQ(path("foo/bar/../blah").lexically_normal().generic_path(), "foo/blah");
+ PATH_TEST_EQ(path("f/../b").lexically_normal().generic_path(), "b");
+ PATH_TEST_EQ(path("f/b/..").lexically_normal().generic_path(), "f");
+ PATH_TEST_EQ(path("f/b/../").lexically_normal().generic_path(), "f/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("f/b/../a").lexically_normal().generic_path(), "f/a");
+ PATH_TEST_EQ(path("foo/bar/blah/../..").lexically_normal().generic_path(), "foo");
+ PATH_TEST_EQ(path("foo/bar/blah/../../bletch").lexically_normal().generic_path(), "foo/bletch");
+ PATH_TEST_EQ(path("//net").lexically_normal().generic_path(), "//net");
+ PATH_TEST_EQ(path("//net/").lexically_normal().generic_path(), "//net/");
+ PATH_TEST_EQ(path("//..net").lexically_normal().generic_path(), "//..net");
+ PATH_TEST_EQ(path("//net/..").lexically_normal().generic_path(), "//net/..");
+ PATH_TEST_EQ(path("//net/foo").lexically_normal().generic_path(), "//net/foo");
+ PATH_TEST_EQ(path("//net/foo/").lexically_normal().generic_path(), "//net/foo/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("//net/foo/..").lexically_normal().generic_path(), "//net/");
+ PATH_TEST_EQ(path("//net/foo/../").lexically_normal().generic_path(), "//net/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+
+ PATH_TEST_EQ(path("/net/foo/bar").lexically_normal().generic_path(), "/net/foo/bar");
+ PATH_TEST_EQ(path("/net/foo/bar/").lexically_normal().generic_path(), "/net/foo/bar/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("/net/foo/..").lexically_normal().generic_path(), "/net");
+ PATH_TEST_EQ(path("/net/foo/../").lexically_normal().generic_path(), "/net/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+
+ PATH_TEST_EQ(path("//net//foo//bar").lexically_normal().generic_path(), "//net/foo/bar");
+ PATH_TEST_EQ(path("//net//foo//bar//").lexically_normal().generic_path(), "//net/foo/bar/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("//net//foo//..").lexically_normal().generic_path(), "//net/");
+ PATH_TEST_EQ(path("//net//foo//..//").lexically_normal().generic_path(), "//net/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+
+ PATH_TEST_EQ(path("///net///foo///bar").lexically_normal().generic_path(), "/net/foo/bar");
+ PATH_TEST_EQ(path("///net///foo///bar///").lexically_normal().generic_path(), "/net/foo/bar/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("///net///foo///..").lexically_normal().generic_path(), "/net");
+ PATH_TEST_EQ(path("///net///foo///..///").lexically_normal().generic_path(), "/net/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+
+ if (platform == "Windows")
+ {
+ BOOST_TEST_EQ(path("c:/foo/bar").lexically_normal().string(), "c:\\foo\\bar");
+
+ PATH_TEST_EQ(path("c:foo").lexically_normal().generic_path(), "c:foo");
+ PATH_TEST_EQ(path("c:..").lexically_normal().generic_path(), "c:..");
+ PATH_TEST_EQ(path("c:foo/..").lexically_normal().generic_path(), "c:");
+
+ PATH_TEST_EQ(path("c:foo/../").lexically_normal().generic_path(), "c:" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+
+ PATH_TEST_EQ(path("c:/foo/..").lexically_normal().generic_path(), "c:/");
+ PATH_TEST_EQ(path("c:/foo/../").lexically_normal().generic_path(), "c:/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("c:/..").lexically_normal().generic_path(), "c:/..");
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("c:/../").lexically_normal().generic_path(), "c:/../.");
+#else
+ PATH_TEST_EQ(path("c:/../").lexically_normal().generic_path(), "c:/..");
+#endif
+ PATH_TEST_EQ(path("c:/../..").lexically_normal().generic_path(), "c:/../..");
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("c:/../../").lexically_normal().generic_path(), "c:/../../.");
+#else
+ PATH_TEST_EQ(path("c:/../../").lexically_normal().generic_path(), "c:/../..");
+#endif
+ PATH_TEST_EQ(path("c:/../foo").lexically_normal().generic_path(), "c:/../foo");
+ PATH_TEST_EQ(path("c:/../foo/").lexically_normal().generic_path(), "c:/../foo/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("c:/../../foo").lexically_normal().generic_path(), "c:/../../foo");
+ PATH_TEST_EQ(path("c:/../../foo/").lexically_normal().generic_path(), "c:/../../foo/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("c:/..foo").lexically_normal().generic_path(), "c:/..foo");
+ }
+ else // POSIX
+ {
+ PATH_TEST_EQ(path("c:..").lexically_normal(), "c:..");
+ PATH_TEST_EQ(path("c:foo/..").lexically_normal(), ".");
+ PATH_TEST_EQ(path("c:foo/../").lexically_normal(), ".");
+ PATH_TEST_EQ(path("c:/foo/..").lexically_normal(), "c:");
+ PATH_TEST_EQ(path("c:/foo/../").lexically_normal(), "c:/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("c:/..").lexically_normal(), ".");
+ PATH_TEST_EQ(path("c:/../").lexically_normal(), ".");
+ PATH_TEST_EQ(path("c:/../..").lexically_normal(), "..");
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_TEST_EQ(path("c:/../../").lexically_normal(), "../.");
+#else
+ PATH_TEST_EQ(path("c:/../../").lexically_normal(), "..");
+#endif
+ PATH_TEST_EQ(path("c:/../foo").lexically_normal(), "foo");
+ PATH_TEST_EQ(path("c:/../foo/").lexically_normal(), "foo/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("c:/../../foo").lexically_normal(), "../foo");
+ PATH_TEST_EQ(path("c:/../../foo/").lexically_normal(), "../foo/" BOOST_FILESYSTEM_V3_TRAILING_DOT);
+ PATH_TEST_EQ(path("c:/..foo").lexically_normal(), "c:/..foo");
+ }
+}
+
+inline void odr_use(const path::value_type& c)
+{
+ static const path::value_type dummy = '\0';
+ BOOST_TEST(&c != &dummy);
+}
+
+} // unnamed namespace
+
+static boost::filesystem::path ticket_6737 = "FilePath"; // #6737 reported this crashed
+ // on VC++ debug mode build
+const boost::filesystem::path ticket_6690("test"); // #6690 another V++ static init crash
+
+//--------------------------------------------------------------------------------------//
+// //
+// main //
+// //
+//--------------------------------------------------------------------------------------//
+
+int cpp_main(int, char*[])
+{
+ // The choice of platform is make at runtime rather than compile-time
+ // so that compile errors for all platforms will be detected even though
+ // only the current platform is runtime tested.
+ platform = (platform == "Win32" || platform == "Win64" || platform == "Cygwin") ? "Windows" : "POSIX";
+ std::cout << "Platform is " << platform << '\n';
+
+ BOOST_TEST(p1.string() != p3.string());
+ p3 = p2;
+ BOOST_TEST(p1.string() == p3.string());
+
+ path p04("foobar");
+ BOOST_TEST(p04.string() == "foobar");
+ p04 = p04; // self-assignment
+ BOOST_TEST(p04.string() == "foobar");
+
+ construction_tests();
+ append_tests();
+ concat_tests();
+ self_assign_append_concat_tests();
+ overload_tests();
+ query_and_decomposition_tests();
+ composition_tests();
+ iterator_tests();
+ non_member_tests();
+ exception_tests();
+ name_function_tests();
+ replace_extension_tests();
+ make_preferred_tests();
+ lexically_normal_tests();
+
+ // verify deprecated names still available
+
+#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+
+ p1.branch_path();
+ p1.leaf();
+ path p_remove_leaf;
+ p_remove_leaf.remove_leaf();
+
+#endif
+
+ std::string s1("//:somestring"); // this used to be treated specially
+
+ // check the path member templates
+ p5.assign(s1.begin(), s1.end());
+
+ PATH_TEST_EQ(p5.string(), "//:somestring");
+ p5 = s1;
+ PATH_TEST_EQ(p5.string(), "//:somestring");
+
+ // this code, courtesy of David Whetstone, detects a now fixed bug that
+ // derefereced the end iterator (assuming debug build with checked itors)
+ std::vector< char > v1;
+ p5.assign(v1.begin(), v1.end());
+ std::string s2(v1.begin(), v1.end());
+ PATH_TEST_EQ(p5.string(), s2);
+ p5.assign(s1.begin(), s1.begin() + 1);
+ PATH_TEST_EQ(p5.string(), "/");
+
+ BOOST_TEST(p1 != p4);
+ BOOST_TEST(p1.string() == p2.string());
+ BOOST_TEST(p1.string() == p3.string());
+ BOOST_TEST(path("foo").filename() == "foo");
+ BOOST_TEST(path("foo").parent_path().string() == "");
+ BOOST_TEST(p1.filename() == "fum");
+ BOOST_TEST(p1.parent_path().string() == "fe/fi/fo");
+ BOOST_TEST(path("").empty() == true);
+ BOOST_TEST(path("foo").empty() == false);
+
+ // inserter and extractor tests
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // bypass VC++ 7.0 and earlier
+ std::cout << "\nInserter and extractor test...";
+ std::stringstream ss;
+ ss << fs::path("foo/bar") << std::endl;
+ fs::path round_trip;
+ ss >> round_trip;
+ BOOST_TEST(round_trip.string() == "foo/bar");
+ std::cout << round_trip.string() << "..." << round_trip << " complete\n";
+#endif
+
+ // Check that path constants have definitions
+ // https://svn.boost.org/trac10/ticket/12759
+ odr_use(path::separator);
+ odr_use(path::preferred_separator);
+ odr_use(path::dot);
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/path_times.cpp b/src/boost/libs/filesystem/test/path_times.cpp
new file mode 100644
index 000000000..8d9a032e6
--- /dev/null
+++ b/src/boost/libs/filesystem/test/path_times.cpp
@@ -0,0 +1,97 @@
+// Boost Filesystem path_times.cpp ---------------------------------------------------//
+
+// Copyright Beman Dawes 2013
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#include <boost/config/warning_disable.hpp>
+
+#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#endif
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/timer/timer.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/detail/lightweight_main.hpp>
+
+namespace fs = boost::filesystem;
+using namespace boost::timer;
+
+#include <fstream>
+#include <iostream>
+
+using std::cout;
+using std::endl;
+
+namespace {
+boost::int64_t max_cycles;
+
+template< class STD_STRING >
+nanosecond_type time_ctor(const STD_STRING& s)
+{
+ boost::timer::auto_cpu_timer tmr;
+ boost::int64_t count = 0;
+ do
+ {
+ fs::path p(s);
+ ++count;
+ } while (count < max_cycles);
+
+ boost::timer::cpu_times elapsed = tmr.elapsed();
+ return elapsed.user + elapsed.system;
+}
+
+nanosecond_type time_loop()
+{
+ boost::timer::auto_cpu_timer tmr;
+ boost::int64_t count = 0;
+ do
+ {
+ ++count;
+ } while (count < max_cycles);
+
+ boost::timer::cpu_times elapsed = tmr.elapsed();
+ return elapsed.user + elapsed.system;
+}
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+// main //
+//--------------------------------------------------------------------------------------//
+
+int cpp_main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cout << "Usage: path_times <cycles-in-millions>\n";
+ return 1;
+ }
+
+ max_cycles = std::atoi(argv[1]) * 1000000LL;
+ cout << "testing " << std::atoi(argv[1]) << " million cycles" << endl;
+
+ cout << "time_loop" << endl;
+ nanosecond_type x = time_loop();
+
+ cout << "time_ctor with string" << endl;
+ nanosecond_type s = time_ctor(std::string("/foo/bar/baz"));
+
+ cout << "time_ctor with wstring" << endl;
+ nanosecond_type w = time_ctor(std::wstring(L"/foo/bar/baz"));
+
+ if (s > w)
+ cout << "narrow/wide CPU-time ratio = " << long double(s) / w << endl;
+ else
+ cout << "wide/narrow CPU-time ratio = " << long double(w) / s << endl;
+
+ cout << "returning from main()" << endl;
+ return 0;
+}
diff --git a/src/boost/libs/filesystem/test/path_unit_test.cpp b/src/boost/libs/filesystem/test/path_unit_test.cpp
new file mode 100644
index 000000000..09d69da59
--- /dev/null
+++ b/src/boost/libs/filesystem/test/path_unit_test.cpp
@@ -0,0 +1,1298 @@
+// filesystem path_unit_test.cpp --------------------------------------------------- //
+
+// Copyright Beman Dawes 2008, 2009
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+// ---------------------------------------------------------------------------------- //
+//
+// The purpose of this test is to ensure that each function in the public
+// interface can be called with arguments of the appropriate types. It does
+// not attempt to verify that the full range of values for each argument
+// are processed correctly.
+//
+// For full functionality tests, including probes with many different argument
+// values, see path_test.cpp and other test programs.
+//
+// ---------------------------------------------------------------------------------- //
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#endif
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/path.hpp>
+
+#include <boost/filesystem/detail/utf8_codecvt_facet.hpp> // for imbue tests
+#include "test_codecvt.hpp" // for codecvt arg tests
+#include <boost/detail/lightweight_test_report.hpp>
+#include <boost/smart_ptr.hpp> // used constructor tests
+#include <boost/functional/hash.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/system/system_error.hpp>
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <string>
+#include <cstring>
+#include <cwchar>
+#include <locale>
+#include <list>
+
+namespace fs = boost::filesystem;
+namespace bs = boost::system;
+using boost::filesystem::path;
+using std::cout;
+using std::endl;
+using std::string;
+using std::wstring;
+
+#define CHECK(x) check(x, __FILE__, __LINE__)
+#define PATH_IS(a, b) check_path(a, b, __FILE__, __LINE__)
+#define NATIVE_IS(p, s, ws) check_native(p, s, ws, __FILE__, __LINE__)
+#define IS(a, b) check_equal(a, b, __FILE__, __LINE__)
+
+#if defined(_MSC_VER)
+#pragma warning(push) // Save warning settings.
+#pragma warning(disable : 4428) // Disable universal-character-name encountered in source warning.
+#endif
+
+namespace {
+
+std::string platform(BOOST_PLATFORM);
+
+void check_path(const path& source, const wstring& expected, const char* file, int line)
+{
+ if (source == expected)
+ return;
+
+ ++::boost::detail::test_errors();
+
+ std::cout << file;
+ std::wcout << L'(' << line << L"): source.wstring(): \""
+ << source.wstring()
+ << L"\" != expected: \"" << expected
+ << L"\"\n";
+}
+
+#ifdef BOOST_WINDOWS_API
+void check_native(const path& p, const string&, const wstring& expected, const char* file, int line)
+#else
+void check_native(const path& p, const string& expected, const wstring&, const char* file, int line)
+#endif
+{
+ if (p.native() == expected)
+ return;
+
+ ++::boost::detail::test_errors();
+
+ std::cout << file << '(' << line << "): native() is not equal expected\n"
+ " native---: "
+ << std::hex;
+ path::string_type nat(p.native());
+ for (path::string_type::const_iterator it = nat.begin(); it != nat.end(); ++it)
+ std::cout << long(*it) << ' ';
+ std::cout << "\n expected-: ";
+ for (path::string_type::const_iterator it = expected.begin(); it != expected.end(); ++it)
+ std::cout << long(*it) << ' ';
+ std::cout << std::dec << std::endl;
+}
+
+template< class T1, class T2 >
+void check_equal(const T1& value, const T2& expected, const char* file, int line)
+{
+ if (value == expected)
+ return;
+
+ ++::boost::detail::test_errors();
+
+ std::cout << file;
+
+ std::wcout << L'(' << line << L"): value: \"" << value
+ << L"\" != expected: \"" << expected
+ << L"\"\n";
+}
+
+void check(bool ok_, const char* file, int line)
+{
+ if (ok_)
+ return;
+
+ ++::boost::detail::test_errors();
+
+ std::cout << file << '(' << line << "): test failed\n";
+}
+
+string s("string");
+wstring ws(L"wstring");
+std::list< char > l; // see main() for initialization to s, t, r, i, n, g
+std::list< wchar_t > wl; // see main() for initialization to w, s, t, r, i, n, g
+std::vector< char > v; // see main() for initialization to f, u, z
+std::vector< wchar_t > wv; // see main() for initialization to w, f, u, z
+
+class Base
+{
+};
+class Derived : public Base
+{
+};
+void fun(const boost::shared_ptr< Base >&)
+{
+}
+
+// test_constructors ---------------------------------------------------------------//
+
+void test_constructors()
+{
+ std::cout << "testing constructors..." << std::endl;
+
+ path x0; // default constructor
+ PATH_IS(x0, L"");
+ BOOST_TEST_EQ(x0.native().size(), 0U);
+
+ path x1(l.begin(), l.end()); // iterator range char
+ PATH_IS(x1, L"string");
+ BOOST_TEST_EQ(x1.native().size(), 6U);
+
+ path x2(x1); // copy constructor
+ PATH_IS(x2, L"string");
+ BOOST_TEST_EQ(x2.native().size(), 6U);
+
+ path x3(wl.begin(), wl.end()); // iterator range wchar_t
+ PATH_IS(x3, L"wstring");
+ BOOST_TEST_EQ(x3.native().size(), 7U);
+
+ // contiguous containers
+ path x4(string("std::string")); // std::string
+ PATH_IS(x4, L"std::string");
+ BOOST_TEST_EQ(x4.native().size(), 11U);
+
+ path x5(wstring(L"std::wstring")); // std::wstring
+ PATH_IS(x5, L"std::wstring");
+ BOOST_TEST_EQ(x5.native().size(), 12U);
+
+ path x4v(v); // std::vector<char>
+ PATH_IS(x4v, L"fuz");
+ BOOST_TEST_EQ(x4v.native().size(), 3U);
+
+ path x5v(wv); // std::vector<wchar_t>
+ PATH_IS(x5v, L"wfuz");
+ BOOST_TEST_EQ(x5v.native().size(), 4U);
+
+ path x6("array char"); // array char
+ PATH_IS(x6, L"array char");
+ BOOST_TEST_EQ(x6.native().size(), 10U);
+
+ path x7(L"array wchar_t"); // array wchar_t
+ PATH_IS(x7, L"array wchar_t");
+ BOOST_TEST_EQ(x7.native().size(), 13U);
+
+ char char_array[100];
+ std::strcpy(char_array, "big array char");
+ path x6o(char_array); // array char, only partially full
+ PATH_IS(x6o, L"big array char");
+ BOOST_TEST_EQ(x6o.native().size(), 14U);
+
+ wchar_t wchar_array[100];
+ std::wcscpy(wchar_array, L"big array wchar_t");
+ path x7o(wchar_array); // array char, only partially full
+ PATH_IS(x7o, L"big array wchar_t");
+ BOOST_TEST_EQ(x7o.native().size(), 17U);
+
+ path x8(s.c_str()); // const char* null terminated
+ PATH_IS(x8, L"string");
+ BOOST_TEST_EQ(x8.native().size(), 6U);
+
+ path x9(ws.c_str()); // const wchar_t* null terminated
+ PATH_IS(x9, L"wstring");
+ BOOST_TEST_EQ(x9.native().size(), 7U);
+
+ path x8nc(const_cast< char* >(s.c_str())); // char* null terminated
+ PATH_IS(x8nc, L"string");
+ BOOST_TEST_EQ(x8nc.native().size(), 6U);
+
+ path x9nc(const_cast< wchar_t* >(ws.c_str())); // wchar_t* null terminated
+ PATH_IS(x9nc, L"wstring");
+ BOOST_TEST_EQ(x9nc.native().size(), 7U);
+
+ // non-contiguous containers
+ path x10(l); // std::list<char>
+ PATH_IS(x10, L"string");
+ BOOST_TEST_EQ(x10.native().size(), 6U);
+
+ path xll(wl); // std::list<wchar_t>
+ PATH_IS(xll, L"wstring");
+ BOOST_TEST_EQ(xll.native().size(), 7U);
+
+ // easy-to-make coding errors
+ // path e1(x0, path::codecvt()); // fails to compile, and that is OK
+
+ boost::shared_ptr< Derived > pDerived(new Derived());
+ fun(pDerived); // tests constructor member template enable_if working correctly;
+ // will fail to compile if enable_if not taking path off the table
+}
+
+path x;
+path y;
+
+// test_assignments ----------------------------------------------------------------//
+
+void test_assignments()
+{
+ std::cout << "testing assignments..." << std::endl;
+
+ x = path("yet another path"); // another path
+ PATH_IS(x, L"yet another path");
+ BOOST_TEST_EQ(x.native().size(), 16U);
+
+ x = x; // self-assignment
+ PATH_IS(x, L"yet another path");
+ BOOST_TEST_EQ(x.native().size(), 16U);
+
+ x.assign(l.begin(), l.end()); // iterator range char
+ PATH_IS(x, L"string");
+
+ x.assign(wl.begin(), wl.end()); // iterator range wchar_t
+ PATH_IS(x, L"wstring");
+
+ x = string("std::string"); // container char
+ PATH_IS(x, L"std::string");
+
+ x = wstring(L"std::wstring"); // container wchar_t
+ PATH_IS(x, L"std::wstring");
+
+ x = "array char"; // array char
+ PATH_IS(x, L"array char");
+
+ x = L"array wchar"; // array wchar_t
+ PATH_IS(x, L"array wchar");
+
+ x = s.c_str(); // const char* null terminated
+ PATH_IS(x, L"string");
+
+ x = ws.c_str(); // const wchar_t* null terminated
+ PATH_IS(x, L"wstring");
+}
+
+// test_move_construction_and_assignment -------------------------------------------//
+
+void test_move_construction_and_assignment()
+{
+ std::cout << "testing move_construction_and_assignment..." << std::endl;
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ path from("long enough to avoid small object optimization");
+ path to(std::move(from));
+ BOOST_TEST(to == "long enough to avoid small object optimization");
+ if (!from.empty())
+ cout << "Note: move construction did not result in empty source path" << endl;
+
+ path from2("long enough to avoid small object optimization");
+ path to2;
+ to2 = std::move(from2);
+ BOOST_TEST(to2 == "long enough to avoid small object optimization");
+ if (!from2.empty())
+ cout << "Note: move assignment did not result in empty rhs path" << endl;
+#else
+ std::cout << "Test skipped because compiler does not support move semantics" << std::endl;
+#endif
+}
+
+// test_appends --------------------------------------------------------------------//
+
+void test_appends()
+{
+ std::cout << "testing appends..." << std::endl;
+
+#ifdef BOOST_WINDOWS_API
+#define BOOST_FS_FOO L"/foo\\"
+#else // POSIX paths
+#define BOOST_FS_FOO L"/foo/"
+#endif
+
+ x = "/foo";
+ x /= path(""); // empty path
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_IS(x, L"/foo");
+#else
+ PATH_IS(x, L"/foo/");
+#endif
+
+ x = "/foo";
+ x /= path("/"); // slash path
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_IS(x, L"/foo/");
+#else
+ PATH_IS(x, L"/");
+#endif
+
+ x = "/foo";
+ x /= path("/boo"); // slash path
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_IS(x, L"/foo/boo");
+#else
+ PATH_IS(x, L"/boo");
+#endif
+
+ x = "/foo";
+ x /= x; // self-append
+#if BOOST_FILESYSTEM_VERSION == 3
+ PATH_IS(x, L"/foo/foo");
+#else
+ PATH_IS(x, L"/foo");
+#endif
+
+ x = "/foo";
+ x /= path("yet another path"); // another path
+ PATH_IS(x, BOOST_FS_FOO L"yet another path");
+
+ x = "/foo";
+ x.append(l.begin(), l.end()); // iterator range char
+ PATH_IS(x, BOOST_FS_FOO L"string");
+
+ x = "/foo";
+ x.append(wl.begin(), wl.end()); // iterator range wchar_t
+ PATH_IS(x, BOOST_FS_FOO L"wstring");
+
+ x = "/foo";
+ x /= string("std_string"); // container char
+ PATH_IS(x, BOOST_FS_FOO L"std_string");
+
+ x = "/foo";
+ x /= wstring(L"std_wstring"); // container wchar_t
+ PATH_IS(x, BOOST_FS_FOO L"std_wstring");
+
+ x = "/foo";
+ x /= "array char"; // array char
+ PATH_IS(x, BOOST_FS_FOO L"array char");
+
+ x = "/foo";
+ x /= L"array wchar"; // array wchar_t
+ PATH_IS(x, BOOST_FS_FOO L"array wchar");
+
+ x = "/foo";
+ x /= s.c_str(); // const char* null terminated
+ PATH_IS(x, BOOST_FS_FOO L"string");
+
+ x = "/foo";
+ x /= ws.c_str(); // const wchar_t* null terminated
+ PATH_IS(x, BOOST_FS_FOO L"wstring");
+}
+
+// test_concats --------------------------------------------------------------------//
+
+void test_concats()
+{
+ std::cout << "testing concats..." << std::endl;
+
+ x = "/foo";
+ x += path(""); // empty path
+ PATH_IS(x, L"/foo");
+
+ x = "/foo";
+ x += path("/"); // slash path
+ PATH_IS(x, L"/foo/");
+
+ x = "/foo";
+ x += path("boo"); // slash path
+ PATH_IS(x, L"/fooboo");
+
+ x = "foo";
+ x += x; // self-append
+ PATH_IS(x, L"foofoo");
+
+ x = "foo-";
+ x += path("yet another path"); // another path
+ PATH_IS(x, L"foo-yet another path");
+
+ x = "foo-";
+ x.concat(l.begin(), l.end()); // iterator range char
+ PATH_IS(x, L"foo-string");
+
+ x = "foo-";
+ x.concat(wl.begin(), wl.end()); // iterator range wchar_t
+ PATH_IS(x, L"foo-wstring");
+
+ x = "foo-";
+ x += string("std::string"); // container char
+ PATH_IS(x, L"foo-std::string");
+
+ x = "foo-";
+ x += wstring(L"std::wstring"); // container wchar_t
+ PATH_IS(x, L"foo-std::wstring");
+
+ x = "foo-";
+ x += "array char"; // array char
+ PATH_IS(x, L"foo-array char");
+
+ x = "foo-";
+ x += L"array wchar"; // array wchar_t
+ PATH_IS(x, L"foo-array wchar");
+
+ x = "foo-";
+ x += s.c_str(); // const char* null terminated
+ PATH_IS(x, L"foo-string");
+
+ x = "foo-";
+ x += ws.c_str(); // const wchar_t* null terminated
+ PATH_IS(x, L"foo-wstring");
+
+ x = "foo-";
+ x += 'x'; // char
+ PATH_IS(x, L"foo-x");
+
+ x = "foo-";
+ x += L'x'; // wchar
+ PATH_IS(x, L"foo-x");
+}
+
+// test_observers ------------------------------------------------------------------//
+
+void test_observers()
+{
+ std::cout << "testing observers..." << std::endl;
+
+ path p0("abc");
+
+ CHECK(p0.native().size() == 3);
+ CHECK(p0.size() == 3);
+ CHECK(p0.string() == "abc");
+ CHECK(p0.string().size() == 3);
+ CHECK(p0.wstring() == L"abc");
+ CHECK(p0.wstring().size() == 3);
+
+ p0 = "";
+ CHECK(p0.native().size() == 0);
+ CHECK(p0.size() == 0);
+
+#ifdef BOOST_WINDOWS_API
+
+ path p("abc\\def/ghi");
+
+ CHECK(std::wstring(p.c_str()) == L"abc\\def/ghi");
+
+ CHECK(p.string() == "abc\\def/ghi");
+ CHECK(p.wstring() == L"abc\\def/ghi");
+
+ CHECK(p.generic_path().string() == "abc/def/ghi");
+ CHECK(p.generic_string() == "abc/def/ghi");
+ CHECK(p.generic_wstring() == L"abc/def/ghi");
+
+ CHECK(p.generic_string< string >() == "abc/def/ghi");
+ CHECK(p.generic_string< wstring >() == L"abc/def/ghi");
+ CHECK(p.generic_string< path::string_type >() == L"abc/def/ghi");
+
+#else // BOOST_POSIX_API
+
+ path p("abc\\def/ghi");
+
+ CHECK(string(p.c_str()) == "abc\\def/ghi");
+
+ CHECK(p.string() == "abc\\def/ghi");
+ CHECK(p.wstring() == L"abc\\def/ghi");
+
+ CHECK(p.generic_path().string() == "abc\\def/ghi");
+ CHECK(p.generic_string() == "abc\\def/ghi");
+ CHECK(p.generic_wstring() == L"abc\\def/ghi");
+
+ CHECK(p.generic_string< string >() == "abc\\def/ghi");
+ CHECK(p.generic_string< wstring >() == L"abc\\def/ghi");
+ CHECK(p.generic_string< path::string_type >() == "abc\\def/ghi");
+
+#endif
+}
+
+// test_relationals ----------------------------------------------------------------//
+
+void test_relationals()
+{
+ std::cout << "testing relationals..." << std::endl;
+
+ boost::hash< path > hash;
+
+#ifdef BOOST_WINDOWS_API
+ // this is a critical use case to meet user expectations
+ CHECK(path("c:\\abc") == path("c:/abc"));
+ CHECK(hash(path("c:\\abc")) == hash(path("c:/abc")));
+#endif
+
+ const path p("bar");
+ const path p2("baz");
+
+ CHECK(!(p < p));
+ CHECK(p < p2);
+ CHECK(!(p2 < p));
+ CHECK(p < "baz");
+ CHECK(p < string("baz"));
+ CHECK(p < L"baz");
+ CHECK(p < wstring(L"baz"));
+ CHECK(!("baz" < p));
+ CHECK(!(string("baz") < p));
+ CHECK(!(L"baz" < p));
+ CHECK(!(wstring(L"baz") < p));
+
+ CHECK(p == p);
+ CHECK(!(p == p2));
+ CHECK(!(p2 == p));
+ CHECK(p2 == "baz");
+ CHECK(p2 == string("baz"));
+ CHECK(p2 == L"baz");
+ CHECK(p2 == wstring(L"baz"));
+ CHECK("baz" == p2);
+ CHECK(string("baz") == p2);
+ CHECK(L"baz" == p2);
+ CHECK(wstring(L"baz") == p2);
+
+ CHECK(hash(p) == hash(p));
+ CHECK(hash(p) != hash(p2)); // Not strictly required, but desirable
+
+ CHECK(!(p != p));
+ CHECK(p != p2);
+ CHECK(p2 != p);
+
+ CHECK(p <= p);
+ CHECK(p <= p2);
+ CHECK(!(p2 <= p));
+
+ CHECK(!(p > p));
+ CHECK(!(p > p2));
+ CHECK(p2 > p);
+
+ CHECK(p >= p);
+ CHECK(!(p >= p2));
+ CHECK(p2 >= p);
+}
+
+// test_inserter_and_extractor -----------------------------------------------------//
+
+void test_inserter_and_extractor()
+{
+ std::cout << "testing inserter and extractor..." << std::endl;
+
+ path p1("foo bar"); // verify space in path roundtrips per ticket #3863
+ path p2;
+
+ std::stringstream ss;
+
+ CHECK(p1 != p2);
+ ss << p1;
+ ss >> p2;
+ CHECK(p1 == p2);
+
+ path wp1(L"foo bar");
+ path wp2;
+
+ std::wstringstream wss;
+
+ CHECK(wp1 != wp2);
+ wss << wp1;
+ wss >> wp2;
+ CHECK(wp1 == wp2);
+}
+
+// test_other_non_members ----------------------------------------------------------//
+
+void test_other_non_members()
+{
+ std::cout << "testing other_non_members..." << std::endl;
+
+ path p1("foo");
+ path p2("bar");
+
+ // operator /
+
+ CHECK(p1 / p2 == path("foo/bar").make_preferred());
+ CHECK("foo" / p2 == path("foo/bar").make_preferred());
+ CHECK(L"foo" / p2 == path("foo/bar").make_preferred());
+ CHECK(string("foo") / p2 == path("foo/bar").make_preferred());
+ CHECK(wstring(L"foo") / p2 == path("foo/bar").make_preferred());
+ CHECK(p1 / "bar" == path("foo/bar").make_preferred());
+ CHECK(p1 / L"bar" == path("foo/bar").make_preferred());
+ CHECK(p1 / string("bar") == path("foo/bar").make_preferred());
+ CHECK(p1 / wstring(L"bar") == path("foo/bar").make_preferred());
+
+ swap(p1, p2);
+
+ CHECK(p1 == "bar");
+ CHECK(p2 == "foo");
+
+ CHECK(!path("").filename_is_dot());
+ CHECK(!path("").filename_is_dot_dot());
+ CHECK(!path("..").filename_is_dot());
+ CHECK(!path(".").filename_is_dot_dot());
+ CHECK(!path("...").filename_is_dot_dot());
+ CHECK(path(".").filename_is_dot());
+ CHECK(path("..").filename_is_dot_dot());
+ CHECK(path("/.").filename_is_dot());
+ CHECK(path("/..").filename_is_dot_dot());
+ CHECK(!path("a.").filename_is_dot());
+ CHECK(!path("a..").filename_is_dot_dot());
+
+ // edge cases
+#if BOOST_FILESYSTEM_VERSION == 3
+ CHECK(path("foo/").filename() == path("."));
+ CHECK(path("foo/").filename_is_dot());
+#else
+ CHECK(path("foo/").filename() == path(""));
+ CHECK(!path("foo/").filename_is_dot());
+#endif
+#if BOOST_FILESYSTEM_VERSION == 3
+ CHECK(path("/").filename() == path("/"));
+#else
+ CHECK(path("/").filename() == path(""));
+#endif
+ CHECK(!path("/").filename_is_dot());
+#ifdef BOOST_WINDOWS_API
+ CHECK(path("c:.").filename() == path("."));
+ CHECK(path("c:.").filename_is_dot());
+#if BOOST_FILESYSTEM_VERSION == 3
+ CHECK(path("c:/").filename() == path("/"));
+#else
+ CHECK(path("c:/").filename() == path(""));
+#endif
+ CHECK(!path("c:\\").filename_is_dot());
+#else // BOOST_WINDOWS_API
+ CHECK(path("c:.").filename() == path("c:."));
+ CHECK(!path("c:.").filename_is_dot());
+#if BOOST_FILESYSTEM_VERSION == 3
+ CHECK(path("c:/").filename() == path("."));
+ CHECK(path("c:/").filename_is_dot());
+#else
+ CHECK(path("c:/").filename() == path(""));
+ CHECK(!path("c:/").filename_is_dot());
+#endif
+#endif // BOOST_WINDOWS_API
+
+ // check that the implementation code to make the edge cases above work right
+ // doesn't cause some non-edge cases to fail
+ CHECK(path("c:").filename() != path("."));
+ CHECK(!path("c:").filename_is_dot());
+
+ // examples from reference.html
+ std::cout << path(".").filename_is_dot(); // outputs 1
+ std::cout << path("/.").filename_is_dot(); // outputs 1
+ std::cout << path("foo/.").filename_is_dot(); // outputs 1
+ std::cout << path("foo/").filename_is_dot(); // outputs 1
+ std::cout << path("/").filename_is_dot(); // outputs 0
+ std::cout << path("/foo").filename_is_dot(); // outputs 0
+ std::cout << path("/foo.").filename_is_dot(); // outputs 0
+ std::cout << path("..").filename_is_dot(); // outputs 0
+ cout << std::endl;
+}
+
+// // test_modifiers ------------------------------------------------------------------//
+//
+// void test_modifiers()
+// {
+// std::cout << "testing modifiers..." << std::endl;
+//
+// }
+
+// test_iterators ------------------------------------------------------------------//
+
+void test_iterators()
+{
+ std::cout << "testing iterators..." << std::endl;
+
+ path p1;
+ CHECK(p1.begin() == p1.end());
+
+ path p2("/");
+ CHECK(p2.begin() != p2.end());
+ CHECK(*p2.begin() == "/");
+ CHECK(++p2.begin() == p2.end());
+
+ path p3("foo/bar/baz");
+
+ path::iterator it(p3.begin());
+ CHECK(p3.begin() != p3.end());
+ CHECK(*it == "foo");
+ CHECK(*++it == "bar");
+ CHECK(*++it == "baz");
+ CHECK(*--it == "bar");
+ CHECK(*--it == "foo");
+ CHECK(*++it == "bar");
+ CHECK(*++it == "baz");
+ CHECK(++it == p3.end());
+}
+
+// test_reverse_iterators ----------------------------------------------------------//
+
+void test_reverse_iterators()
+{
+ std::cout << "testing reverse_iterators..." << std::endl;
+
+ path p1;
+ CHECK(p1.rbegin() == p1.rend());
+
+ path p2("/");
+ CHECK(p2.rbegin() != p2.rend());
+ CHECK(*p2.rbegin() == "/");
+ CHECK(++p2.rbegin() == p2.rend());
+
+ path p3("foo/bar/baz");
+
+ path::reverse_iterator it(p3.rbegin());
+ CHECK(p3.rbegin() != p3.rend());
+ CHECK(*it == "baz");
+ CHECK(*++it == "bar");
+ CHECK(*++it == "foo");
+ CHECK(*--it == "bar");
+ CHECK(*--it == "baz");
+ CHECK(*++it == "bar");
+ CHECK(*++it == "foo");
+ CHECK(++it == p3.rend());
+}
+
+// test_modifiers ------------------------------------------------------------------//
+
+void test_modifiers()
+{
+ std::cout << "testing modifiers..." << std::endl;
+
+ CHECK(path("").remove_filename() == "");
+ CHECK(path("foo").remove_filename() == "");
+ CHECK(path("/foo").remove_filename() == "/");
+ CHECK(path("foo/bar").remove_filename() == "foo");
+ BOOST_TEST_EQ(path("foo/bar/").remove_filename(), path("foo/bar"));
+ BOOST_TEST_EQ(path(".").remove_filename(), path(""));
+ BOOST_TEST_EQ(path("./.").remove_filename(), path("."));
+ BOOST_TEST_EQ(path("/.").remove_filename(), path("/"));
+ BOOST_TEST_EQ(path("..").remove_filename(), path(""));
+ BOOST_TEST_EQ(path("../..").remove_filename(), path(".."));
+ BOOST_TEST_EQ(path("/..").remove_filename(), path("/"));
+ BOOST_TEST_EQ(path("//").remove_filename(), path(""));
+ BOOST_TEST_EQ(path("////").remove_filename(), path(""));
+}
+
+// test_decompositions -------------------------------------------------------------//
+
+void test_decompositions()
+{
+ std::cout << "testing decompositions..." << std::endl;
+
+ CHECK(path("").root_name().string() == "");
+ CHECK(path("foo").root_name().string() == "");
+ CHECK(path("/").root_name().string() == "");
+ CHECK(path("/foo").root_name().string() == "");
+ CHECK(path("//netname").root_name().string() == "//netname");
+ CHECK(path("//netname/foo").root_name().string() == "//netname");
+
+ CHECK(path("").root_directory().string() == "");
+ CHECK(path("foo").root_directory().string() == "");
+ CHECK(path("/").root_directory().string() == "/");
+ CHECK(path("/foo").root_directory().string() == "/");
+ CHECK(path("//netname").root_directory().string() == "");
+ CHECK(path("//netname/foo").root_directory().string() == "/");
+
+ CHECK(path("").root_path().string() == "");
+ CHECK(path("/").root_path().string() == "/");
+ CHECK(path("/foo").root_path().string() == "/");
+ CHECK(path("//netname").root_path().string() == "//netname");
+ CHECK(path("//netname/foo").root_path().string() == "//netname/");
+
+#ifdef BOOST_WINDOWS_API
+ CHECK(path("c:/foo").root_path().string() == "c:/");
+#endif
+
+ CHECK(path("").relative_path().string() == "");
+ CHECK(path("/").relative_path().string() == "");
+ CHECK(path("/foo").relative_path().string() == "foo");
+
+ CHECK(path("").parent_path().string() == "");
+ CHECK(path("/").parent_path().string() == "");
+ CHECK(path("/foo").parent_path().string() == "/");
+ CHECK(path("/foo/bar").parent_path().string() == "/foo");
+
+ CHECK(path("/foo/bar/baz.zoo").filename().string() == "baz.zoo");
+
+ CHECK(path("/foo/bar/baz.zoo").stem().string() == "baz");
+ CHECK(path("/foo/bar.woo/baz").stem().string() == "baz");
+
+ CHECK(path("foo.bar.baz.tar.bz2").extension().string() == ".bz2");
+ CHECK(path("/foo/bar/baz.zoo").extension().string() == ".zoo");
+ CHECK(path("/foo/bar.woo/baz").extension().string() == "");
+}
+
+// test_queries --------------------------------------------------------------------//
+
+void test_queries()
+{
+ std::cout << "testing queries..." << std::endl;
+
+ path p1("");
+ path p2("//netname/foo.doo");
+
+ CHECK(p1.empty());
+ CHECK(!p1.has_root_path());
+ CHECK(!p1.has_root_name());
+ CHECK(!p1.has_root_directory());
+ CHECK(!p1.has_relative_path());
+ CHECK(!p1.has_parent_path());
+ CHECK(!p1.has_filename());
+ CHECK(!p1.has_stem());
+ CHECK(!p1.has_extension());
+ CHECK(!p1.is_absolute());
+ CHECK(p1.is_relative());
+
+ CHECK(!p2.empty());
+ CHECK(p2.has_root_path());
+ CHECK(p2.has_root_name());
+ CHECK(p2.has_root_directory());
+ CHECK(p2.has_relative_path());
+ CHECK(p2.has_parent_path());
+ CHECK(p2.has_filename());
+ CHECK(p2.has_stem());
+ CHECK(p2.has_extension());
+ CHECK(p2.is_absolute());
+ CHECK(!p2.is_relative());
+}
+
+// test_imbue_locale ---------------------------------------------------------------//
+
+void test_imbue_locale()
+{
+ std::cout << "testing imbue locale..." << std::endl;
+
+ // weak test case for before/after states since we don't know what characters the
+ // default locale accepts.
+ path before("abc");
+
+ // So that tests are run with known encoding, use Boost UTF-8 codecvt
+ // \u2722 and \xE2\x9C\xA2 are UTF-16 and UTF-8 FOUR TEARDROP-SPOKED ASTERISK
+
+ std::locale global_loc = std::locale();
+ std::locale loc(global_loc, new fs::detail::utf8_codecvt_facet);
+ std::cout << " imbuing locale ..." << std::endl;
+ std::locale old_loc = path::imbue(loc);
+
+ std::cout << " testing with the imbued locale ..." << std::endl;
+ path p2("\xE2\x9C\xA2");
+ CHECK(p2.wstring().size() == 1);
+ CHECK(p2.wstring()[0] == 0x2722);
+
+ std::cout << " imbuing the original locale ..." << std::endl;
+ path::imbue(old_loc);
+
+ std::cout << " testing with the original locale ..." << std::endl;
+ path after("abc");
+ CHECK(before == after);
+
+ std::cout << " locale testing complete" << std::endl;
+}
+
+// test_codecvt_argument -----------------------------------------------------------//
+
+void test_codecvt_argument()
+{
+ std::cout << "testing codecvt arguments..." << std::endl;
+
+ const char* c1 = "a1";
+ const std::string s1(c1);
+ const std::wstring ws1(L"b2"); // off-by-one mimics test_codecvt
+ const std::string s2("y8");
+ const std::wstring ws2(L"z9");
+
+ test_codecvt cvt; // produces off-by-one values that will always differ from
+ // the system's default locale codecvt facet
+
+ int t = 0;
+
+ // constructors
+ std::cout << " constructors test " << ++t << std::endl;
+ path p(c1, cvt);
+ NATIVE_IS(p, s1, ws1);
+
+ std::cout << " test " << ++t << std::endl;
+ path p1(s1.begin(), s1.end(), cvt);
+ NATIVE_IS(p1, s1, ws1);
+
+ std::cout << " test " << ++t << std::endl;
+ path p2(ws2, cvt);
+ NATIVE_IS(p2, s2, ws2);
+
+ std::cout << " test " << ++t << std::endl;
+ path p3(ws2.begin(), ws2.end(), cvt);
+ NATIVE_IS(p3, s2, ws2);
+
+ // path p2(p1, cvt); // fails to compile, and that is OK
+
+ // assigns
+ p1.clear();
+ std::cout << " assigns test " << ++t << std::endl;
+ p1.assign(s1, cvt);
+ NATIVE_IS(p1, s1, ws1);
+ p1.clear();
+ std::cout << " test " << ++t << std::endl;
+ p1.assign(s1.begin(), s1.end(), cvt);
+ NATIVE_IS(p1, s1, ws1);
+ // p1.assign(p, cvt); // fails to compile, and that is OK
+
+ // appends
+ p1.clear();
+ std::cout << " appends test " << ++t << std::endl;
+ p1.append(s1, cvt);
+ NATIVE_IS(p1, s1, ws1);
+ p1.clear();
+ std::cout << " test " << ++t << std::endl;
+ p1.append(s1.begin(), s1.end(), cvt);
+ NATIVE_IS(p1, s1, ws1);
+ // p1.append(p, cvt); // fails to compile, and that is OK
+
+ // native observers
+ std::cout << " native observers test " << ++t << std::endl;
+ CHECK(p.string< std::string >(cvt) == s1);
+ std::cout << " test " << ++t << std::endl;
+ CHECK(p.string(cvt) == s1);
+ std::cout << " test " << ++t << std::endl;
+ CHECK(p.string< std::wstring >(cvt) == ws1);
+ std::cout << " test " << ++t << std::endl;
+ CHECK(p.wstring(cvt) == ws1);
+
+ // generic observers
+ std::cout << " generic observers test " << ++t << std::endl;
+ CHECK(p.generic_string< std::string >(cvt) == s1);
+ std::cout << " test " << ++t << std::endl;
+ CHECK(p.generic_string(cvt) == s1);
+ std::cout << " test " << ++t << std::endl;
+ CHECK(p.generic_string< std::wstring >(cvt) == ws1);
+ std::cout << " test " << ++t << std::endl;
+ CHECK(p.generic_wstring(cvt) == ws1);
+
+ std::cout << " codecvt arguments testing complete" << std::endl;
+}
+
+// test_overloads ------------------------------------------------------------------//
+
+void test_overloads()
+{
+ std::cout << "testing overloads..." << std::endl;
+ std::string sto("hello");
+ const char a[] = "goodbye";
+ path p1(sto);
+ path p2(sto.c_str());
+ path p3(a);
+ path p4("foo");
+
+ std::wstring wsto(L"hello");
+ const wchar_t wa[] = L"goodbye";
+ path wp1(wsto);
+ path wp2(wsto.c_str());
+ path wp3(wa);
+ path wp4(L"foo");
+}
+
+// test_error_handling -------------------------------------------------------------//
+
+class error_codecvt :
+ public std::codecvt< wchar_t, char, std::mbstate_t >
+{
+public:
+ explicit error_codecvt() :
+ std::codecvt< wchar_t, char, std::mbstate_t >()
+ {
+ }
+
+protected:
+ virtual bool do_always_noconv() const throw() { return false; }
+ virtual int do_encoding() const throw() { return 0; }
+
+ virtual std::codecvt_base::result do_in(std::mbstate_t&, const char*, const char*, const char*&, wchar_t*, wchar_t*, wchar_t*&) const
+ {
+ static std::codecvt_base::result r = std::codecvt_base::noconv;
+ if (r == std::codecvt_base::partial)
+ r = std::codecvt_base::error;
+ else if (r == std::codecvt_base::error)
+ r = std::codecvt_base::noconv;
+ else
+ r = std::codecvt_base::partial;
+ return r;
+ }
+
+ virtual std::codecvt_base::result do_out(std::mbstate_t&, const wchar_t*, const wchar_t*, const wchar_t*&, char*, char*, char*&) const
+ {
+ static std::codecvt_base::result r = std::codecvt_base::noconv;
+ if (r == std::codecvt_base::partial)
+ r = std::codecvt_base::error;
+ else if (r == std::codecvt_base::error)
+ r = std::codecvt_base::noconv;
+ else
+ r = std::codecvt_base::partial;
+ return r;
+ }
+
+ virtual std::codecvt_base::result do_unshift(std::mbstate_t&, char*, char*, char*&) const { return ok; }
+ virtual int do_length(std::mbstate_t&, const char*, const char*, std::size_t) const { return 0; }
+ virtual int do_max_length() const throw() { return 0; }
+};
+
+void test_error_handling()
+{
+ std::cout << "testing error handling..." << std::endl;
+
+ std::locale global_loc = std::locale();
+ std::locale loc(global_loc, new error_codecvt);
+ std::cout << " imbuing error locale ..." << std::endl;
+ std::locale old_loc = path::imbue(loc);
+
+ // These tests rely on a path constructor that fails in the locale conversion.
+ // Thus construction has to call codecvt. Force that by using a narrow string
+ // for Windows, and a wide string for POSIX.
+#ifdef BOOST_WINDOWS_API
+#define STRING_FOO_ "foo"
+#else
+#define STRING_FOO_ L"foo"
+#endif
+
+ {
+ std::cout << " testing std::codecvt_base::partial error..." << std::endl;
+ bool exception_thrown(false);
+ try
+ {
+ path(STRING_FOO_);
+ }
+ catch (const bs::system_error& ex)
+ {
+ exception_thrown = true;
+ BOOST_TEST_EQ(ex.code(), bs::error_code(std::codecvt_base::partial, fs::codecvt_error_category()));
+ }
+ catch (...)
+ {
+ std::cout << "***** unexpected exception type *****" << std::endl;
+ }
+ BOOST_TEST(exception_thrown);
+ }
+
+ {
+ std::cout << " testing std::codecvt_base::error error..." << std::endl;
+ bool exception_thrown(false);
+ try
+ {
+ path(STRING_FOO_);
+ }
+ catch (const bs::system_error& ex)
+ {
+ exception_thrown = true;
+ BOOST_TEST_EQ(ex.code(), bs::error_code(std::codecvt_base::error, fs::codecvt_error_category()));
+ }
+ catch (...)
+ {
+ std::cout << "***** unexpected exception type *****" << std::endl;
+ }
+ BOOST_TEST(exception_thrown);
+ }
+
+ {
+ std::cout << " testing std::codecvt_base::noconv error..." << std::endl;
+ bool exception_thrown(false);
+ try
+ {
+ path(STRING_FOO_);
+ }
+ catch (const bs::system_error& ex)
+ {
+ exception_thrown = true;
+ BOOST_TEST_EQ(ex.code(), bs::error_code(std::codecvt_base::noconv, fs::codecvt_error_category()));
+ }
+ catch (...)
+ {
+ std::cout << "***** unexpected exception type *****" << std::endl;
+ }
+ BOOST_TEST(exception_thrown);
+ }
+
+ std::cout << " restoring original locale ..." << std::endl;
+ path::imbue(old_loc);
+ std::cout << " testing error handling complete" << std::endl;
+}
+
+#if 0
+
+// // test_locales --------------------------------------------------------------------//
+//
+// void test_locales()
+// {
+// std::cout << "testing locales..." << std::endl;
+//
+// }
+
+// test_user_supplied_type ---------------------------------------------------------//
+
+typedef std::basic_string<int> user_string;
+
+} // unnamed namespace
+
+namespace boost {
+namespace filesystem {
+namespace path_traits {
+
+template<> struct is_iterator< const user_string::value_type* > { static const bool value = true; };
+template<> struct is_iterator< user_string::value_type* > { static const bool value = true; };
+template<> struct is_iterator< user_string::iterator > { static const bool value = true; };
+template<> struct is_iterator< user_string::const_iterator > { static const bool value = true; };
+template<> struct is_container< user_string > { static const bool value = true; };
+
+template<>
+void append< user_string::value_type >(const user_string::value_type* begin,
+ const user_string::value_type* end, string_type& target, system::error_code& ec)
+{
+ for (; begin != end && *begin; ++begin)
+ target += *begin + 1; // change so that results distinguishable from char cvts
+}
+
+#ifdef __GNUC__
+// This specialization shouldn't be needed, and VC++, Intel, and others work
+// fine without it. But gcc 4.3.2, and presumably other versions, need it.
+template<>
+void append< user_string::value_type >(const user_string::value_type* begin,
+ string_type& target, system::error_code& ec)
+{
+ path_traits::append<user_string::value_type>(begin,
+ static_cast<const user_string::value_type *>(0), target, ec);
+}
+#endif
+
+template<>
+user_string convert< user_string >(string_type const& source, system::error_code& ec)
+{
+ user_string temp;
+ for (string_type::const_iterator it = source.begin(); it != source.end(); ++it)
+ temp += *it - 1;
+ return temp;
+}
+
+} // namespace path_traits
+} // namespace filesystem
+} // namespace boost
+
+namespace {
+
+void test_user_supplied_type()
+{
+ std::cout << "testing user supplied type..." << std::endl;
+
+ user_string::value_type usr_c_str[] = { 'a', 'b', 'c', 0 };
+ user_string usr(usr_c_str);
+
+ path p1(usr.c_str());
+ CHECK(p1 == path("bcd"));
+ CHECK(p1 == "bcd");
+ user_string s1(p1.string<user_string>());
+ CHECK(s1 == usr);
+}
+
+#endif
+
+inline const char* macro_value(const char* name, const char* value)
+{
+ static const char* no_value = "[no value]";
+ static const char* not_defined = "[not defined]";
+
+ //if (0 != strcmp(name, value + 1)) // macro is defined
+ //{
+ // if (value[1])
+ // return value;
+ // else
+ // return no_value;
+ //}
+ //return not_defined;
+
+ return 0 == strcmp(name, value + 1) ? not_defined : (value[1] ? value : no_value);
+}
+
+#define BOOST_MACRO_VALUE(X) macro_value(#X, BOOST_STRINGIZE(=X))
+
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+// //
+// main //
+// //
+//--------------------------------------------------------------------------------------//
+
+int test_main(int, char*[])
+{
+// document state of critical macros
+#ifdef BOOST_POSIX_API
+ cout << "BOOST_POSIX_API" << endl;
+ BOOST_TEST(path::preferred_separator == '/');
+#endif
+#ifdef BOOST_WINDOWS_API
+ cout << "BOOST_WINDOWS_API" << endl;
+ BOOST_TEST(path::preferred_separator == '\\');
+#endif
+
+ cout << "BOOST_FILESYSTEM_DECL "
+ << BOOST_MACRO_VALUE(BOOST_FILESYSTEM_DECL) << endl;
+
+ //#ifdef BOOST_FILESYSTEM_DECL
+ // cout << "BOOST_FILESYSTEM_DECL is defined as "
+ // << BOOST_STRINGIZE(BOOST_FILESYSTEM_DECL) << endl;
+ //#else
+ // cout << "BOOST_FILESYSTEM_DECL is not defined" << endl;
+ //#endif
+
+ l.push_back('s');
+ l.push_back('t');
+ l.push_back('r');
+ l.push_back('i');
+ l.push_back('n');
+ l.push_back('g');
+
+ wl.push_back(L'w');
+ wl.push_back(L's');
+ wl.push_back(L't');
+ wl.push_back(L'r');
+ wl.push_back(L'i');
+ wl.push_back(L'n');
+ wl.push_back(L'g');
+
+ v.push_back('f');
+ v.push_back('u');
+ v.push_back('z');
+
+ wv.push_back(L'w');
+ wv.push_back(L'f');
+ wv.push_back(L'u');
+ wv.push_back(L'z');
+
+ test_overloads();
+ test_constructors();
+ test_assignments();
+ test_move_construction_and_assignment();
+ test_appends();
+ test_concats();
+ test_modifiers();
+ test_observers();
+ test_relationals();
+ test_inserter_and_extractor();
+ test_other_non_members();
+ test_iterators();
+ test_reverse_iterators();
+ test_decompositions();
+ test_queries();
+ test_imbue_locale();
+ test_codecvt_argument();
+ test_error_handling();
+
+#if 0
+ test_user_supplied_type();
+#endif
+
+ std::string foo("\\abc");
+ const char* bar = "/abc";
+
+ if (foo == bar)
+ cout << "unintended consequence\n";
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/quick.cpp b/src/boost/libs/filesystem/test/quick.cpp
new file mode 100644
index 000000000..b38ac4bc6
--- /dev/null
+++ b/src/boost/libs/filesystem/test/quick.cpp
@@ -0,0 +1,24 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+// See library home page at http://www.boost.org/libs/system
+
+#include <boost/filesystem.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+namespace fs = boost::filesystem;
+
+int main()
+{
+ fs::path p1("a");
+ fs::path p2 = p1 / "b";
+
+ BOOST_TEST_EQ(p2, "a/b");
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/relative_test.cpp b/src/boost/libs/filesystem/test/relative_test.cpp
new file mode 100644
index 000000000..e2d7b13e1
--- /dev/null
+++ b/src/boost/libs/filesystem/test/relative_test.cpp
@@ -0,0 +1,119 @@
+// filesystem relative_test.cpp ---------------------------------------------------- //
+
+// Copyright Beman Dawes 2015
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+// ---------------------------------------------------------------------------------- //
+//
+// At least initially, development is easier if these tests are in a separate file.
+//
+// ---------------------------------------------------------------------------------- //
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/detail/lightweight_test_report.hpp>
+#include <iostream>
+
+using boost::filesystem::path;
+using std::cout;
+using std::endl;
+
+namespace {
+
+void lexically_relative_test()
+{
+ cout << "lexically_relative_test..." << endl;
+
+ BOOST_TEST(path("").lexically_relative("") == "");
+ BOOST_TEST(path("").lexically_relative("/foo") == "");
+ BOOST_TEST(path("/foo").lexically_relative("") == "");
+ BOOST_TEST(path("/foo").lexically_relative("/foo") == ".");
+ BOOST_TEST(path("").lexically_relative("foo") == "");
+ BOOST_TEST(path("foo").lexically_relative("") == "");
+ BOOST_TEST(path("foo").lexically_relative("foo") == ".");
+
+ BOOST_TEST(path("a/b/c").lexically_relative("a") == "b/c");
+ BOOST_TEST(path("a//b//c").lexically_relative("a") == "b/c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b") == "c");
+ BOOST_TEST(path("a///b//c").lexically_relative("a//b") == "c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/c") == ".");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/c/x") == "..");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/x") == "../b/c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/x") == "../c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/x/y") == "../../b/c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/x/y") == "../../c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/c/x/y/z") == "../../..");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/") == "b/c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/.") == "b/c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/./") == "b/c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/..") == "");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/../") == "");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/d/..") == "c");
+ BOOST_TEST(path("a/b/c").lexically_relative("a/b/d/../") == "c");
+
+ // paths unrelated except first element, and first element is root directory
+ BOOST_TEST(path("/a/b/c").lexically_relative("/x") == "../a/b/c");
+ BOOST_TEST(path("/a/b/c").lexically_relative("/x/y") == "../../a/b/c");
+ BOOST_TEST(path("/a/b/c").lexically_relative("/x/y/z") == "../../../a/b/c");
+
+ // paths unrelated
+ BOOST_TEST(path("a/b/c").lexically_relative("x") == "");
+ BOOST_TEST(path("a/b/c").lexically_relative("x/y") == "");
+ BOOST_TEST(path("a/b/c").lexically_relative("x/y/z") == "");
+ BOOST_TEST(path("a/b/c").lexically_relative("/x") == "");
+ BOOST_TEST(path("a/b/c").lexically_relative("/x/y") == "");
+ BOOST_TEST(path("a/b/c").lexically_relative("/x/y/z") == "");
+ BOOST_TEST(path("a/b/c").lexically_relative("/a/b/c") == "");
+
+ // TODO: add some Windows-only test cases that probe presence or absence of
+ // drive specifier-and root-directory
+
+ // Some tests from Jamie Allsop's paper
+ BOOST_TEST(path("/a/d").lexically_relative("/a/b/c") == "../../d");
+ BOOST_TEST(path("/a/b/c").lexically_relative("/a/d") == "../b/c");
+#ifdef BOOST_WINDOWS_API
+ BOOST_TEST(path("c:\\y").lexically_relative("c:\\x") == "../y");
+#else
+ BOOST_TEST(path("c:\\y").lexically_relative("c:\\x") == "");
+#endif
+ BOOST_TEST(path("d:\\y").lexically_relative("c:\\x") == "");
+
+ // From issue #1976
+ BOOST_TEST(path("/foo/new").lexically_relative("/foo/bar") == "../new");
+}
+
+void lexically_proximate_test()
+{
+ cout << "lexically_proximate_test..." << endl;
+ // paths unrelated
+ BOOST_TEST(path("a/b/c").lexically_proximate("x") == "a/b/c");
+}
+
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+// //
+// main //
+// //
+//--------------------------------------------------------------------------------------//
+
+int test_main(int, char*[])
+{
+// document state of critical macros
+#ifdef BOOST_POSIX_API
+ cout << "BOOST_POSIX_API" << endl;
+#endif
+#ifdef BOOST_WINDOWS_API
+ cout << "BOOST_WINDOWS_API" << endl;
+#endif
+
+ lexically_relative_test();
+ lexically_proximate_test();
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/sample_test.cpp b/src/boost/libs/filesystem/test/sample_test.cpp
new file mode 100644
index 000000000..a014d6c21
--- /dev/null
+++ b/src/boost/libs/filesystem/test/sample_test.cpp
@@ -0,0 +1,62 @@
+// filesystem sample_test.cpp ----------------------------------------------//
+
+// Copyright Beman Dawes 2012
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// --------------------------------------------------------------------------//
+//
+// This program provides a template for bug reporting test cases.
+//
+// --------------------------------------------------------------------------//
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <iostream>
+#include <string>
+#include <cstring>
+#ifndef BOOST_LIGHTWEIGHT_MAIN
+#include <boost/test/prg_exec_monitor.hpp>
+#else
+#include <boost/detail/lightweight_main.hpp>
+#endif
+
+namespace fs = boost::filesystem;
+using fs::path;
+using std::cout;
+using std::endl;
+using std::string;
+using std::wstring;
+
+namespace {
+bool cleanup = true;
+}
+
+// cpp_main ----------------------------------------------------------------//
+
+int cpp_main(int argc, char* argv[])
+{
+ if (argc > 1 && std::strcmp(argv[1], "--no-cleanup") == 0)
+ cleanup = false;
+
+ // Test cases go after this block of comments
+ // Use test case macros from boost/core/lightweight_test.hpp:
+ //
+ // BOOST_TEST(predicate); // test passes if predicate evaluates to true
+ // BOOST_TEST_EQ(x, y); // test passes if x == y
+ // BOOST_TEST_NE(x, y); // test passes if x != y
+ // BOOST_ERROR(msg); // test fails, outputs msg
+ // Examples:
+ // BOOST_TEST(path("f00").size() == 3); // test passes
+ // BOOST_TEST_EQ(path("f00").size(), 3); // test passes
+ // BOOST_MSG("Oops!"); // test fails, outputs "Oops!"
+
+ if (cleanup)
+ {
+ // Remove any test files or directories here
+ }
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/filesystem/test/test_cmake/CMakeLists.txt b/src/boost/libs/filesystem/test/test_cmake/CMakeLists.txt
new file mode 100644
index 000000000..71e88c7bb
--- /dev/null
+++ b/src/boost/libs/filesystem/test/test_cmake/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright 2020 Andrey Semashev
+#
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
+#
+# NOTE: This does NOT run the unit tests for Boost.Filesystem.
+# It only tests, if the CMakeLists.txt file in it's root works as expected
+
+cmake_minimum_required(VERSION 3.5)
+
+project(BoostFilesystemCMakeSelfTest)
+
+# Use experimental superproject to pull library dependencies recursively
+set(BOOST_ENABLE_CMAKE 1)
+add_subdirectory(../../../.. "${CMAKE_CURRENT_BINARY_DIR}/boost_superproject")
+
+add_definitions(-DBOOST_ALL_NO_LIB)
+
+add_executable(boost_filesystem_cmake_self_test main.cpp)
+target_link_libraries(boost_filesystem_cmake_self_test Boost::filesystem)
diff --git a/src/boost/libs/filesystem/test/test_cmake/main.cpp b/src/boost/libs/filesystem/test/test_cmake/main.cpp
new file mode 100644
index 000000000..ea18dee5a
--- /dev/null
+++ b/src/boost/libs/filesystem/test/test_cmake/main.cpp
@@ -0,0 +1,13 @@
+// Copyright (c) 2020 Andrey Semashev
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/filesystem.hpp>
+
+int main()
+{
+ boost::filesystem::path p(".");
+ boost::filesystem::is_directory(p);
+}
diff --git a/src/boost/libs/filesystem/test/test_codecvt.hpp b/src/boost/libs/filesystem/test/test_codecvt.hpp
new file mode 100644
index 000000000..d5fc61701
--- /dev/null
+++ b/src/boost/libs/filesystem/test/test_codecvt.hpp
@@ -0,0 +1,72 @@
+// test_codecvt.hpp ------------------------------------------------------------------//
+
+// Copyright Beman Dawes 2009, 2010
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#ifndef BOOST_FILESYSTEM_TEST_CODECVT_HPP
+#define BOOST_FILESYSTEM_TEST_CODECVT_HPP
+
+#include <boost/filesystem/config.hpp>
+#include <locale>
+#include <cwchar> // for mbstate_t
+
+//------------------------------------------------------------------------------------//
+// //
+// class test_codecvt //
+// //
+// Warning: partial implementation; even do_in and do_out only partially meet the //
+// standard library specifications as the "to" buffer must hold the entire result. //
+// //
+// The value of a wide character is the value of the corresponding narrow character //
+// plus 1. This ensures that compares against expected values will fail if the //
+// code conversion did not occur as expected. //
+// //
+//------------------------------------------------------------------------------------//
+
+class test_codecvt :
+ public std::codecvt< wchar_t, char, std::mbstate_t >
+{
+public:
+ explicit test_codecvt() :
+ std::codecvt< wchar_t, char, std::mbstate_t >()
+ {
+ }
+
+protected:
+ virtual bool do_always_noconv() const throw() { return false; }
+ virtual int do_encoding() const throw() { return 0; }
+
+ virtual std::codecvt_base::result do_in(std::mbstate_t&, const char* from, const char* from_end, const char*& from_next, wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const
+ {
+ for (; from != from_end && to != to_end; ++from, ++to)
+ *to = wchar_t(*from + 1);
+ if (to == to_end)
+ return error;
+ *to = L'\0';
+ from_next = from;
+ to_next = to;
+ return ok;
+ }
+
+ virtual std::codecvt_base::result do_out(std::mbstate_t&, const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, char* to, char* to_end, char*& to_next) const
+ {
+ for (; from != from_end && to != to_end; ++from, ++to)
+ *to = static_cast< char >(*from - 1);
+ if (to == to_end)
+ return error;
+ *to = '\0';
+ from_next = from;
+ to_next = to;
+ return ok;
+ }
+
+ virtual std::codecvt_base::result do_unshift(std::mbstate_t&, char* /*from*/, char* /*to*/, char*& /*next*/) const { return ok; }
+ virtual int do_length(std::mbstate_t&, const char* /*from*/, const char* /*from_end*/, std::size_t /*max*/) const { return 0; }
+ virtual int do_max_length() const throw() { return 0; }
+};
+
+#endif // BOOST_FILESYSTEM_TEST_CODECVT_HPP
diff --git a/src/boost/libs/filesystem/test/windows_attributes.cpp b/src/boost/libs/filesystem/test/windows_attributes.cpp
new file mode 100644
index 000000000..cdca5355e
--- /dev/null
+++ b/src/boost/libs/filesystem/test/windows_attributes.cpp
@@ -0,0 +1,106 @@
+// windows_attributes ----------------------------------------------------------------//
+
+// Copyright Beman Dawes 2010
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+
+// Useful for debugging status related issues //
+
+//--------------------------------------------------------------------------------------//
+
+#include <boost/filesystem.hpp>
+#include <boost/detail/lightweight_main.hpp>
+#include <windows.h>
+#include <map>
+#include <utility>
+#include <iostream>
+#include <string>
+
+using std::make_pair;
+namespace fs = boost::filesystem;
+
+int cpp_main(int argc, char* argv[])
+{
+ typedef std::map< DWORD, std::string > decode_type;
+ decode_type table;
+
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_ARCHIVE, "FILE_ATTRIBUTE_ARCHIVE"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_COMPRESSED, "FILE_ATTRIBUTE_COMPRESSED"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_DEVICE, "FILE_ATTRIBUTE_DEVICE"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_DIRECTORY, "FILE_ATTRIBUTE_DIRECTORY"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_ENCRYPTED, "FILE_ATTRIBUTE_ENCRYPTED"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_HIDDEN, "FILE_ATTRIBUTE_HIDDEN"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "FILE_ATTRIBUTE_NOT_CONTENT_INDEXED"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_OFFLINE, "FILE_ATTRIBUTE_OFFLINE"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_READONLY, "FILE_ATTRIBUTE_READONLY"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_REPARSE_POINT, "FILE_ATTRIBUTE_REPARSE_POINT"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_SPARSE_FILE, "FILE_ATTRIBUTE_SPARSE_FILE"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_SYSTEM, "FILE_ATTRIBUTE_SYSTEM"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_TEMPORARY, "FILE_ATTRIBUTE_TEMPORARY"));
+ table.insert(make_pair< DWORD, std::string >(FILE_ATTRIBUTE_VIRTUAL, "FILE_ATTRIBUTE_VIRTUAL"));
+
+ if (argc < 2)
+ {
+ std::cout << "Usage: windows_attributes path\n";
+ return 1;
+ }
+
+ // report Win32 ::GetFileAttributesA()
+
+ DWORD at(::GetFileAttributesA(argv[1]));
+ if (at == INVALID_FILE_ATTRIBUTES)
+ {
+ std::cout << "GetFileAttributes(\"" << argv[1]
+ << "\") returned INVALID_FILE_ATTRIBUTES\n";
+ return 0;
+ }
+
+ std::cout << "GetFileAttributes(\"" << argv[1]
+ << "\") returned ";
+
+ bool bar = false;
+ for (decode_type::iterator it = table.begin(); it != table.end(); ++it)
+ {
+ if (!(it->first & at))
+ continue;
+ if (bar)
+ std::cout << " | ";
+ bar = true;
+ std::cout << it->second;
+ at &= ~it->first;
+ }
+ std::cout << std::endl;
+
+ if (at)
+ std::cout << "plus unknown attributes " << at << std::endl;
+
+ // report Boost Filesystem file_type
+
+ fs::file_status stat = fs::status(argv[1]);
+
+ const char* types[] =
+ {
+ "status_error",
+ "file_not_found",
+ "regular_file",
+ "directory_file",
+ // the following may not apply to some operating systems or file systems
+ "symlink_file",
+ "block_file",
+ "character_file",
+ "fifo_file",
+ "socket_file",
+ "reparse_file", // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink
+ "type_unknown" // file does exist", but isn't one of the above types or
+ // we don't have strong enough permission to find its type
+ };
+
+ std::cout << "boost::filesystem::status().type() is " << types[stat.type()] << std::endl;
+
+ return 0;
+}