diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index e4e0e27..08d458e 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -295,7 +295,7 @@ //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ghc::filesystem version in decimal (major * 10000 + minor * 100 + patch) -#define GHC_FILESYSTEM_VERSION 10504L +#define GHC_FILESYSTEM_VERSION 10505L #if !defined(GHC_WITH_EXCEPTIONS) && (defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)) #define GHC_WITH_EXCEPTIONS @@ -351,7 +351,7 @@ bool has_executable_extension(const path& p); } #endif -// 30.10.8 class path +// [fs.class.path] class path class GHC_FS_API_CLASS path #if defined(GHC_OS_WINDOWS) && !defined(GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE) #define GHC_USE_WCHAR_T @@ -372,7 +372,7 @@ public: using string_type = std::basic_string; using path_helper_base::preferred_separator; - // 30.10.10.1 enumeration format + // [fs.enum.path.format] enumeration format /// The path format in which the constructor argument is given. enum format { generic_format, ///< The generic format, internally used by @@ -413,7 +413,7 @@ public: path>::type; template using path_type_EcharT = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value, path>::type; - // 30.10.8.4.1 constructors and destructor + // [fs.path.construct] constructors and destructor path() noexcept; path(const path& p); path(path&& p) noexcept; @@ -430,7 +430,7 @@ public: #endif ~path(); - // 30.10.8.4.2 assignments + // [fs.path.assign] assignments path& operator=(const path& p); path& operator=(path&& p) noexcept; path& operator=(string_type&& source); @@ -442,7 +442,7 @@ public: template path& assign(InputIterator first, InputIterator last); - // 30.10.8.4.3 appends + // [fs.path.append] appends path& operator/=(const path& p); template path& operator/=(const Source& source); @@ -451,7 +451,7 @@ public: template path& append(InputIterator first, InputIterator last); - // 30.10.8.4.4 concatenation + // [fs.path.concat] concatenation path& operator+=(const path& x); path& operator+=(const string_type& x); #ifdef GHC_WITH_STRING_VIEW @@ -468,7 +468,7 @@ public: template path& concat(InputIterator first, InputIterator last); - // 30.10.8.4.5 modifiers + // [fs.path.modifiers] modifiers void clear() noexcept; path& make_preferred(); path& remove_filename(); @@ -476,7 +476,7 @@ public: path& replace_extension(const path& replacement = path()); void swap(path& rhs) noexcept; - // 30.10.8.4.6 native format observers + // [fs.path.native.obs] native format observers const string_type& native() const noexcept; const value_type* c_str() const noexcept; operator string_type() const; @@ -492,7 +492,7 @@ public: std::u16string u16string() const; std::u32string u32string() const; - // 30.10.8.4.7 generic format observers + // [fs.path.generic.obs] generic format observers template , class Allocator = std::allocator> std::basic_string generic_string(const Allocator& a = Allocator()) const; std::string generic_string() const; @@ -505,7 +505,7 @@ public: std::u16string generic_u16string() const; std::u32string generic_u32string() const; - // 30.10.8.4.8 compare + // [fs.path.compare] compare int compare(const path& p) const noexcept; int compare(const string_type& s) const; #ifdef GHC_WITH_STRING_VIEW @@ -513,7 +513,7 @@ public: #endif int compare(const value_type* s) const; - // 30.10.8.4.9 decomposition + // [fs.path.decompose] decomposition path root_name() const; path root_directory() const; path root_path() const; @@ -523,7 +523,7 @@ public: path stem() const; path extension() const; - // 30.10.8.4.10 query + // [fs.path.query] query bool empty() const noexcept; bool has_root_name() const; bool has_root_directory() const; @@ -536,12 +536,12 @@ public: bool is_absolute() const; bool is_relative() const; - // 30.10.8.4.11 generation + // [fs.path.gen] generation path lexically_normal() const; path lexically_relative(const path& base) const; path lexically_proximate(const path& base) const; - // 30.10.8.5 iterators + // [fs.path.itr] iterators class iterator; using const_iterator = iterator; iterator begin() const; @@ -594,7 +594,7 @@ private: #endif }; -// 30.10.8.6 path non-member functions +// [fs.path.nonmember] path non-member functions GHC_FS_API void swap(path& lhs, path& rhs) noexcept; GHC_FS_API size_t hash_value(const path& p) noexcept; #ifdef GHC_HAS_THREEWAY_COMP @@ -608,13 +608,13 @@ GHC_FS_API bool operator>(const path& lhs, const path& rhs) noexcept; GHC_FS_API bool operator>=(const path& lhs, const path& rhs) noexcept; GHC_FS_API path operator/(const path& lhs, const path& rhs); -// 30.10.8.6.1 path inserter and extractor +// [fs.path.io] path inserter and extractor template std::basic_ostream& operator<<(std::basic_ostream& os, const path& p); template std::basic_istream& operator>>(std::basic_istream& is, path& p); -// 30.10.8.6.2 path factory functions +// [pfs.path.factory] path factory functions template > #if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) [[deprecated("use ghc::filesystem::path::path() with std::u8string instead")]] @@ -626,7 +626,7 @@ template #endif path u8path(InputIterator first, InputIterator last); -// 30.10.9 class filesystem_error +// [fs.class.filesystem_error] class filesystem_error class GHC_FS_API_CLASS filesystem_error : public std::system_error { public: @@ -683,7 +683,8 @@ struct space_info uintmax_t available; }; -// 30.10.10, enumerations +// [fs.enum] enumerations +// [fs.enum.file_type] enum class file_type { none, not_found, @@ -697,6 +698,7 @@ enum class file_type { unknown, }; +// [fs.enum.perms] enum class perms : uint16_t { none = 0, @@ -724,6 +726,7 @@ enum class perms : uint16_t { unknown = 0xffff }; +// [fs.enum.perm.opts] enum class perm_options : uint16_t { replace = 3, add = 1, @@ -731,6 +734,7 @@ enum class perm_options : uint16_t { nofollow = 4, }; +// [fs.enum.copy.opts] enum class copy_options : uint16_t { none = 0, @@ -750,17 +754,18 @@ enum class copy_options : uint16_t { #endif }; +// [fs.enum.dir.opts] enum class directory_options : uint16_t { none = 0, follow_directory_symlink = 1, skip_permission_denied = 2, }; -// 30.10.11 class file_status +// [fs.class.file_status] class file_status class GHC_FS_API_CLASS file_status { public: - // 30.10.11.1 constructors and destructor + // [fs.file_status.cons] constructors and destructor file_status() noexcept; explicit file_status(file_type ft, perms prms = perms::unknown) noexcept; file_status(const file_status&) noexcept; @@ -769,10 +774,10 @@ public: // assignments: file_status& operator=(const file_status&) noexcept; file_status& operator=(file_status&&) noexcept; - // 30.10.11.3 modifiers + // [fs.file_status.mods] modifiers void type(file_type ft) noexcept; void permissions(perms prms) noexcept; - // 30.10.11.2 observers + // [fs.file_status.obs] observers file_type type() const noexcept; perms permissions() const noexcept; friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); } @@ -783,11 +788,11 @@ private: using file_time_type = std::chrono::time_point; -// 30.10.12 Class directory_entry +// [fs.class.directory_entry] Class directory_entry class GHC_FS_API_CLASS directory_entry { public: - // 30.10.12.1 constructors and destructor + // [fs.dir.entry.cons] constructors and destructor directory_entry() noexcept = default; directory_entry(const directory_entry&) = default; directory_entry(directory_entry&&) noexcept = default; @@ -801,7 +806,7 @@ public: directory_entry& operator=(const directory_entry&) = default; directory_entry& operator=(directory_entry&&) noexcept = default; - // 30.10.12.2 modifiers + // [fs.dir.entry.mods] modifiers #ifdef GHC_WITH_EXCEPTIONS void assign(const path& p); void replace_filename(const path& p); @@ -811,7 +816,7 @@ public: void replace_filename(const path& p, std::error_code& ec); void refresh(std::error_code& ec) noexcept; - // 30.10.12.3 observers + // [fs.dir.entry.obs] observers const filesystem::path& path() const noexcept; operator const filesystem::path&() const noexcept; #ifdef GHC_WITH_EXCEPTIONS @@ -876,7 +881,7 @@ private: time_t _last_write_time = 0; }; -// 30.10.13 Class directory_iterator +// [fs.class.directory.iterator] Class directory_iterator class GHC_FS_API_CLASS directory_iterator { public: @@ -901,7 +906,7 @@ public: using pointer = const directory_entry*; using reference = const directory_entry&; - // 30.10.13.1 member functions + // [fs.dir.itr.members] member functions directory_iterator() noexcept; #ifdef GHC_WITH_EXCEPTIONS explicit directory_iterator(const path& p); @@ -921,7 +926,7 @@ public: #endif directory_iterator& increment(std::error_code& ec) noexcept; - // other members as required by 27.2.3, input iterators + // other members as required by [input.iterators] #ifdef GHC_WITH_EXCEPTIONS proxy operator++(int) { @@ -939,11 +944,11 @@ private: std::shared_ptr _impl; }; -// 30.10.13.2 directory_iterator non-member functions +// [fs.dir.itr.nonmembers] directory_iterator non-member functions GHC_FS_API directory_iterator begin(directory_iterator iter) noexcept; GHC_FS_API directory_iterator end(const directory_iterator&) noexcept; -// 30.10.14 class recursive_directory_iterator +// [fs.class.re.dir.itr] class recursive_directory_iterator class GHC_FS_API_CLASS recursive_directory_iterator { public: @@ -953,7 +958,7 @@ public: using pointer = const directory_entry*; using reference = const directory_entry&; - // 30.10.14.1 constructors and destructor + // [fs.rec.dir.itr.members] constructors and destructor recursive_directory_iterator() noexcept; #ifdef GHC_WITH_EXCEPTIONS explicit recursive_directory_iterator(const path& p); @@ -965,7 +970,7 @@ public: recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept; ~recursive_directory_iterator(); - // 30.10.14.1 observers + // [fs.rec.dir.itr.members] observers directory_options options() const; int depth() const; bool recursion_pending() const; @@ -973,7 +978,7 @@ public: const directory_entry& operator*() const; const directory_entry* operator->() const; - // 30.10.14.1 modifiers recursive_directory_iterator& + // [fs.rec.dir.itr.members] modifiers recursive_directory_iterator& recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs); recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept; #ifdef GHC_WITH_EXCEPTIONS @@ -987,7 +992,7 @@ public: void pop(std::error_code& ec); void disable_recursion_pending(); - // other members as required by 27.2.3, input iterators + // other members as required by [input.iterators] #ifdef GHC_WITH_EXCEPTIONS directory_iterator::proxy operator++(int) { @@ -1014,11 +1019,11 @@ private: std::shared_ptr _impl; }; -// 30.10.14.2 directory_iterator non-member functions +// [fs.rec.dir.itr.nonmembers] directory_iterator non-member functions GHC_FS_API recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; GHC_FS_API recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; -// 30.10.15 filesystem operations +// [fs.op.funcs] filesystem operations #ifdef GHC_WITH_EXCEPTIONS GHC_FS_API path absolute(const path& p); GHC_FS_API path canonical(const path& p); @@ -2299,7 +2304,7 @@ GHC_INLINE u8arguments::u8arguments(int& argc, char**& argv) } //----------------------------------------------------------------------------- -// 30.10.8.4.1 constructors and destructor +// [fs.path.construct] constructors and destructor GHC_INLINE path::path() noexcept {} @@ -2354,7 +2359,7 @@ inline path::path(InputIterator first, InputIterator last, const std::locale& lo GHC_INLINE path::~path() {} //----------------------------------------------------------------------------- -// 30.10.8.4.2 assignments +// [fs.path.assign] assignments GHC_INLINE path& path::operator=(const path& p) { @@ -2427,7 +2432,7 @@ inline path& path::assign(InputIterator first, InputIterator last) #ifdef GHC_EXPAND_IMPL //----------------------------------------------------------------------------- -// 30.10.8.4.3 appends +// [fs.path.append] appends GHC_INLINE path& path::operator/=(const path& p) { @@ -2508,7 +2513,7 @@ inline path& path::append(InputIterator first, InputIterator last) #ifdef GHC_EXPAND_IMPL //----------------------------------------------------------------------------- -// 30.10.8.4.4 concatenation +// [fs.path.concat] concatenation GHC_INLINE path& path::operator+=(const path& x) { @@ -2590,7 +2595,7 @@ inline path& path::concat(InputIterator first, InputIterator last) #ifdef GHC_EXPAND_IMPL //----------------------------------------------------------------------------- -// 30.10.8.4.5 modifiers +// [fs.path.modifiers] modifiers GHC_INLINE void path::clear() noexcept { _path.clear(); @@ -2640,7 +2645,7 @@ GHC_INLINE void path::swap(path& rhs) noexcept } //----------------------------------------------------------------------------- -// 30.10.8.4.6, native format observers +// [fs.path.native.obs] native format observers GHC_INLINE const path::string_type& path::native() const noexcept { return _path; @@ -2723,7 +2728,7 @@ GHC_INLINE std::u32string path::u32string() const #endif // GHC_EXPAND_IMPL //----------------------------------------------------------------------------- -// 30.10.8.4.7, generic format observers +// [fs.path.generic.obs] generic format observers template inline std::basic_string path::generic_string(const Allocator& a) const { @@ -2803,7 +2808,7 @@ GHC_INLINE std::u32string path::generic_u32string() const } //----------------------------------------------------------------------------- -// 30.10.8.4.8, compare +// [fs.path.compare] compare GHC_INLINE int path::compare(const path& p) const noexcept { #ifdef LWG_2936_BEHAVIOUR @@ -2877,7 +2882,7 @@ GHC_INLINE int path::compare(const value_type* s) const } //----------------------------------------------------------------------------- -// 30.10.8.4.9, decomposition +// [fs.path.decompose] decomposition #ifdef GHC_OS_WINDOWS GHC_INLINE void path::handle_prefixes() { @@ -3009,7 +3014,7 @@ GHC_INLINE bool has_executable_extension(const path& p) #endif //----------------------------------------------------------------------------- -// 30.10.8.4.10, query +// [fs.path.query] query GHC_INLINE bool path::empty() const noexcept { return _path.empty(); @@ -3072,7 +3077,7 @@ GHC_INLINE bool path::is_relative() const } //----------------------------------------------------------------------------- -// 30.10.8.4.11, generation +// [fs.path.gen] generation GHC_INLINE path path::lexically_normal() const { path dest; @@ -3148,7 +3153,7 @@ GHC_INLINE path path::lexically_proximate(const path& base) const } //----------------------------------------------------------------------------- -// 30.10.8.5, iterators +// [fs.path.itr] iterators GHC_INLINE path::iterator::iterator() {} GHC_INLINE path::iterator::iterator(const path& p, const impl_string_type::const_iterator& pos) @@ -3301,7 +3306,7 @@ GHC_INLINE path::iterator path::end() const } //----------------------------------------------------------------------------- -// 30.10.8.6, path non-member functions +// [fs.path.nonmember] path non-member functions GHC_INLINE void swap(path& lhs, path& rhs) noexcept { swap(lhs._path, rhs._path); @@ -3359,7 +3364,7 @@ GHC_INLINE path operator/(const path& lhs, const path& rhs) #endif // GHC_EXPAND_IMPL //----------------------------------------------------------------------------- -// 30.10.8.6.1 path inserter and extractor +// [fs.path.io] path inserter and extractor template inline std::basic_ostream& operator<<(std::basic_ostream& os, const path& p) { @@ -3416,7 +3421,7 @@ inline std::basic_istream& operator>>(std::basic_istream=(const directory_entry& rhs) const no } //----------------------------------------------------------------------------- -// 30.10.13 class directory_iterator +// [fs.class.directory_iterator] class directory_iterator #ifdef GHC_OS_WINDOWS class directory_iterator::impl @@ -5567,7 +5572,7 @@ public: }; #endif -// 30.10.13.1 member functions +// [fs.dir.itr.members] member functions GHC_INLINE directory_iterator::directory_iterator() noexcept : _impl(new impl(path(), directory_options::none)) { @@ -5670,7 +5675,7 @@ GHC_INLINE bool directory_iterator::operator!=(const directory_iterator& rhs) co return _impl->_dir_entry._path != rhs._impl->_dir_entry._path; } -// 30.10.13.2 directory_iterator non-member functions +// [fs.dir.itr.nonmembers] directory_iterator non-member functions GHC_INLINE directory_iterator begin(directory_iterator iter) noexcept { @@ -5683,7 +5688,7 @@ GHC_INLINE directory_iterator end(const directory_iterator&) noexcept } //----------------------------------------------------------------------------- -// 30.10.14 class recursive_directory_iterator +// [fs.class.rec.dir.itr] class recursive_directory_iterator GHC_INLINE recursive_directory_iterator::recursive_directory_iterator() noexcept : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) @@ -5729,7 +5734,7 @@ GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(recursive_ GHC_INLINE recursive_directory_iterator::~recursive_directory_iterator() {} -// 30.10.14.1 observers +// [fs.rec.dir.itr.members] observers GHC_INLINE directory_options recursive_directory_iterator::options() const { return _impl->_options; @@ -5755,7 +5760,7 @@ GHC_INLINE const directory_entry* recursive_directory_iterator::operator->() con return &(*(_impl->_dir_iter_stack.top())); } -// 30.10.14.1 modifiers recursive_directory_iterator& +// [fs.rec.dir.itr.members] modifiers recursive_directory_iterator& GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator=(const recursive_directory_iterator& rhs) { _impl = rhs._impl; @@ -5834,7 +5839,7 @@ GHC_INLINE void recursive_directory_iterator::disable_recursion_pending() _impl->_recursion_pending = false; } -// other members as required by 27.2.3, input iterators +// other members as required by [input.iterators] GHC_INLINE bool recursive_directory_iterator::operator==(const recursive_directory_iterator& rhs) const { return _impl->_dir_iter_stack.top() == rhs._impl->_dir_iter_stack.top(); @@ -5845,7 +5850,7 @@ GHC_INLINE bool recursive_directory_iterator::operator!=(const recursive_directo return _impl->_dir_iter_stack.top() != rhs._impl->_dir_iter_stack.top(); } -// 30.10.14.2 directory_iterator non-member functions +// [fs.rec.dir.itr.nonmembers] directory_iterator non-member functions GHC_INLINE recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept { return iter; diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index cf889d9..66b0201 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -362,7 +362,7 @@ TEST_CASE("fs::detail::toUtf8", "[filesystem][fs.detail.utf8]") } #endif -TEST_CASE("30.10.8.1 path::preferred_separator", "[filesystem][path][fs.path.generic]") +TEST_CASE("[fs.path.generic] path::preferred_separator", "[filesystem][path][fs.path.generic]") { #ifdef GHC_OS_WINDOWS CHECK(fs::path::preferred_separator == '\\'); @@ -372,7 +372,7 @@ TEST_CASE("30.10.8.1 path::preferred_separator", "[filesystem][path][fs.path.gen } #ifndef GHC_OS_WINDOWS -TEST_CASE("30.10.8.1 path(\"//host\").has_root_name()", "[filesystem][path][fs.path.generic]") +TEST_CASE("[fs.path.generic] path(\"//host\").has_root_name()", "[filesystem][path][fs.path.generic]") { if (!has_host_root_name_support()) { WARN("This implementation doesn't support path(\"//host\").has_root_name() == true [C++17 30.12.8.1 par. 4] on this platform, tests based on this are skipped. (Should be okay.)"); @@ -380,7 +380,7 @@ TEST_CASE("30.10.8.1 path(\"//host\").has_root_name()", "[filesystem][path][fs.p } #endif -TEST_CASE("30.10.8.4.1 path constructors and destructor", "[filesystem][path][fs.path.construct]") +TEST_CASE("[fs.path.construct] path constructors and destructor", "[filesystem][path][fs.path.construct]") { CHECK("/usr/local/bin" == fs::path("/usr/local/bin").generic_string()); std::string str = "/usr/local/bin"; @@ -432,7 +432,7 @@ TEST_CASE("30.10.8.4.1 path constructors and destructor", "[filesystem][path][fs #endif } -TEST_CASE("30.10.8.4.2 path assignments", "[filesystem][path][fs.path.assign]") +TEST_CASE("[fs.path.assign] path assignments", "[filesystem][path][fs.path.assign]") { fs::path p1{"/foo/bar"}; fs::path p2{"/usr/local"}; @@ -467,7 +467,7 @@ TEST_CASE("30.10.8.4.2 path assignments", "[filesystem][path][fs.path.assign]") REQUIRE(p2 == p3); } -TEST_CASE("30.10.8.4.3 path appends", "[filesystem][path][fs.path.append]") +TEST_CASE("[fs.path.append] path appends", "[filesystem][path][fs.path.append]") { #ifdef GHC_OS_WINDOWS CHECK(fs::path("foo") / "c:/bar" == "c:/bar"); @@ -493,7 +493,7 @@ TEST_CASE("30.10.8.4.3 path appends", "[filesystem][path][fs.path.append]") // TODO: append(first, last) } -TEST_CASE("30.10.8.4.4 path concatenation", "[filesystem][path][fs.path.concat]") +TEST_CASE("[fs.path.concat] path concatenation", "[filesystem][path][fs.path.concat]") { CHECK((fs::path("foo") += fs::path("bar")) == "foobar"); CHECK((fs::path("foo") += fs::path("/bar")) == "foo/bar"); @@ -532,7 +532,7 @@ TEST_CASE("30.10.8.4.4 path concatenation", "[filesystem][path][fs.path.concat]" // TODO: contat(first, last) } -TEST_CASE("30.10.8.4.5 path modifiers", "[filesystem][path][fs.path.modifiers]") +TEST_CASE("[fs.path.modifiers] path modifiers", "[filesystem][path][fs.path.modifiers]") { fs::path p = fs::path("/foo/bar"); p.clear(); @@ -571,7 +571,7 @@ TEST_CASE("30.10.8.4.5 path modifiers", "[filesystem][path][fs.path.modifiers]") CHECK(p2 == "foo"); } -TEST_CASE("30.10.8.4.6 path native format observers", "[filesystem][path][fs.path.native.obs]") +TEST_CASE("[fs.path.native.obs] path native format observers", "[filesystem][path][fs.path.native.obs]") { #ifdef GHC_OS_WINDOWS #if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T) @@ -609,7 +609,7 @@ TEST_CASE("30.10.8.4.6 path native format observers", "[filesystem][path][fs.pat #endif } -TEST_CASE("30.10.8.4.7 path generic format observers", "[filesystem][path][fs.path.generic.obs]") +TEST_CASE("[fs.path.generic.obs] path generic format observers", "[filesystem][path][fs.path.generic.obs]") { #ifdef GHC_OS_WINDOWS #ifndef IS_WCHAR_PATH @@ -644,7 +644,7 @@ TEST_CASE("30.10.8.4.7 path generic format observers", "[filesystem][path][fs.pa #endif } -TEST_CASE("30.10.8.4.8 path compare", "[filesystem][path][fs.path.compare]") +TEST_CASE("[fs.path.compare] path compare", "[filesystem][path][fs.path.compare]") { CHECK(fs::path("/foo/b").compare("/foo/a") > 0); CHECK(fs::path("/foo/b").compare("/foo/b") == 0); @@ -670,7 +670,7 @@ TEST_CASE("30.10.8.4.8 path compare", "[filesystem][path][fs.path.compare]") #endif // LWG_2936_BEHAVIOUR } -TEST_CASE("30.10.8.4.9 path decomposition", "[filesystem][path][fs.path.decompose]") +TEST_CASE("[fs.path.decompose] path decomposition", "[filesystem][path][fs.path.decompose]") { // root_name() CHECK(fs::path("").root_name() == ""); @@ -820,7 +820,7 @@ TEST_CASE("30.10.8.4.9 path decomposition", "[filesystem][path][fs.path.decompos } } -TEST_CASE("30.10.8.4.10 path query", "[fielsystem][path][fs.path.query]") +TEST_CASE("[fs.path.query] path query", "[fielsystem][path][fs.path.query]") { // empty CHECK(fs::path("").empty()); @@ -918,7 +918,7 @@ TEST_CASE("30.10.8.4.10 path query", "[fielsystem][path][fs.path.query]") } } -TEST_CASE("30.10.8.4.11 path generation", "[filesystem][path][fs.path.gen]") +TEST_CASE("[fs.path.gen] path generation", "[filesystem][path][fs.path.gen]") { // lexically_normal() CHECK(fs::path("foo/./bar/..").lexically_normal() == "foo/"); @@ -1005,7 +1005,7 @@ static std::string reverseIterateResult(const fs::path& path) return result.str(); } -TEST_CASE("30.10.8.5 path iterators", "[filesystem][path][fs.path.itr]") +TEST_CASE("[fs.path.itr] path iterators", "[filesystem][path][fs.path.itr]") { CHECK(iterateResult(fs::path()).empty()); CHECK("." == iterateResult(fs::path("."))); @@ -1088,7 +1088,7 @@ TEST_CASE("30.10.8.5 path iterators", "[filesystem][path][fs.path.itr]") } } -TEST_CASE("30.10.8.6 path non-member functions", "[filesystem][path][fs.path.nonmember]") +TEST_CASE("[fs.path.nonmember] path non-member functions", "[filesystem][path][fs.path.nonmember]") { fs::path p1("foo/bar"); fs::path p2("some/other"); @@ -1110,7 +1110,7 @@ TEST_CASE("30.10.8.6 path non-member functions", "[filesystem][path][fs.path.non CHECK(p1 / p2 == "some/other/foo/bar"); } -TEST_CASE("30.10.8.6.1 path inserter and extractor", "[filesystem][path][fs.path.io]") +TEST_CASE("[fs.path.io] path inserter and extractor", "[filesystem][path][fs.path.io]") { { std::ostringstream os; @@ -1160,7 +1160,7 @@ TEST_CASE("30.10.8.6.1 path inserter and extractor", "[filesystem][path][fs.path } } -TEST_CASE("30.10.8.6.2 path factory functions", "[filesystem][path][fs.path.factory]") +TEST_CASE("[fs.path.factory] path factory functions", "[filesystem][path][fs.path.factory]") { CHECK(fs::u8path("foo/bar") == fs::path("foo/bar")); CHECK(fs::u8path("foo/bar") == fs::path("foo/bar")); @@ -1168,7 +1168,7 @@ TEST_CASE("30.10.8.6.2 path factory functions", "[filesystem][path][fs.path.fact CHECK(fs::u8path(str.begin(), str.end()) == str); } -TEST_CASE("30.10.9 class filesystem_error", "[filesystem][filesystem_error][fs.class.filesystem_error]") +TEST_CASE("[fs.class.filesystem_error] class filesystem_error", "[filesystem][filesystem_error][fs.class.filesystem_error]") { std::error_code ec(1, std::system_category()); fs::filesystem_error fse("None", std::error_code()); @@ -1192,7 +1192,7 @@ constexpr fs::perms constExprOwnerAll() return fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec; } -TEST_CASE("30.10.10.4 enum class perms", "[filesystem][enum][fs.enum]") +TEST_CASE("[fs.enum] enum class perms", "[filesystem][enum][fs.enum]") { static_assert(constExprOwnerAll() == fs::perms::owner_all, "constexpr didn't result in owner_all"); CHECK((fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec) == fs::perms::owner_all); @@ -1202,7 +1202,7 @@ TEST_CASE("30.10.10.4 enum class perms", "[filesystem][enum][fs.enum]") CHECK((fs::perms::all | fs::perms::set_uid | fs::perms::set_gid | fs::perms::sticky_bit) == fs::perms::mask); } -TEST_CASE("30.10.11 class file_status", "[filesystem][file_status][fs.class.file_status]") +TEST_CASE("[fs.class.file_status] class file_status", "[filesystem][file_status][fs.class.file_status]") { { fs::file_status fs; @@ -1250,7 +1250,7 @@ TEST_CASE("30.10.11 class file_status", "[filesystem][file_status][fs.class.file #endif } -TEST_CASE("30.10.12 class directory_entry", "[filesystem][directory_entry][fs.dir.entry]") +TEST_CASE("[fs.dir.entry] class directory_entry", "[filesystem][directory_entry][fs.dir.entry]") { TemporaryDirectory t; std::error_code ec; @@ -1367,7 +1367,7 @@ TEST_CASE("30.10.12 class directory_entry", "[filesystem][directory_entry][fs.di CHECK(!(d1 == d2)); } -TEST_CASE("30.10.13 class directory_iterator", "[filesystem][directory_iterator][fs.class.directory_iterator]") +TEST_CASE("[fs.class.directory_iterator] class directory_iterator", "[filesystem][directory_iterator][fs.class.directory_iterator]") { { TemporaryDirectory t; @@ -1428,7 +1428,7 @@ TEST_CASE("30.10.13 class directory_iterator", "[filesystem][directory_iterator] } } -TEST_CASE("30.10.14 class recursive_directory_iterator", "[filesystem][recursive_directory_iterator][fs.class.rec.dir.itr]") +TEST_CASE("[fs.class.rec.dir.itr] class recursive_directory_iterator", "[filesystem][recursive_directory_iterator][fs.class.rec.dir.itr]") { { auto iter = fs::recursive_directory_iterator("."); @@ -1586,7 +1586,7 @@ TEST_CASE("30.10.14 class recursive_directory_iterator", "[filesystem][recursive } } -TEST_CASE("30.10.15.1 absolute", "[filesystem][operations][fs.op.absolute]") +TEST_CASE("[fs.op.absolute] absolute", "[filesystem][operations][fs.op.absolute]") { CHECK(fs::absolute("") == fs::current_path() / ""); CHECK(fs::absolute(fs::current_path()) == fs::current_path()); @@ -1600,7 +1600,7 @@ TEST_CASE("30.10.15.1 absolute", "[filesystem][operations][fs.op.absolute]") CHECK(!ec); } -TEST_CASE("30.10.15.2 canonical", "[filesystem][operations][fs.op.canonical]") +TEST_CASE("[fs.op.canonical] canonical", "[filesystem][operations][fs.op.canonical]") { CHECK_THROWS_AS(fs::canonical(""), fs::filesystem_error); { @@ -1643,7 +1643,7 @@ TEST_CASE("30.10.15.2 canonical", "[filesystem][operations][fs.op.canonical]") } } -TEST_CASE("30.10.15.3 copy", "[filesystem][operations][fs.op.copy]") +TEST_CASE("[fs.op.copy] copy", "[filesystem][operations][fs.op.copy]") { { TemporaryDirectory t(TempOpt::change_path); @@ -1712,7 +1712,7 @@ TEST_CASE("30.10.15.3 copy", "[filesystem][operations][fs.op.copy]") #endif } -TEST_CASE("30.10.15.4 copy_file", "[filesystem][operations][fs.op.copy_file]") +TEST_CASE("[fs.op.copy_file] copy_file", "[filesystem][operations][fs.op.copy_file]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -1737,7 +1737,7 @@ TEST_CASE("30.10.15.4 copy_file", "[filesystem][operations][fs.op.copy_file]") CHECK(!fs::exists("foobar")); } -TEST_CASE("30.10.15.5 copy_symlink", "[filesystem][operations][fs.op.copy_symlink]") +TEST_CASE("[fs.op.copy_symlink] copy_symlink", "[filesystem][operations][fs.op.copy_symlink]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -1762,7 +1762,7 @@ TEST_CASE("30.10.15.5 copy_symlink", "[filesystem][operations][fs.op.copy_symlin CHECK(ec); } -TEST_CASE("30.10.15.6 create_directories", "[filesystem][operations][fs.op.create_directories]") +TEST_CASE("[fs.op.create_directories] create_directories", "[filesystem][operations][fs.op.create_directories]") { TemporaryDirectory t; fs::path p = t.path() / "testdir"; @@ -1809,7 +1809,7 @@ TEST_CASE("30.10.15.6 create_directories", "[filesystem][operations][fs.op.creat #endif } -TEST_CASE("30.10.15.7 create_directory", "[filesystem][operations][fs.op.create_directory]") +TEST_CASE("[fs.op.create_directory] create_directory", "[filesystem][operations][fs.op.create_directory]") { TemporaryDirectory t; fs::path p = t.path() / "testdir"; @@ -1856,7 +1856,7 @@ TEST_CASE("30.10.15.7 create_directory", "[filesystem][operations][fs.op.create_ #endif } -TEST_CASE("30.10.15.8 create_directory_symlink", "[filesystem][operations][fs.op.create_directory_symlink]") +TEST_CASE("[fs.op.create_directory_symlink] create_directory_symlink", "[filesystem][operations][fs.op.create_directory_symlink]") { if (is_symlink_creation_supported()) { TemporaryDirectory t; @@ -1875,7 +1875,7 @@ TEST_CASE("30.10.15.8 create_directory_symlink", "[filesystem][operations][fs.op } } -TEST_CASE("30.10.15.9 create_hard_link", "[filesystem][operations][fs.op.create_hard_link]") +TEST_CASE("[fs.op.create_hard_link] create_hard_link", "[filesystem][operations][fs.op.create_hard_link]") { #ifndef GHC_OS_WEB TemporaryDirectory t(TempOpt::change_path); @@ -1894,7 +1894,7 @@ TEST_CASE("30.10.15.9 create_hard_link", "[filesystem][operations][fs.op.create_ #endif } -TEST_CASE("30.10.15.10 create_symlink", "[filesystem][operations][fs.op.create_symlink]") +TEST_CASE("[fs.op.create_symlink] create_symlink", "[filesystem][operations][fs.op.create_symlink]") { if (is_symlink_creation_supported()) { TemporaryDirectory t; @@ -1913,7 +1913,7 @@ TEST_CASE("30.10.15.10 create_symlink", "[filesystem][operations][fs.op.create_s } } -TEST_CASE("30.10.15.11 current_path", "[filesystem][operations][fs.op.current_path]") +TEST_CASE("[fs.op.current_path] current_path", "[filesystem][operations][fs.op.current_path]") { TemporaryDirectory t; std::error_code ec; @@ -1928,7 +1928,7 @@ TEST_CASE("30.10.15.11 current_path", "[filesystem][operations][fs.op.current_pa CHECK(ec); } -TEST_CASE("30.10.15.12 equivalent", "[filesystem][operations][fs.op.equivalent]") +TEST_CASE("[fs.op.equivalent] equivalent", "[filesystem][operations][fs.op.equivalent]") { TemporaryDirectory t(TempOpt::change_path); generateFile("foo", 1234); @@ -1982,7 +1982,7 @@ TEST_CASE("30.10.15.12 equivalent", "[filesystem][operations][fs.op.equivalent]" #endif } -TEST_CASE("30.10.15.13 exists", "[filesystem][operations][fs.op.exists]") +TEST_CASE("[fs.op.exists] exists", "[filesystem][operations][fs.op.exists]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2007,7 +2007,7 @@ TEST_CASE("30.10.15.13 exists", "[filesystem][operations][fs.op.exists]") #endif } -TEST_CASE("30.10.15.14 file_size", "[filesystem][operations][fs.op.file_size]") +TEST_CASE("[fs.op.file_size] file_size", "[filesystem][operations][fs.op.file_size]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2038,7 +2038,7 @@ static uintmax_t getHardlinkCount(const fs::path& p) } #endif -TEST_CASE("30.10.15.15 hard_link_count", "[filesystem][operations][fs.op.hard_link_count]") +TEST_CASE("[fs.op.hard_link_count] hard_link_count", "[filesystem][operations][fs.op.hard_link_count]") { #ifndef GHC_OS_WEB TemporaryDirectory t(TempOpt::change_path); @@ -2134,7 +2134,7 @@ private: bool _hasSocket; }; -TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.16 is_block_file", "[filesystem][operations][fs.op.is_block_file]") +TEST_CASE_METHOD(FileTypeMixFixture, "[fs.op.is_block_file] is_block_file", "[filesystem][operations][fs.op.is_block_file]") { std::error_code ec; CHECK(!fs::is_block_file("directory")); @@ -2163,7 +2163,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.16 is_block_file", "[filesystem][ CHECK(!fs::is_block_file(fs::file_status(fs::file_type::unknown))); } -TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.17 is_character_file", "[filesystem][operations][fs.op.is_character_file]") +TEST_CASE_METHOD(FileTypeMixFixture, "[fs.op.is_character_file] is_character_file", "[filesystem][operations][fs.op.is_character_file]") { std::error_code ec; CHECK(!fs::is_character_file("directory")); @@ -2192,7 +2192,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.17 is_character_file", "[filesyst CHECK(!fs::is_character_file(fs::file_status(fs::file_type::unknown))); } -TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.18 is_directory", "[filesystem][operations][fs.op.is_directory]") +TEST_CASE_METHOD(FileTypeMixFixture, "[fs.op.is_directory] is_directory", "[filesystem][operations][fs.op.is_directory]") { std::error_code ec; CHECK(fs::is_directory("directory")); @@ -2221,7 +2221,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.18 is_directory", "[filesystem][o CHECK(!fs::is_directory(fs::file_status(fs::file_type::unknown))); } -TEST_CASE("30.10.15.19 is_empty", "[filesystem][operations][fs.op.is_empty]") +TEST_CASE("[fs.op.is_empty] is_empty", "[filesystem][operations][fs.op.is_empty]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2243,7 +2243,7 @@ TEST_CASE("30.10.15.19 is_empty", "[filesystem][operations][fs.op.is_empty]") CHECK(ec); } -TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.20 is_fifo", "[filesystem][operations][fs.op.is_fifo]") +TEST_CASE_METHOD(FileTypeMixFixture, "[fs.op.is_fifo] is_fifo", "[filesystem][operations][fs.op.is_fifo]") { std::error_code ec; CHECK(!fs::is_fifo("directory")); @@ -2272,7 +2272,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.20 is_fifo", "[filesystem][operat CHECK(!fs::is_fifo(fs::file_status(fs::file_type::unknown))); } -TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.21 is_other", "[filesystem][operations][fs.op.is_other]") +TEST_CASE_METHOD(FileTypeMixFixture, "[fs.op.is_other] is_other", "[filesystem][operations][fs.op.is_other]") { std::error_code ec; CHECK(!fs::is_other("directory")); @@ -2301,7 +2301,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.21 is_other", "[filesystem][opera CHECK(fs::is_other(fs::file_status(fs::file_type::unknown))); } -TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.22 is_regular_file", "[filesystem][operations][fs.op.is_regular_file]") +TEST_CASE_METHOD(FileTypeMixFixture, "[fs.op.is_regular_file] is_regular_file", "[filesystem][operations][fs.op.is_regular_file]") { std::error_code ec; CHECK(!fs::is_regular_file("directory")); @@ -2330,7 +2330,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.22 is_regular_file", "[filesystem CHECK(!fs::is_regular_file(fs::file_status(fs::file_type::unknown))); } -TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.23 is_socket", "[filesystem][operations][fs.op.is_socket]") +TEST_CASE_METHOD(FileTypeMixFixture, "[fs.op.is_socket] is_socket", "[filesystem][operations][fs.op.is_socket]") { std::error_code ec; CHECK(!fs::is_socket("directory")); @@ -2359,7 +2359,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.23 is_socket", "[filesystem][oper CHECK(!fs::is_socket(fs::file_status(fs::file_type::unknown))); } -TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.24 is_symlink", "[filesystem][operations][fs.op.is_symlink]") +TEST_CASE_METHOD(FileTypeMixFixture, "[fs.op.is_symlink] is_symlink", "[filesystem][operations][fs.op.is_symlink]") { std::error_code ec; CHECK(!fs::is_symlink("directory")); @@ -2402,7 +2402,7 @@ static fs::file_time_type timeFromString(const std::string& str) } #endif -TEST_CASE("30.10.15.25 last_write_time", "[filesystem][operations][fs.op.last_write_time]") +TEST_CASE("[fs.op.last_write_time] last_write_time", "[filesystem][operations][fs.op.last_write_time]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2437,7 +2437,7 @@ TEST_CASE("30.10.15.25 last_write_time", "[filesystem][operations][fs.op.last_wr #endif } -TEST_CASE("30.10.15.26 permissions", "[filesystem][operations][fs.op.permissions]") +TEST_CASE("[fs.op.permissions] permissions", "[filesystem][operations][fs.op.permissions]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2457,7 +2457,7 @@ TEST_CASE("30.10.15.26 permissions", "[filesystem][operations][fs.op.permissions CHECK_THROWS_AS(fs::permissions("bar", fs::perms::owner_write, static_cast(0)), fs::filesystem_error); } -TEST_CASE("30.10.15.27 proximate", "[filesystem][operations][fs.op.proximate]") +TEST_CASE("[fs.op.proximate] proximate", "[filesystem][operations][fs.op.proximate]") { std::error_code ec; CHECK(fs::proximate("/a/d", "/a/b/c") == "../../d"); @@ -2487,7 +2487,7 @@ TEST_CASE("30.10.15.27 proximate", "[filesystem][operations][fs.op.proximate]") #endif } -TEST_CASE("30.10.15.28 read_symlink", "[filesystem][operations][fs.op.read_symlink]") +TEST_CASE("[fs.op.read_symlink] read_symlink", "[filesystem][operations][fs.op.read_symlink]") { if (is_symlink_creation_supported()) { TemporaryDirectory t(TempOpt::change_path); @@ -2503,7 +2503,7 @@ TEST_CASE("30.10.15.28 read_symlink", "[filesystem][operations][fs.op.read_symli } } -TEST_CASE("30.10.15.29 relative", "[filesystem][operations][fs.op.relative]") +TEST_CASE("[fs.op.relative] relative", "[filesystem][operations][fs.op.relative]") { CHECK(fs::relative("/a/d", "/a/b/c") == "../../d"); CHECK(fs::relative("/a/b/c", "/a/d") == "../b/c"); @@ -2516,7 +2516,7 @@ TEST_CASE("30.10.15.29 relative", "[filesystem][operations][fs.op.relative]") CHECK(!ec); } -TEST_CASE("30.10.15.30 remove", "[filesystem][operations][fs.op.remove]") +TEST_CASE("[fs.op.remove] remove", "[filesystem][operations][fs.op.remove]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2540,7 +2540,7 @@ TEST_CASE("30.10.15.30 remove", "[filesystem][operations][fs.op.remove]") CHECK(!ec); } -TEST_CASE("30.10.15.31 remove_all", "[filesystem][operations][fs.op.remove_all]") +TEST_CASE("[fs.op.remove_all] remove_all", "[filesystem][operations][fs.op.remove_all]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2560,7 +2560,7 @@ TEST_CASE("30.10.15.31 remove_all", "[filesystem][operations][fs.op.remove_all]" CHECK(fs::directory_iterator(t.path()) == fs::directory_iterator()); } -TEST_CASE("30.10.15.32 rename", "[filesystem][operations][fs.op.rename]") +TEST_CASE("[fs.op.rename] rename", "[filesystem][operations][fs.op.rename]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2584,7 +2584,7 @@ TEST_CASE("30.10.15.32 rename", "[filesystem][operations][fs.op.rename]") CHECK(!fs::exists("barfoo")); } -TEST_CASE("30.10.15.33 resize_file", "[filesystem][operations][fs.op.resize_file]") +TEST_CASE("[fs.op.resize_file] resize_file", "[filesystem][operations][fs.op.resize_file]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2602,7 +2602,7 @@ TEST_CASE("30.10.15.33 resize_file", "[filesystem][operations][fs.op.resize_file CHECK(!fs::exists("bar")); } -TEST_CASE("30.10.15.34 space", "[filesystem][operations][fs.op.space]") +TEST_CASE("[fs.op.space] space", "[filesystem][operations][fs.op.space]") { { fs::space_info si; @@ -2634,7 +2634,7 @@ TEST_CASE("30.10.15.34 space", "[filesystem][operations][fs.op.space]") #endif } -TEST_CASE("30.10.15.35 status", "[filesystem][operations][fs.op.status]") +TEST_CASE("[fs.op.status] status", "[filesystem][operations][fs.op.status]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2662,7 +2662,7 @@ TEST_CASE("30.10.15.35 status", "[filesystem][operations][fs.op.status]") } } -TEST_CASE("30.10.15.36 status_known", "[filesystem][operations][fs.op.status_known]") +TEST_CASE("[fs.op.status_known] status_known", "[filesystem][operations][fs.op.status_known]") { CHECK(!fs::status_known(fs::file_status())); CHECK(fs::status_known(fs::file_status(fs::file_type::not_found))); @@ -2675,7 +2675,7 @@ TEST_CASE("30.10.15.36 status_known", "[filesystem][operations][fs.op.status_kno CHECK(fs::status_known(fs::file_status(fs::file_type::unknown))); } -TEST_CASE("30.10.15.37 symlink_status", "[filesystem][operations][fs.op.symlink_status]") +TEST_CASE("[fs.op.symlink_status] symlink_status", "[filesystem][operations][fs.op.symlink_status]") { TemporaryDirectory t(TempOpt::change_path); std::error_code ec; @@ -2702,7 +2702,7 @@ TEST_CASE("30.10.15.37 symlink_status", "[filesystem][operations][fs.op.symlink_ } } -TEST_CASE("30.10.15.38 temporary_directory_path", "[filesystem][operations][fs.op.temp_dir_path]") +TEST_CASE("[fs.op.temp_dir_path] temporary_directory_path", "[filesystem][operations][fs.op.temp_dir_path]") { std::error_code ec; CHECK_NOTHROW(fs::exists(fs::temp_directory_path())); @@ -2711,7 +2711,7 @@ TEST_CASE("30.10.15.38 temporary_directory_path", "[filesystem][operations][fs.o CHECK(!ec); } -TEST_CASE("30.10.15.39 weakly_canonical", "[filesystem][operations][fs.op.weakly_canonical]") +TEST_CASE("[fs.op.weakly_canonical] weakly_canonical", "[filesystem][operations][fs.op.weakly_canonical]") { INFO("This might fail on std::implementations that return fs::current_path() for fs::canonical(\"\")"); CHECK(fs::weakly_canonical("") == ".");