1 2 3[](https://travis-ci.org/gulrak/filesystem) 4[](https://ci.appveyor.com/project/gulrak/filesystem) 5[](https://cirrus-ci.com/github/gulrak/filesystem) 6[](https://cloud.drone.io/gulrak/filesystem) 7[](https://coveralls.io/github/gulrak/filesystem?branch=master) 8[](https://github.com/gulrak/filesystem/tree/v1.3.2) 9 10# Filesystem 11 12This is a header-only single-file std::filesystem compatible helper library, 13based on the C++17 specs, but implemented for C++11, C++14 or C++17 (tightly following 14the C++17 with very few documented exceptions). It is currently tested on 15macOS 10.12/10.14, Windows 10, Ubuntu 18.04, FreeBSD 12 and Alpine ARM/ARM64 Linux 16but should work on other systems too, as long as you have at least a 17C++11 compatible compiler. It is of course in its own namespace `ghc::filesystem` 18to not interfere with a regular `std::filesystem` should you use it in a mixed C++17 19environment. 20 21*It could still use some polishing, test coverage is above 90%, I didn't benchmark 22much yet, but I'll try to optimize some parts and refactor others, so I'm striving 23to improve it as long as it doesn't introduce additional C++17 compatibility 24issues. Feedback is always welcome. Simply open an issue if you see something missing 25or wrong or not behaving as expected and I'll comment.* 26 27 28## Motivation 29 30I'm often in need of filesystem functionality, mostly `fs::path`, but directory 31access too, and when beginning to use C++11, I used that language update 32to try to reduce my third-party dependencies. I could drop most of what 33I used, but still missed some stuff that I started implementing for the 34fun of it. Originally I based these helpers on my own coding- and naming 35conventions. When C++17 was finalized, I wanted to use that interface, 36but it took a while, to push myself to convert my classes. 37 38The implementation is closely based on chapter 30.10 from the C++17 standard 39and a draft close to that version is 40[Working Draft N4687](https://github.com/cplusplus/draft/raw/master/papers/n4687.pdf). 41It is from after the standardization of C++17 but it contains the latest filesystem 42interface changes compared to the 43[Working Draft N4659](https://github.com/cplusplus/draft/raw/master/papers/n4659.pdf). 44 45I want to thank the people working on improving C++, I really liked how the language 46evolved with C++11 and the following standards. Keep on the good work! 47 48Oh, and if you ask yourself, what `ghc` is standing for, it is simply 49`gulraks helper classes`, yeah, I know, not very imaginative, but I wanted a 50short namespace and I use it in some of my private classes (so it has nothing 51to do with Haskell). 52 53## Platforms 54 55`ghc::filesystem` is developed on macOS but tested on Windows and Linux. 56It should work on any of these with a C++11-capable compiler. I currently 57don't have a BSD derivate besides macOS, so the preprocessor checks will 58cry out if you try to use it there, but if there is demand, I can try to 59help. Also there are some checks to hopefully better work on Android, but 60as I currently don't test with the Android NDK, I wouldn't call it a 61supported platform yet. All in all, I don't see it replacing `std::filesystem` 62where full C++17 is available, it doesn't try to be a "better" 63`std::filesystem`, just a drop-in if you can't use it (with the exception 64of the UTF-8 preference on Windows). 65 66 67Unit tests are currently run with: 68 69* macOS 10.12: Xcode 9.2 (clang-900.0.39.2), GCC 9.2, Clang 9.0, macOS 10.13: Xcode 10.1, macOS 10.14: Xcode 11.2 70* Windows: Visual Studio 2017, Visual Studio 2015, Visual Studio 2019, MinGW GCC 6.3 (Win32), GCC 7.2 (Win64) 71* Linux (Ubuntu): GCC (5.5, 6.5, 7.4, 8.3, 9.2), Clang (5.0, 6.0, 7.1, 8.0, 9.0) 72* Linux (Alpine ARM/ARM64): GCC 9.2.0 73* FreeBSD: Clang 8.0 74 75 76## Tests 77 78The header comes with a set of unit-tests and uses [CMake](https://cmake.org/) 79as a build tool and [Catch2](https://github.com/catchorg/Catch2) as test framework. 80 81All tests agains this implementation should succeed, depending on your environment 82it might be that there are some warnings, e.g. if you have no rights to create 83Symlinks on Windows or at least the test thinks so, but these are just informative. 84 85To build the tests from inside the project directory under macOS or Linux just: 86 87```cpp 88mkdir build 89cd build 90cmake -DCMAKE_BUILD_TYPE=Debug .. 91make 92``` 93 94This generates `filesystem_test`, the binary that runs all tests. 95 96If the default compiler is a GCC 8 or newer, or Clang 7 or newer, it 97additionally tries to build a version of the test binary compiled against GCCs/Clangs 98`std::filesystem` implementation, named `std_filesystem_test` 99as an additional test of conformance. Ideally all tests should compile and 100succeed with all filesystem implementations, but in reality, there are 101some differences in behavior, sometimes due to room for interpretation in 102in the standard, and there might be issues in these implementations too. 103 104 105## Usage 106 107### Downloads 108 109The latest release version is [v1.3.2](https://github.com/gulrak/filesystem/tree/v1.3.2) and 110source archives can be found [here](https://github.com/gulrak/filesystem/releases/tag/v1.3.2). 111 112### Using it as Single-File-Header 113 114As `ghc::filesystem` is at first a header-only library, it should be enough to copy the header 115or the `include/ghc` directory into your project folder oder point your include path to this place and 116simply include the `filesystem.hpp` header (or `ghc/filesystem.hpp` if you use the subdirectory). 117 118Everything is in the namespace `ghc::filesystem`, so one way to use it only as 119a fallback could be: 120 121```cpp 122#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include) 123#if __has_include(<filesystem>) 124#define GHC_USE_STD_FS 125#include <filesystem> 126namespace fs = std::filesystem; 127#endif 128#endif 129#ifndef GHC_USE_STD_FS 130#include <ghc/filesystem.hpp> 131namespace fs = ghc::filesystem; 132#endif 133``` 134 135**Note that this code uses a two-stage preprocessor condition because Visual Studio 2015 136doesn't like the `(<...>)` syntax, even if it could cut evaluation early before.** 137 138**Note also, that on MSVC this detection only works starting from version 15.7 on and when setting 139the `/Zc:__cplusplus` compile switch, as the compiler allways reports `199711L` 140without that switch ([see](https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/)).** 141 142If you want to also use the `fstream` wrapper with `path` support as fallback, 143you might use: 144 145```cpp 146#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include) 147#if __has_include(<filesystem>) 148#define GHC_USE_STD_FS 149#include <filesystem> 150namespace fs { 151using namespace std::filesystem; 152using ifstream = std::ifstream; 153using ofstream = std::ofstream; 154using fstream = std::fstream; 155} 156#endif 157#endif 158#ifndef GHC_USE_STD_FS 159#include <ghc/filesystem.hpp> 160namespace fs { 161using namespace ghc::filesystem; 162using ifstream = ghc::filesystem::ifstream; 163using ofstream = ghc::filesystem::ofstream; 164using fstream = ghc::filesystem::fstream; 165} 166#endif 167``` 168 169Now you have e.g. `fs::ofstream out(somePath);` and it is either the wrapper or 170the C++17 `std::ofstream`. 171 172**Be aware, as a header-only library, it is not hiding the fact, that it 173uses system includes, so they "pollute" your global namespace.** 174 175:information_source: **Hint:** There is an additional header named `ghc/fs_std.hpp` that implements this 176dynamic selection of a filesystem implementation, that you can include 177instead of `ghc/filesystem.hpp` when you want std::filesystem where 178available and ghc::filesystem where not. It also enables the `wchar_t` 179support on `ghc::filesystem` on Windows, so the resulting implementation 180in the `fs` namespace will be compatible. 181 182 183### Using it as Forwarding-/Implementation-Header 184 185Alternatively, starting from v1.1.0 `ghc::filesystem` can also be used by 186including one of two additional wrapper headers. These allow to include 187a forwarded version in most places (`ghc/fs_fwd.hpp`) while hiding the 188implementation details in a single cpp that includes `ghc/fs_impl.hpp` to 189implement the needed code. That way system includes are only visible from 190inside the cpp, all other places are clean. 191 192Be aware, that it is currently not supported to hide the implementation 193into a Windows-DLL, as a DLL interface with C++ standard templates in interfaces 194is a different beast. If someone is willing to give it a try, I might integrate 195a PR but currently working on that myself is not a priority. 196 197If you use the forwarding/implementation approach, you can still use the dynamic 198switching like this: 199 200```cpp 201#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include) 202#if __has_include(<filesystem>) 203#define GHC_USE_STD_FS 204#include <filesystem> 205namespace fs { 206using namespace std::filesystem; 207using ifstream = std::ifstream; 208using ofstream = std::ofstream; 209using fstream = std::fstream; 210} 211#endif 212#endif 213#ifndef GHC_USE_STD_FS 214#include <ghc/fs-fwd.hpp> 215namespace fs { 216using namespace ghc::filesystem; 217using ifstream = ghc::filesystem::ifstream; 218using ofstream = ghc::filesystem::ofstream; 219using fstream = ghc::filesystem::fstream; 220} 221#endif 222``` 223 224and in the implementation hiding cpp, you might use (before any include that includes `ghc/fs_fwd.hpp` 225to take precedence: 226 227```cpp 228#if !(defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include) 229#if __has_include(<filesystem>)) 230#include <ghc/fs_impl.hpp> 231#endif 232#endif 233``` 234 235:information_source: **Hint:** There are additional helper headers, named `ghc/fs_std_fwd.hpp` and 236`ghc/fs_std_impl.hpp` that use this technique, so you can simply include them 237if you want to dynamically select the filesystem implementation. they also 238enable the `wchar_t` support on `ghc::filesystem` on Windows, so the resulting 239implementation in the `fs` namespace will be compatible. 240 241 242 243### Git Submodule and CMake 244 245Starting from v1.1.0, it is possible to add `ghc::filesystem` 246as a git submodule, add the directory to your `CMakeLists.txt` with 247`add_subdirectory()` and then simply use `target_link_libraries(your-target ghc_filesystem)` 248to ensure correct include path that allow `#include <ghc/filesystem.hpp>` 249to work. 250 251The `CMakeLists.txt` offers a few options to customize its behaviour: 252 253* `GHC_FILESYSTEM_BUILD_TESTING` - Compile tests, default is `OFF` when used as 254 a submodule, else `ON`. 255* `GHC_FILESYSTEM_BUILD_EXAMPLES` - Compile the examples, default is `OFF` when used as 256 a submodule, else `ON`. 257* `GHC_FILESYSTEM_WITH_INSTALL` - Add install target to build, default is `OFF` when used as 258 a submodule, else `ON`. 259 260### Versioning 261 262There is a version macro `GHC_FILESYSTEM_VERSION` defined in case future changes 263might make it needed to react on the version, but I don't plan to break anything. 264It's the version as decimal number `(major * 10000 + minor * 100 + patch)`. 265 266**Note:** Starting from v1.0.2 only even patch versions will be used for releases 267and odd patch version will only be used for in between commits while working on 268the next version. 269 270 271## Documentation 272 273There is almost no documentation in this release, as any `std::filesystem` 274documentation would work, besides the few differences explained in the next 275section. So you might head over to https://en.cppreference.com/w/cpp/filesystem 276for a description of the components of this library. 277 278The only additions to the standard are documented here: 279 280 281### `ghc::filesystem::ifstream`, `ghc::filesystem::ofstream`, `ghc::filesystem::fstream` 282 283These are simple wrappers around `std::ifstream`, `std::ofstream` and `std::fstream`. 284They simply add an `open()` method and a constuctor with an `ghc::filesystem::path` 285argument as the `fstream` variants in C++17 have them. 286 287### `ghc::filesystem::u8arguments` 288 289This is a helper class that currently checks for UTF-8 encoding on non-Windows platforms but on Windows it 290fetches the command line arguments als Unicode strings from the OS with 291 292```cpp 293::CommandLineToArgvW(::GetCommandLineW(), &argc) 294``` 295 296and then converts them to UTF-8, and replaces `argc` and `argv`. It is a guard-like 297class that reverts its changes when going out of scope. 298 299So basic usage is: 300 301```cpp 302namespace fs = ghc::filesystem; 303 304int main(int argc, char* argv[]) 305{ 306 fs::u8arguments u8guard(argc, argv); 307 if(!u8guard.valid()) { 308 std::cerr << "Bad encoding, needs UTF-8." << std::endl; 309 exit(EXIT_FAILURE); 310 } 311 312 // now use argc/argv as usual, they have utf-8 enconding on windows 313 // ... 314 315 return 0; 316} 317``` 318 319That way `argv` is UTF-8 encoded as long as the scope from `main` is valid. 320 321**Note:** On macOS, while debugging under Xcode the code currently will return 322`false` as Xcode starts the application with `US-ASCII` as encoding, no matter what 323encoding is actually used and even setting `LC_ALL` in the product scheme doesn't 324change anything. I still need to investigate this. 325 326 327## Differences 328 329As this implementation is based on existing code from my private helper 330classes, it derived some constraints of it, leading to some differences 331between this and the standard C++17 API. 332 333 334### LWG Defects 335 336This implementation has switchable behavior for the LWG defects 337[#2682](https://wg21.cmeerw.net/lwg/issue2682), 338[#2935](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2935) and 339[#2937](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2937). 340The currently selected behavior is following 341[#2682](https://wg21.cmeerw.net/lwg/issue2682), 342[#2937](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2937) but 343not following [#2935](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2935), 344as I feel it is a bug to report no error on a `create_directory()` or `create_directories()` 345where a regular file of the same name prohibits the creation of a directory and forces 346the user of those functions to double-check via `fs::is_directory` if it really worked. 347The more intuitive approach to directory creation of treating a file with that name as an 348error is also advocated by the newer paper 349[WG21 P1164R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1164r0.pdf), the revison 350P1161R1 was agreed upon on Kona 2019 meeting [see merge](https://github.com/cplusplus/draft/issues/2703) 351and GCC by now switched to following its proposal 352([GCC #86910](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86910)). 353 354### Not Implemented on C++ before C++17 355 356```cpp 357// methods in ghc::filesystem::path: 358path& operator+=(basic_string_view<value_type> x); 359int compare(basic_string_view<value_type> s) const; 360``` 361 362These are not implemented under C++11 and C++14, as there is no 363`std::basic_string_view` available and I did want to keep this 364implementation self-contained and not write a full C++17-upgrade for 365C++11/14. Starting with v1.1.0 these are supported when compiling 366ghc::filesystem under C++17. 367 368 369### Differences in API 370 371```cpp 372filesystem::path::string_type 373filesystem::path::value_type 374``` 375 376In Windows, an implementation should use `std::wstring` and `wchar_t` as types used 377for the native representation, but as I'm a big fan of the 378["UTF-8 Everywhere" philosophy](https://utf8everywhere.org/), I decided 379agains it for now. If you need to call some Windows API, use the W-variant 380with the `path::wstring()` member 381(e.g. `GetFileAttributesW(p.wstring().c_str())`). This gives you the 382Unicode variant independant of the `UNICODE` macro and makes sharing code 383between Windows, Linux and macOS easier. 384 385Starting with v1.2.0 `ghc::filesystem` has the option to select the more 386standard conforming APi with `wchar_t` and `std::wstring` on Windows by 387defining `GHC_WIN_WSTRING_STRING_TYPE`. This define has no effect on other 388platforms and will be set by the helping headers `ghc/fs_std.hpp` and 389the pair `ghc/fs_std_fwd.hpp`/`ghc/fs_std_impl.hpp` to enhance compatibility. 390 391 392```cpp 393const path::string_type& path::native() const /*noexcept*/; 394const path::value_type *path::c_str() const /*noexcept*/; 395``` 396 397These two can not be `noexcept` with the current implementation. This due 398to the fact, that internally path is working on the generic path version 399only, and the getters need to do a conversion to native path format. 400 401```cpp 402const path::string_type& path::generic_string() const; 403``` 404 405This returns a const reference, instead of a value, because it can. This 406implementation uses the generic representation for internal workings, so 407it's "free" to return that. 408 409 410### Differences in Behavior 411 412#### fs.path ([ref](https://en.cppreference.com/w/cpp/filesystem/path)) 413 414As the complete inner mechanics of this implementation `fs::path` are working 415on the generic format, it is the internal representation. So creating any mixed 416slash `fs::path` object under Windows (e.g. with `"C:\foo/bar"`) will lead to a 417unified path with `"C:\foo\bar"` via `native()` and `"C:/foo/bar"` via 418`generic_string()` API. 419 420Additionally this implementation follows the standards suggestion to handle 421posix paths of the form `"//host/path"` and USC path on windows also as having 422a root-name (e.g. `"//host"`). The GCC implementation didn't choose to do that 423while testing on Ubuntu 18.04 and macOS with GCC 8.1.0 or Clang 7.0.0. This difference 424will show as warnings under std::filesystem. This leads to a change in the 425algorithm described in the standard for `operator/=(path& p)` where any path 426`p` with `p.is_absolute()` will degrade to an assignment, while this implementation 427has the exception where `*this == *this.root_name()` and `p == preferred_seperator` 428a normal append will be done, to allow: 429 430```cpp 431fs::path p1 = "//host/foo/bar/file.txt"; 432fs::path p2; 433for (auto p : p1) p2 /= p; 434ASSERT(p1 == p2); 435``` 436 437For all non-host-leading paths the behaviour will match the one described by 438the standard. 439 440#### fs.op.copy ([ref](https://en.cppreference.com/w/cpp/filesystem/copy)) 441 442Then there is `fs::copy`. The tests in the suite fail partially with C++17 `std::filesystem` 443on GCC/Clang. They complain about a copy call with `fs::copy_options::recursive` combined 444with `fs::copy_options::create_symlinks` or `fs::copy_options::create_hard_links` if the 445source is a directory. There is nothing in the standard that forbids this combination 446and it is the only way to deep-copy a tree while only create links for the files. 447There is [LWG #2682](https://wg21.cmeerw.net/lwg/issue2682) that supports this 448interpretation, but the issue ignores the usefulness of the combination with recursive 449and part of the justification for the proposed solution is "we did it so for almost two years". 450But this makes `fs::copy` with `fs::copy_options::create_symlinks` or `fs::copy_options::create_hard_links` 451just a more complicated syntax for the `fs::create_symlink` or `fs::create_hardlink` operation 452and I don't want to believe, that this was the intention of the original writing. 453As there is another issue related to copy, with a different take on the description. 454 455**Note:** With v1.1.2 I decided to integrate a behavior switch for this and make the LWG #2682 456the default. 457 458## Open Issues 459 460### General Known Issues 461 462There are still some methods that break the `noexcept` clause, some 463are related to LWG defects, some are due to my implementation. I 464work on fixing the later ones, and might in cases where there is no 465way of implementing the feature without risk of an exception, break 466conformance and remove the `noexcept`. 467 468### Windows 469 470#### Symbolic Links on Windows 471 472As symbolic links on Windows, while being supported more or less since 473Windows Vista (with some strict security constraints) and fully since some earlier 474build of Windows 10, when "Developer Mode" is activated, are at time of writing 475(2018) rarely used, still they are supported with this implementation. 476 477#### Permissions 478 479The Windows ACL permission feature translates badly to the POSIX permission 480bit mask used in the interface of C++17 filesystem. The permissions returned 481in the `file_status` are therefore currently synthesized for the `user`-level 482and copied to the `group`- and `other`-level. There is still some potential 483for more interaction with the Windows permission system, but currently setting 484or reading permissions with this implementation will most certainly not lead 485to the expected behavior. 486 487 488## Release Notes 489 490### [v1.3.2](https://github.com/gulrak/filesystem/releases/tag/v1.3.2) 491 492* Bugfix for [#58](https://github.com/gulrak/filesystem/issues/58), on MinGW the 493 compilation could fail with an error about an undefined `ERROR_FILE_TOO_LARGE` 494 constant. 495* Bugfix for [#56](https://github.com/gulrak/filesystem/issues/58), `fs::lexically_relative` 496 didn't ignore trailing slash on the base parameter, thanks for PR 497 [#57](https://github.com/gulrak/filesystem/pull/57). 498* Bugfix for [#55](https://github.com/gulrak/filesystem/issues/55), `fs::create_directories` 499 returned `true` when nothing needed to be created, because the directory already existed. 500* Bugfix for [#54](https://github.com/gulrak/filesystem/issues/54), `error_code` 501 was not reset, if cached result was returned. 502* Pull request [#53](https://github.com/gulrak/filesystem/pull/53), fix for wrong 503 handling of leading whitespace when reading `fs::path` from a stream. 504* Pull request [#52](https://github.com/gulrak/filesystem/pull/52), an ARM Linux 505 target is now part of the CI infrastructure with the service of Drone CI. 506* Pull request [#51](https://github.com/gulrak/filesystem/pull/51), FreeBSD is now 507 part of the CI infrastucture with the service of Cirrus CI. 508* Pull request [#50](https://github.com/gulrak/filesystem/pull/50), adaptive cast to 509 `timespec` fields to avoid warnings. 510 511### [v1.3.0](https://github.com/gulrak/filesystem/releases/tag/v1.3.0) 512 513* **Important: `ghc::filesystem` is re-licensed from BSD-3-Clause to MIT license.** (see 514 [#47](https://github.com/gulrak/filesystem/issues/47)) 515* Pull request [#46](https://github.com/gulrak/filesystem/pull/46), suppresses 516 unused parameter warning on Android. 517* Bugfix for [#44](https://github.com/gulrak/filesystem/issues/44), fixes 518 for warnings from newer Xcode versions. 519 520### [v1.2.10](https://github.com/gulrak/filesystem/releases/tag/v1.2.10) 521 522* The Visual Studio 2019 compiler, GCC 9.2 and Clang 9.0 where added to the 523 CI configuration. 524* Bugfix for [#41](https://github.com/gulrak/filesystem/issues/41), `fs::rename` 525 on Windows didn't replace an axisting regular file as required by the standard, 526 but gave an error. New tests and a fix as provided in the issue was implemented. 527* Bugfix for [#39](https://github.com/gulrak/filesystem/issues/39), for the 528 forwarding use via `fs_fwd.hpp` or `fs_std_fwd.hpp` der was a use of 529 `DWORD` in the forwarding part leading to an error if `Windows.h` was not 530 included before the header. The tests were changed to give an error in that 531 case too and the useage of `DWORD` was removed. 532* Bugfix for [#38](https://github.com/gulrak/filesystem/issues/38), casting the 533 return value of `GetProcAddress` gave a warning with `-Wcast-function-type` 534 on MSYS2 and MinGW GCC 9 builds. 535 536### [v1.2.8](https://github.com/gulrak/filesystem/releases/tag/v1.2.8) 537 538* Pull request [#30](https://github.com/gulrak/filesystem/pull/30), the 539 `CMakeLists.txt` will automatically exclude building examples and tests when 540 used as submodule, the configuration options now use a prefixed name to 541 reduce risk of conflicts. 542* Pull request [#24](https://github.com/gulrak/filesystem/pull/24), install 543 target now creates a `ghcFilesystemConfig.cmake` in 544 `${CMAKE_INSTALL_LIBDIR}/cmake/ghcFilesystem` for `find_package` that 545 exports a target as `ghcFilesystem::ghc_filesystem`. 546* Pull request [#31](https://github.com/gulrak/filesystem/pull/31), fixes 547 `error: redundant redeclaration of 'constexpr' static data member` deprecation 548 warning in C++17 mode. 549* Pull request [#32](https://github.com/gulrak/filesystem/pull/32), fixes 550 old-style-cast warnings. 551* Pull request [#34](https://github.com/gulrak/filesystem/pull/34), fixes 552 [TOCTOU](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use) situation 553 on `fs::create_directories`, thanks for the PR! 554* Feature [#35](https://github.com/gulrak/filesystem/issues/35), new CMake 555 option to add an install target `GHC_FILESYSTEM_WITH_INSTALL` that is 556 defaulted to OFF if `ghc::filesystem` is used via `add_subdirectory`. 557* Bugfix for [#33](https://github.com/gulrak/filesystem/issues/33), fixes 558 an issue with `fs::path::lexically_normal()` that leaves a trailing separator 559 in case of a resulting path ending with `..` as last element. 560* Bugfix for [#36](https://github.com/gulrak/filesystem/issues/36), warings 561 on Xcode 11.2 due to unhelpfull references in path element iteration. 562 563### [v1.2.6](https://github.com/gulrak/filesystem/releases/tag/v1.2.6) 564 565* Pull request [#23](https://github.com/gulrak/filesystem/pull/23), tests and 566 examples can now be disabled in CMake via seting `BUILD_TESTING` and 567 `BUILD_EXAMPLES` to `NO`, `OFF` or `FALSE`. 568* Pull request [#25](https://github.com/gulrak/filesystem/pull/25), 569 missing specialization for construction from `std::string_view` when 570 available was added. 571* Additional test case when `std::string_view` is available. 572* Bugfix for [#27](https://github.com/gulrak/filesystem/issues/27), the 573 `fs::path::preferred_seperator` declaration was not compiling on pre 574 C++17 compilers and no test accessed it, to show the problem. Fixed 575 it to an construction C++11 compiler should accept and added a test that 576 is successful on all combinations tested. 577* Bugfix for [#29](https://github.com/gulrak/filesystem/issues/29), stricter 578 warning settings where chosen and resulting warnings where fixed. 579 580### [v1.2.4](https://github.com/gulrak/filesystem/releases/tag/v1.2.4) 581 582* Enabled stronger warning switches and resulting fixed issues on GCC and MinGW 583* Bugfix for #22, the `fs::copy_options` where not forwarded from `fs::copy` to 584 `fs::copy_file` in one of the cases. 585 586### [v1.2.2](https://github.com/gulrak/filesystem/releases/tag/v1.2.2) 587 588* Fix for ([#21](https://github.com/gulrak/filesystem/pull/21)), when compiling 589 on Alpine Linux with musl instead of glibc, the wrong `strerror_r` signature 590 was expected. The complex preprocessor define mix was dropped in favor of 591 the usual dispatch by overloading a unifying wrapper. 592 593### [v1.2.0](https://github.com/gulrak/filesystem/releases/tag/v1.2.0) 594 595* Added MinGW 32/64 and Visual Studio 2015 builds to the CI configuration. 596* Fixed additional compilation issues on MinGW. 597* Pull request ([#13](https://github.com/gulrak/filesystem/pull/13)), set 598 minimum required CMake version to 3.7.2 (as in Debian 8). 599* Pull request ([#14](https://github.com/gulrak/filesystem/pull/14)), added 600 support for a make install target. 601* Bugfix for ([#15](https://github.com/gulrak/filesystem/issues/15)), the 602 forward/impl way of using `ghc::filesystem` missed a `<vector>` include 603 in the windows case. 604* Bugfix for ([#16](https://github.com/gulrak/filesystem/issues/16)), 605 VS2019 didn't like the old size dispatching in the utf8 decoder, so it 606 was changed to a sfinae based approach. 607* New feature ([#17](https://github.com/gulrak/filesystem/issues/17)), optional 608 support for standard conforming `wchar_t/std::wstring` interface when 609 compiling on Windows with defined `GHC_WIN_WSTRING_STRING_TYPE`, this is 610 default when using the `ghc/fs_std*.hpp` header, to enhance compatibility. 611* New feature ([#18](https://github.com/gulrak/filesystem/issues/18)), optional 612 filesystem exceptions/errors on unicode errors with defined 613 `GHC_RAISE_UNICODE_ERRORS` (instead of replacing invalid code points or 614 UTF-8 encoding errors with the replacement character `U+FFFD`). 615* Pull request ([#20](https://github.com/gulrak/filesystem/pull/20)), fix for 616 file handle leak in `fs::copy_file`. 617* Coverage now checked in CI (~95% line coverage). 618 619### [v1.1.4](https://github.com/gulrak/filesystem/releases/tag/v1.1.4) 620 621* Additional Bugfix for ([#12](https://github.com/gulrak/filesystem/issues/12)), 622 error in old unified `readdir/readdir_r` code of `fs::directory_iterator`; 623 as `readdir_r` is now depricated, I decided to drop it and the resulting 624 code is much easier, shorter and due to more refactoring faster 625* Fix for crashing unit tests against MSVC C++17 std::filesystem 626* Travis-CI now additionally test with Xcode 10.2 on macOS 627* Some minor refactorings 628 629### [v1.1.2](https://github.com/gulrak/filesystem/releases/tag/v1.1.2) 630 631* Bugfix for ([#11](https://github.com/gulrak/filesystem/issues/11)), 632 `fs::path::lexically_normal()` had some issues with `".."`-sequences. 633* Bugfix for ([#12](https://github.com/gulrak/filesystem/issues/12)), 634 `fs::recursive_directory_iterator` could run into endless loops, 635 the methods depth() and pop() had issues and the copy behaviour and 636 `input_iterator_tag` conformance was broken, added tests 637* Restructured some CMake code into a macro to ease the support for 638 C++17 std::filesystem builds of tests and examples for interoperability 639 checks. 640* Some fixes on Windows tests to ease interoperability test runs. 641* Reduced noise on `fs::weakly_canonical()` tests against `std::fs` 642* Added simple `du` example showing the `recursive_directory_iterator` 643 used to add the sizes of files in a directory tree. 644* Added error checking in `fs::file_time_type` test helpers 645* `fs::copy()` now conforms LWG #2682, disallowing the use of 646 `copy_option::create_symlinks' to be used on directories 647 648### [v1.1.0](https://github.com/gulrak/filesystem/releases/tag/v1.1.0) 649 650* Restructuring of the project directory. The header files are now using 651 `hpp` as extension to be marked as c++ and they where moved to 652 `include/ghc/` to be able to include by `<ghc/filesystem.hpp>` as the 653 former include name might have been to generic and conflict with other 654 files. 655* Better CMake support: `ghc::filesystem` now can be used as a submodul 656 and added with `add_subdirectory` and will export itself as `ghc_filesystem` 657 target. To use it, only `target_link_libraries(your-target ghc_filesystem)` 658 is needed and the include directories will be set so `#include <ghc/filesystem.hpp>` 659 will be a valid directive. 660 Still you can simply only add the header file to you project and include it 661 from there. 662* Enhancement ([#10](https://github.com/gulrak/filesystem/issues/10)), 663 support for separation of implementation and forwarded api: Two 664 additional simple includes are added, that can be used to forward 665 `ghc::filesystem` declarations (`fs_fwd.hpp`) and to wrap the 666 implementation into a single cpp (`fs_impl.hpp`) 667* The `std::basic_string_view` variants of the `fs::path` api are 668 now supported when compiling with C++17. 669* Added CI integration for Travis-CI and Appveyor. 670* Fixed MinGW compilation issues. 671* Added long filename support for Windows. 672 673### [v1.0.10](https://github.com/gulrak/filesystem/releases/tag/v1.0.10) 674 675* Bugfix for ([#9](https://github.com/gulrak/filesystem/issues/9)), added 676 missing return statement to `ghc::filesystem::path::generic_string()` 677* Added checks to hopefully better compile against Android NDK. There where 678 no tests run yet, so feedback is needed to actually call this supported. 679* `filesystem.h` was renamed `filesystem.hpp` to better reflect that it is 680 a c++ language header. 681 682### [v1.0.8](https://github.com/gulrak/filesystem/releases/tag/v1.0.8) 683 684* Bugfix for ([#6](https://github.com/gulrak/filesystem/issues/6)), where 685 `ghc::filesystem::remove()` and `ghc::filesystem::remove_all()` both are 686 now able to remove a single file and both will not raise an error if the 687 path doesn't exist. 688* Merged pull request ([#7](https://github.com/gulrak/filesystem/pull/7)), 689 a typo leading to setting error code instead of comparing it in 690 `ghc::filesystem::remove()` under Windows. 691* Bugfix for (([#8](https://github.com/gulrak/filesystem/issues/8)), the 692 Windows version of `ghc::filesystem::directory_iterator` now releases 693 resources when reaching `end()` like the POSIX one does. 694 695 696### [v1.0.6](https://github.com/gulrak/filesystem/releases/tag/v1.0.6) 697 698* Bugfix for ([#4](https://github.com/gulrak/filesystem/issues/4)), missing error_code 699 propagation in `ghc::filesystem::copy()` and `ghc::filesystem::remove_all` fixed. 700* Bugfix for ([#5](https://github.com/gulrak/filesystem/issues/5)), added missing std 701 namespace in `ghc::filesystem::recursive_directory_iterator::difference_type`. 702 703### [v1.0.4](https://github.com/gulrak/filesystem/releases/tag/v1.0.4) 704 705* Bugfix for ([#3](https://github.com/gulrak/filesystem/issues/3)), fixed missing inlines 706 and added test to ensure including into multiple implementation files works as expected. 707* Building tests with `-Wall -Wextra -Werror` and fixed resulting issues. 708 709### [v1.0.2](https://github.com/gulrak/filesystem/releases/tag/v1.0.2) 710 711* Updated catch2 to v2.4.0. 712* Refactored `fs.op.permissions` test to work with all tested `std::filesystem` 713 implementations (gcc, clang, msvc++). 714* Added helper class `ghc::filesystem::u8arguments` as `argv` converter, to 715 help follow the UTF-8 path on windows. Simply instantiate it with `argc` and 716 `argv` and it will fetch the Unicode version of the command line and convert 717 it to UTF-8. The destructor reverts the change. 718* Added `examples` folder with hopefully some usefull example usage. Examples are 719 tested (and build) with `ghc::filesystem` and C++17 `std::filesystem` when 720 available. 721* Starting with this version, only even patch level versions will be tagged and 722 odd patch levels mark in-between non-stable wip states. 723* Tests can now also be run against MS version of std::filesystem for comparison. 724* Added missing `fstream` include. 725* Removed non-conforming C99 `timespec`/`timeval` usage. 726* Fixed some integer type mismatches that could lead to warnings. 727* Fixed `chrono` conversion issues in test and example on clang 7.0.0. 728 729### [v1.0.1](https://github.com/gulrak/filesystem/releases/tag/v1.0.1) 730 731* Bugfix: `ghc::filesystem::canonical` now sees empty path as non-existant and reports 732 an error. Due to this `ghc::filesystem::weakly_canonical` now returns relative 733 paths for non-existant argument paths. ([#1](https://github.com/gulrak/filesystem/issues/1)) 734* Bugfix: `ghc::filesystem::remove_all` now also counts directories removed ([#2](https://github.com/gulrak/filesystem/issues/2)) 735* Bugfix: `recursive_directory_iterator` tests didn't respect equality domain issues 736 and dereferencable constraints, leading to fails on `std::filesystem` tests. 737* Bugfix: Some `noexcept` tagged methods and functions could indirectly throw exceptions 738 due to UFT-8 decoding issues. 739* `std_filesystem_test` is now also generated if LLVM/clang 7.0.0 is found. 740 741 742### [v1.0.0](https://github.com/gulrak/filesystem/releases/tag/v1.0.0) 743 744This was the first public release version. It implements the full range of 745C++17 std::filesystem, as far as possible without other C++17 dependencies. 746 747