Name Date Size #Lines LOC

..--

LICENSEH A D25-Apr-20251.1 KiB2016

LICENSE.spdxH A D25-Apr-2025244 87

README.mdH A D25-Apr-202534.6 KiB747595

README.md.licenseH A D25-Apr-202599 54

filesystem.hppH A D25-Apr-2025157.5 KiB5,2174,492

README.md

1![Supported Platforms](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows%20%7C%20FreeBSD-blue.svg)
2![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)
3[![Build Status](https://travis-ci.org/gulrak/filesystem.svg?branch=master)](https://travis-ci.org/gulrak/filesystem)
4[![Build Status](https://ci.appveyor.com/api/projects/status/t07wp3k2cddo0hpo/branch/master?svg=true)](https://ci.appveyor.com/project/gulrak/filesystem)
5[![Build Status](https://api.cirrus-ci.com/github/gulrak/filesystem.svg?branch=master)](https://cirrus-ci.com/github/gulrak/filesystem)
6[![Build Status](https://cloud.drone.io/api/badges/gulrak/filesystem/status.svg?ref=refs/heads/master)](https://cloud.drone.io/gulrak/filesystem)
7[![Coverage Status](https://coveralls.io/repos/github/gulrak/filesystem/badge.svg?branch=master)](https://coveralls.io/github/gulrak/filesystem?branch=master)
8[![Latest Release Tag](https://img.shields.io/github/tag/gulrak/filesystem.svg)](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

README.md.license

1#
2# Copyright (c) 2018, Steffen Schümann <[email protected]>
3# SPDX-License-Identifier: MIT
4#
5