mirror of
https://github.com/boostorg/filesystem.git
synced 2026-01-19 04:12:09 +00:00
Rewritten documentation in QuickBook and Doxygen.
This commit is contained in:
10
bug/bug.cpp
10
bug/bug.cpp
@@ -1,5 +1,10 @@
|
||||
// Copyright Beman Dawes 2014
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// filesystem/bug/bug.cpp
|
||||
|
||||
//[bug_cpp
|
||||
#include <boost/detail/lightweight_test_report.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@@ -13,7 +18,4 @@ int test_main(int, char*[]) // note name
|
||||
|
||||
return ::boost::report_errors(); // required
|
||||
}
|
||||
|
||||
// Copyright Beman Dawes 2014
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// www.boost.org/LICENSE_1_0.txt
|
||||
//]
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=../doc/issue_reporting.html">
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="../doc/issue_reporting.html">../doc/issue_reporting.html</a>.
|
||||
<hr>
|
||||
<p>© Copyright Beman Dawes, 2014</p>
|
||||
<p> Distributed under the Boost Software License, Version 1.0.
|
||||
See http://www.boost.org/LICENSE_1_0.txt</p>
|
||||
</body>
|
||||
</html>
|
||||
2
doc/.gitignore
vendored
Normal file
2
doc/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
html
|
||||
*_reference.xml
|
||||
152
doc/Jamfile.v2
152
doc/Jamfile.v2
@@ -1,23 +1,149 @@
|
||||
# Boost Filesystem Library Example Jamfile
|
||||
|
||||
# Copyright Beman Dawes 2010
|
||||
|
||||
# Copyright 2024 Andrey Semashev
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See www.boost.org/LICENSE_1_0.txt
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Library home page: http://www.boost.org/libs/filesystem
|
||||
using quickbook ;
|
||||
using boostbook ;
|
||||
using doxygen ;
|
||||
using xsltproc ;
|
||||
|
||||
project
|
||||
: requirements
|
||||
<library>/boost/filesystem//boost_filesystem
|
||||
<link>static
|
||||
import set ;
|
||||
import doxygen ;
|
||||
import xsltproc ;
|
||||
import notfile ;
|
||||
import path ;
|
||||
import project ;
|
||||
|
||||
project boost/libs/filesystem/doc ;
|
||||
|
||||
local doxygen_params =
|
||||
<doxygen:param>RECURSIVE=YES
|
||||
<doxygen:param>ALPHABETICAL_INDEX=YES
|
||||
<doxygen:param>REPEAT_BRIEF=YES
|
||||
<doxygen:param>ALWAYS_DETAILED_SEC=YES
|
||||
<doxygen:param>BRIEF_MEMBER_DESC=NO
|
||||
<doxygen:param>ABBREVIATE_BRIEF=YES
|
||||
<doxygen:param>INHERIT_DOCS=YES
|
||||
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
||||
<doxygen:param>HIDE_UNDOC_CLASSES=YES
|
||||
<doxygen:param>HIDE_SCOPE_NAMES=YES
|
||||
<doxygen:param>AUTOLINK_SUPPORT=YES
|
||||
<doxygen:param>DISTRIBUTE_GROUP_DOC=NO
|
||||
<doxygen:param>SUBGROUPING=NO
|
||||
<doxygen:param>EXTRACT_ALL=NO
|
||||
<doxygen:param>EXTRACT_PRIVATE=NO
|
||||
<doxygen:param>BUILTIN_STL_SUPPORT=YES
|
||||
<doxygen:param>ENABLE_PREPROCESSING=YES
|
||||
<doxygen:param>MACRO_EXPANSION=YES
|
||||
<doxygen:param>SHORT_NAMES=YES
|
||||
<doxygen:param>TAB_SIZE=4
|
||||
<doxygen:param>SOURCE_BROWSER=YES
|
||||
<doxygen:param>VERBATIM_HEADERS=NO
|
||||
# <doxygen:param>SEARCH_INCLUDES=YES
|
||||
# <doxygen:param>"INCLUDE_PATH=../../.."
|
||||
# <doxygen:param>EXCLUDE_SYMBOLS="detail detail::*"
|
||||
<doxygen:param>"PREDEFINED=BOOST_FILESYSTEM_DOXYGEN \\
|
||||
BOOST_FILESYSTEM_DECL= \\
|
||||
BOOST_FILESYSTEM_DETAIL_DOC_ALT(alt, ...)=alt \\
|
||||
BOOST_FILESYSTEM_DETAIL_DOC_HIDDEN(...)=... \\
|
||||
BOOST_FILESYSTEM_DETAIL_DOC(...)=__VA_ARGS__ \\
|
||||
BOOST_NO_CXX17_DEDUCTION_GUIDES=1 \\
|
||||
BOOST_BITMASK(x)= \\
|
||||
BOOST_SYMBOL_VISIBLE= \\
|
||||
BOOST_FORCEINLINE=inline \\
|
||||
BOOST_INLINE_VARIABLE=inline \\
|
||||
BOOST_NOEXCEPT=noexcept \\
|
||||
BOOST_CONSTEXPR=constexpr \\
|
||||
BOOST_CXX14_CONSTEXPR=constexpr"
|
||||
<xsl:param>"boost.doxygen.detailns=detail"
|
||||
;
|
||||
|
||||
exe path_table : path_table.cpp ;
|
||||
install path_table-copy : path_table : <location>. ;
|
||||
|
||||
doxygen path_reference
|
||||
:
|
||||
../../../boost/filesystem/path.hpp
|
||||
:
|
||||
$(doxygen_params)
|
||||
<xsl:param>"boost.doxygen.reftitle=Path Reference"
|
||||
<xsl:param>"boost.doxygen.refid=path"
|
||||
;
|
||||
|
||||
doxygen operations_reference
|
||||
:
|
||||
../../../boost/filesystem/operations.hpp
|
||||
:
|
||||
$(doxygen_params)
|
||||
<xsl:param>"boost.doxygen.reftitle=Filesystem Operations"
|
||||
<xsl:param>"boost.doxygen.refid=operations"
|
||||
;
|
||||
|
||||
doxygen directory_reference
|
||||
:
|
||||
../../../boost/filesystem/directory.hpp
|
||||
:
|
||||
$(doxygen_params)
|
||||
<xsl:param>"boost.doxygen.reftitle=Directory Iteration"
|
||||
<xsl:param>"boost.doxygen.refid=directory"
|
||||
;
|
||||
|
||||
doxygen file_status_reference
|
||||
:
|
||||
../../../boost/filesystem/file_status.hpp
|
||||
:
|
||||
$(doxygen_params)
|
||||
<xsl:param>"boost.doxygen.reftitle=File Status"
|
||||
<xsl:param>"boost.doxygen.refid=file_status"
|
||||
;
|
||||
|
||||
doxygen exception_reference
|
||||
:
|
||||
../../../boost/filesystem/exception.hpp
|
||||
:
|
||||
$(doxygen_params)
|
||||
<xsl:param>"boost.doxygen.reftitle=Exceptions"
|
||||
<xsl:param>"boost.doxygen.refid=exceptions"
|
||||
;
|
||||
|
||||
doxygen io_reference
|
||||
:
|
||||
../../../boost/filesystem/cstdio.hpp
|
||||
../../../boost/filesystem/fstream.hpp
|
||||
:
|
||||
$(doxygen_params)
|
||||
<xsl:param>"boost.doxygen.reftitle=I/O Utilities"
|
||||
<xsl:param>"boost.doxygen.refid=io_utilities"
|
||||
;
|
||||
|
||||
xml filesystem_doc
|
||||
:
|
||||
filesystem.qbk
|
||||
:
|
||||
<dependency>path_reference
|
||||
<dependency>operations_reference
|
||||
<dependency>directory_reference
|
||||
<dependency>file_status_reference
|
||||
<dependency>exception_reference
|
||||
<dependency>io_reference
|
||||
;
|
||||
|
||||
boostbook filesystem
|
||||
:
|
||||
filesystem_doc
|
||||
:
|
||||
<xsl:param>"boost.root=../../../.."
|
||||
<xsl:param>"boost.libraries=../../../libs/libraries.htm"
|
||||
<xsl:param>"nav.layout=none"
|
||||
<xsl:param>"boost.image=Boost"
|
||||
<xsl:param>"navig.graphics=1"
|
||||
<xsl:param>"chunk.section.depth=1"
|
||||
<xsl:param>"boost.compact.function=0"
|
||||
<format>pdf:<xsl:param>"boost.url.prefix=https://www.boost.org/doc/libs/release/libs/filesystem/doc/html"
|
||||
;
|
||||
|
||||
###############################################################################
|
||||
alias boostdoc ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease ;
|
||||
alias boostrelease : filesystem ;
|
||||
explicit boostrelease ;
|
||||
|
||||
137
doc/acknowledgements.qbk
Normal file
137
doc/acknowledgements.qbk
Normal file
@@ -0,0 +1,137 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:acknowledgements Acknowledgements]
|
||||
|
||||
[section:v1 Version 1]
|
||||
|
||||
The Filesystem Library was designed and implemented by Beman Dawes. The original `directory_iterator` and `filesystem_error` classes
|
||||
were based on prior work from Dietmar Kühl, as modified by Jan Langer. Thomas Witt was a particular help in later stages of initial
|
||||
development. Peter Dimov and Rob Stewart made many useful suggestions and comments over a long period of time. Howard Hinnant helped
|
||||
with internationalization issues.
|
||||
|
||||
Key [link filesystem.design.requirements design requirements] and [link filesystem.design.realities design realities] were developed
|
||||
during extensive discussions on the Boost mailing list, followed by comments on the initial implementation. Numerous helpful comments
|
||||
were then received during the Formal Review. Participants included:
|
||||
|
||||
* Aaron Brashears
|
||||
* Alan Bellingham
|
||||
* Aleksey Gurtovoy
|
||||
* Alex Rosenberg
|
||||
* Alisdair Meredith
|
||||
* Andy Glew
|
||||
* Anthony Williams
|
||||
* Baptiste Lepilleur
|
||||
* Beman Dawes
|
||||
* Bill Kempf
|
||||
* Bill Seymour
|
||||
* Carl Daniel
|
||||
* Chris Little
|
||||
* Chuck Allison
|
||||
* Craig Henderson
|
||||
* Dan Nuffer
|
||||
* Dan'l Miller
|
||||
* Daniel Frey
|
||||
* Darin Adler
|
||||
* David Abrahams
|
||||
* David Held
|
||||
* Davlet Panech
|
||||
* Dietmar Kühl
|
||||
* Douglas Gregor
|
||||
* Dylan Nicholson
|
||||
* Ed Brey
|
||||
* Eric Jensen
|
||||
* Eric Woodruff
|
||||
* Fedder Skovgaard
|
||||
* Gary Powell
|
||||
* Gennaro Prota
|
||||
* Geoff Leyland
|
||||
* George Heintzelman
|
||||
* Giovanni Bajo
|
||||
* Glen Knowles
|
||||
* Hillel Sims
|
||||
* Howard Hinnant
|
||||
* Jaap Suter
|
||||
* James Dennett
|
||||
* Jan Langer
|
||||
* Jani Kajala
|
||||
* Jason Stewart
|
||||
* Jeff Garland
|
||||
* Jens Maurer
|
||||
* Jesse Jones
|
||||
* Jim Hyslop
|
||||
* Joel de Guzman
|
||||
* Joel Young
|
||||
* John Levon
|
||||
* John Maddock
|
||||
* John Williston
|
||||
* Jonathan Caves
|
||||
* Jonathan Biggar
|
||||
* Jurko
|
||||
* Justus Schwartz
|
||||
* Keith Burton
|
||||
* Ken Hagen
|
||||
* Kostya Altukhov
|
||||
* Mark Rodgers
|
||||
* Martin Schuerch
|
||||
* Matt Austern
|
||||
* Matthias Troyer
|
||||
* Mattias Flodin
|
||||
* Michiel Salters
|
||||
* Mickael Pointier
|
||||
* Misha Bergal
|
||||
* Neal Becker
|
||||
* Noel Yap
|
||||
* Parksie
|
||||
* Patrick Hartling
|
||||
* Pavel Vozenilek
|
||||
* Pete Becker
|
||||
* Peter Dimov
|
||||
* Rainer Deyke
|
||||
* Rene Rivera
|
||||
* Rob Lievaart
|
||||
* Rob Stewart
|
||||
* Ron Garcia
|
||||
* Ross Smith
|
||||
* Sashan
|
||||
* Steve Robbins
|
||||
* Thomas Witt
|
||||
* Tom Harris
|
||||
* Toon Knapen
|
||||
* Victor Wagner
|
||||
* Vincent Finn
|
||||
* Vladimir Prus
|
||||
* Yitzhak Sapir
|
||||
|
||||
A lengthy discussion on the C++ committee's library reflector illuminated the "illusion of portability" problem, particularly in
|
||||
postings by PJ Plauger and Pete Becker.
|
||||
|
||||
Walter Landry provided much help illuminating symbolic link use cases for version 1.31.0.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:v2 Version 2]
|
||||
|
||||
So many people have contributed comments and bug reports that it isn't any longer possible to acknowledge them individually. That said,
|
||||
Peter Dimov and Rob Stewart need to be specially thanked for their many constructive criticisms and suggestions. Terence Wilson and
|
||||
Chris Frey contributed timing programs which helped illuminate performance issues.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:v3 Version 3]
|
||||
|
||||
Peter Dimov suggested the idea of a single path class that could cope with multiple character types and encodings rather than
|
||||
a `basic_path` class template. That idea was the basis for the Version 3 redesign. Walter Landry contributed both the design
|
||||
and implementation of the `copy_any`, `copy_directory`, `copy_symlink`, and `read_symlink` functions.
|
||||
|
||||
Thanks for comments from Robert Stewart, Zach Laine, Peter Dimov, Gregory Peele, Scott McMurray, John Bytheway, Jeff Flinn,
|
||||
Jeffery Bosboom.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
60
doc/cautions.qbk
Normal file
60
doc/cautions.qbk
Normal file
@@ -0,0 +1,60 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:cautions Cautions]
|
||||
|
||||
After reading the tutorial you can dive right into simple, script-like programs using
|
||||
the Filesystem Library! Before doing any serious work, however, there a few cautions to be aware of.
|
||||
|
||||
[section:fs_races Effects and Postconditions not guaranteed in the presence of race-conditions]
|
||||
|
||||
Filesystem function specifications follow the C++ Standard Library form, specifying behavior in terms of
|
||||
effects and postconditions. If a [link filesystem.reference.path.usage.multithreading race-condition] exists,
|
||||
a function's postconditions may no longer be true by the time the function returns to the
|
||||
caller.
|
||||
|
||||
The state of files and directories is often globally shared, and thus may be changed unexpectedly
|
||||
by other threads, processes, or even other computers having network access to the filesystem. As an
|
||||
example of the difficulties this can cause, note that the following asserts may fail:
|
||||
|
||||
```
|
||||
assert(exists("foo") == exists("foo")); /*< This will fail if a non-existent "foo" comes into existence, or an
|
||||
existent "foo" is removed, between the first and second call to `exists()`.
|
||||
This could happen if, during the execution of the example code, another thread,
|
||||
process, or computer is also performing operations in the same directory. */
|
||||
|
||||
remove_all("foo");
|
||||
assert(!exists("foo")); /*< This will fail if between the call to `remove_all()` and the call to
|
||||
`exists()` a new file or directory named "foo" is created by another
|
||||
thread, process, or computer. */
|
||||
|
||||
assert(is_directory("foo") == is_directory("foo")); /*< This will fail if another thread, process, or computer removes an
|
||||
existing file "foo" and then creates a directory named "foo", between the
|
||||
example code's two calls to `is_directory()`. */
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:exceptions Exceptions]
|
||||
|
||||
Unless otherwise specified, Boost.Filesystem functions throw
|
||||
[link filesystem.reference.basic_filesystem_error-constructors `basic_filesystem_error`]
|
||||
exceptions to report failures such as I/O errors. Implementations may also use C++ Standard Library
|
||||
functions which can throw `std::bad_alloc` exceptions to report memory allocation errors. These exceptions
|
||||
may be thrown even though the error condition leading to the exception is not explicitly specified in
|
||||
the function's "Throws" paragraph.
|
||||
|
||||
Nominally non-throwing versions are provided for [link filesystem.reference.operational-functions operational functions]
|
||||
that access the external file system, since these are often used in contexts where error codes may be
|
||||
the preferred way to report an error. Even the nominally non-throwing versions of functions will throw
|
||||
`std::bad_alloc` exceptions to report memory allocation errors. However, functions marked `noexcept` never
|
||||
throw exceptions.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
647
doc/changelog.qbk
Normal file
647
doc/changelog.qbk
Normal file
@@ -0,0 +1,647 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024-2025.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:changelog Changelog]
|
||||
|
||||
[heading 1.91.0]
|
||||
|
||||
* Boost.Filesystem now defines and uses its own platform macros `BOOST_FILESYSTEM_POSIX_API` and `BOOST_FILESYSTEM_WINDOWS_API`. The old `BOOST_POSIX_API`
|
||||
and `BOOST_WINDOWS_API` macros are still defined by Boost.System. Boost.Filesystem will check that the two sets of macros are in sync and by default will
|
||||
fail to compile if not. The compilation error can be reduced to a warning by defininig `BOOST_FILESYSTEM_ALLOW_SYSTEM_API_MISMATCH` to 1 or disabled entirely
|
||||
by defining it to 2. Note that in this case the error code values reported by Boost.Filesystem will not match the error category.
|
||||
* On POSIX platforms not supporting `openat` and related APIs, fixed an error reported by `recursive_directory_iterator` increment when the iterator
|
||||
encounters a dangling symlink and following symlinks is disabled.
|
||||
* [*Breaking change for Cygwin users.] The library now treats Cygwin as a POSIX platform. This has several user-facing consequences, in particular:
|
||||
* The `path::value_type` type has changed from `wchar_t` to `char`. As on other POSIX platforms, wide character paths will be converted to the narrow
|
||||
character encoding using the locale set by `path::imbue`. Note that since Cygwin is running on top of Windows, it will also perform character code
|
||||
conversion internally. It is important that locale in the Cygwin environment is configured correctly.
|
||||
* Path syntax now follows POSIX conventions, Windows-specific paths (e.g. UNC paths, drive names and path prefixes) are not supported.
|
||||
* Certain Windows-specific parts of the API will become inaccessible. Since reparse points are a Windows-only feature, `file_type::reparse_file` will not
|
||||
be reported for files. Reparse point handling is dependent on Cygwin runtime behavior.
|
||||
* Cygwin has its own implementation of symlinks that is incompatible with native Windows symlinks. Boost.Filesystem will now create and operate on Cygwin
|
||||
symlinks.
|
||||
* Error codes reported by Boost.Filesystem will now use POSIX `errno` values.
|
||||
* On DragonFly BSD, NetBSD and Solaris, Boost.Filesystem default path locale now uses UTF-8 for path character encoding.
|
||||
* Reworked documentation, converted to QuickBook and Doxygen.
|
||||
|
||||
[heading 1.89.0]
|
||||
|
||||
* Clear passed `error_code` argument on successful completion of the `permissions` operation. ([github_pr 338])
|
||||
* On Windows, added a workaround for `directory_iterator` constructor failing with an "Invalid Signature" error for a Samba 3.0.2 share, when SMB signing
|
||||
is required. ([github_issue 334])
|
||||
|
||||
[heading 1.87.0]
|
||||
|
||||
* As was announced in 1.84.0, Windows versions prior to 10 are no longer supported.
|
||||
* On Windows, `canonical` is now based on the `GetFinalPathNameByHandleW` WinAPI function. As a side effect, drive letters are converted to upper case,
|
||||
which makes the resulting paths more interoperable. ([github_issue 325])
|
||||
* [*v4:] `canonical` no longer produces a trailing directory separator in the resulting path, if the input path has one.
|
||||
* If a `path` constructor or member function is called with an argument of a user-defined type that is convertible to `path` and one or more
|
||||
[link filesystem.reference.path.requirements.Source `Source`] types, the conversion to `path` is now chosen by default. This may resolve argument
|
||||
conversion ambiguities in some cases, but may also result in a less optimal conversion path. If a different conversion path is desired, users are
|
||||
recommended to use explicit type casts. ([github_issue 326])
|
||||
* Added a workaround for `dirfd` being a macro on FreeBSD 9 and older. ([github_issue 328])
|
||||
|
||||
[heading 1.86.0]
|
||||
|
||||
* `is_empty` operation is now better protected against concurrent filesystem modifications.
|
||||
* On POSIX systems, `is_empty` now indicates error if invoked on a file other than a regular file or a directory.
|
||||
* On Windows, fixed `file_size` and `is_empty` operating on symlinks rather than the files the symlinks refer to. ([github_issue 313])
|
||||
* `directory_entry::refresh` no longer throws an exception if the file referenced by the entry doesn't exist. This makes `directory_entry::status` and
|
||||
`directory_entry::symlink_status`, as well as methods based on them, behave similarly to the equivalent standalone operations. The fact that the file
|
||||
does not exist is still indicated via the `error_code` returned by the corresponding `directory_entry::refresh` overload, or can be seen by testing
|
||||
if the file type returned by `directory_entry::status` or `directory_entry::symlink_status` calls is `file_type::file_not_found`. ([github_issue 314])
|
||||
|
||||
[heading 1.85.0]
|
||||
|
||||
* `path::generic_path` and `path::generic_string` methods now remove duplicate directory separators in the returned paths.
|
||||
* [*v4:] `path::generic_path`, `path::generic_string`, `path::make_preferred` and `path::lexically_normal` avoid converting between backslashes and forward slashes
|
||||
in path root names. For example, on Windows, `path("\\\\?\\c:\\foo").generic_string()` now returns [^"\\\\?\\c:\/foo"] instead of [^"\/\/?\/c:\/foo"]. Similarly,
|
||||
`path("\\\\host/share/foo/..").lexically_normal()` now returns [^"\\\\host\\share"].
|
||||
* [*v4:] `equivalent` now indicates error if either one of the paths doesn't exist.
|
||||
* [*v4:] `absolute` now returns a path with a trailing directory separator when the input path has an empty `relative_path()`. ([github_issue 301])
|
||||
* Added a `unique_path` overload taking a single `error_code& ec` argument. The overload generates a unique path using the default path model.
|
||||
* `weakly_canonical` now produces an absolute path if the input path is relative and contains no elements that exist in the filesystem. ([github_issue 300])
|
||||
* Added a new `copy_options::ignore_attribute_errors` option for `copy_file` and `copy` operations. The new option allows to ignore possible errors while copying
|
||||
file attributes. ([github_issue 179])
|
||||
* On Linux, `copy_file` backends based on `sendfile` and `copy_file_range` system calls will attempt to preallocate storage for the target file. This may reduce
|
||||
filesystem fragmentation and provide early error indication if there is not enough free space. Not all filesystems support this feature; file copying proceeds
|
||||
if storage preallocation is not supported.
|
||||
* On POSIX systems that support [@https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopendir.html `fdopendir`], `openat` and related APIs defined in
|
||||
POSIX.1-2008, as well as on Windows, `recursive_directory_iterator` now uses file descriptors/handles instead of paths to query the file statuses and open nested
|
||||
directories during iteration. This makes directory iteration more resilient to concurrent modifications of the filesystem.
|
||||
* Removed APIs that were previously declared deprecated. In particular, `path` and `recursive_directory_iterator` member functions, `is_regular`, `copy_directory`,
|
||||
`symbolic_link_exists`, `complete`, `copy_option`, `symlink_option`, as well as `boost/filesystem/convenience.hpp` and `boost/filesystem/path_traits.hpp` headers
|
||||
were removed. Possible replacements for the removed components are mentioned in [link filesystem.deprecated.deprecated-names Deprecated names and features] section.
|
||||
* Support for `path` construction, assignment and appending from container types (e.g. `std::vector<char>`) is now disabled by default. Users can still enable this
|
||||
functionality by defining `BOOST_FILESYSTEM_DEPRECATED`. This functionality remains deprecated and will be completely removed in a future release.
|
||||
|
||||
[heading 1.84.0]
|
||||
|
||||
* As was announced in Boost 1.82.0, C++03 is no longer supported. A C++11 or later compiler is required.
|
||||
* Fixed that some `directory_entry` observers taking `error_code& ec` argument did not clear the error code on successful return. ([github_issue 291])
|
||||
* On Windows, improved robustness of date and time conversion and added support for dates before January 1, 1970. ([github_issue 293])
|
||||
* Removed support for Windows CE that was deprecated since Boost.Filesystem 1.79.0.
|
||||
* Removed `boost/filesystem/string_file.hpp` header. The header was deprecated since Boost.Filesystem 1.79.0.
|
||||
* [*Deprecated:] Support for Windows versions older than Windows 10 is deprecated and will be removed in Boost 1.87.
|
||||
|
||||
[heading 1.83.0]
|
||||
|
||||
* Added [member directory_entry::refresh] method that updates internal cached file statuses for the directory entry identified by path.
|
||||
* [*v4:] `directory_entry` constructors and modifiers that initialize or modify the path now automatically call `refresh`. This may result in errors
|
||||
that were not indicated before and in [*v3], if querying the filesystem for file statuses fails (e.g. if the file does not exist). This new behavior
|
||||
is similar to `std::filesystem`.
|
||||
* [*v4:] `directory_entry` constructors and methods taking `file_status` parameters are removed. Users are recommended to remove these arguments and rely
|
||||
on `directory_entry` calling `refresh` internally.
|
||||
* Added `directory_entry` member methods for checking the file type of the file, similar to `std::filesystem`.
|
||||
* Added more methods for testing file status: `is_block_file`, `is_character_file`, `is_fifo`, `is_socket` and `is_reparse_file`.
|
||||
* `recursive_directory_iterator` is now more likely to reuse information about the file type that is obtained during filesystem iteration. This may improve
|
||||
performance. ([github_issue 288])
|
||||
* File streams defined in `boost/filesystem/fstream.hpp` are now movable, if the standard library file streams are. ([github_issue 280])
|
||||
* Added a new header `boost/filesystem/cstdio.hpp` with a portable `fopen` overload that takes `path` as the first argument. This function is equivalent to
|
||||
`std::fopen`, except that on Windows it uses the native wide character encoding for paths.
|
||||
* Generic `path` comparison operators are now more restricted to avoid potential ambiguities when user's code contains a `using namespace boost::filesystem;`
|
||||
directive. ([github_issue 285])
|
||||
* Fixed potential overload resolution ambiguity in users' code, where `path` constructors from iterators could interfere with function overloads taking a
|
||||
`std::initializer_list` argument. ([github_issue 287])
|
||||
* On Windows, added more workarounds for errors returned by various filesystems when creating a directory iterator. ([github_issue 284], [github_issue 286])
|
||||
* On Windows, relaxed access rights needed for querying file times. ([github_issue 290])
|
||||
|
||||
[heading 1.82.0]
|
||||
|
||||
* Due to changes in Boost.System and some other libraries used in Boost.Filesystem, the support for C++03 is deprecated. C++11 will become the minimum
|
||||
starting with Boost.Filesystem 1.84.
|
||||
* Fixed compilation errors that could have been caused by `path` conversion constructors being too permissive on the accepted arguments.
|
||||
([github_issue 273])
|
||||
* [*v4:] `path::remove_filename` now presesrves the trailing directory separator. ([github_issue 271])
|
||||
* Added `path::remove_filename_and_trailing_separators`, which removes the filename and directory separators preceding it from the path. This behavior
|
||||
is similar to `path::remove_filename` in Filesystem [*v3], but is also usable in [*v4].
|
||||
* Added `path::replace_filename`, which replaces filename in a path.
|
||||
* Updated implementation of the library version selection to avoid ODR violations. ([github_issue 279])
|
||||
* On Windows, added a workaround for querying file attributes for files in SMBv1 shares. Previously, directories in SMBv1 shares could have been reported
|
||||
as regular files. This does not affect SMBv2 or later. ([github_issue 282])
|
||||
|
||||
[heading 1.81.0]
|
||||
|
||||
* [*Deprecated:] `path` construction, assignment and appending from containers of characters, such as `std::vector<char>` or `std::list<wchar_t>`,
|
||||
is deprecated in [*v3] and removed in [*v4]. Please use string types or iterators instead.
|
||||
* [*Deprecated:] `boost/filesystem/path_traits.hpp` header is deprecated and will be removed in a future release. The header contained implementation details
|
||||
of `path` and should not be used in user's code.
|
||||
* Previously deprecated APIs will now generate compilation warnings on use. To suppress these warnings, `BOOST_FILESYSTEM_ALLOW_DEPRECATED` macro can be
|
||||
defined when compiling user's code.
|
||||
* Fixed compilation due to a missing include on POSIX systems that do not support `*at` APIs. ([github_issue 250])
|
||||
* On Windows prior to 10, added a workaround for network share filesystem that produces `ERROR_INVALID_PARAMETER` when constructing directory iterators.
|
||||
([github_pr 246])
|
||||
* On Windows, fixed `weakly_canonical` failing with an `ERROR_INVALID_FUNCTION` error code if the path started with the [^"\\\\?\\"] prefix.
|
||||
([github_issue 247])
|
||||
* Added support for `std::string_view`, `boost::string_view` and `boost::container::string` (as well as respective `wchar_t` counterparts) in `path`
|
||||
constructors, assignment and appending operations. ([github_issue 208])
|
||||
* `path` constructors, assignment and appending operations taking a pair of iterators will no longer accept iterators with value types that are not one of
|
||||
the supported path character types.
|
||||
* On Windows, improved compatibility of `directory_iterator` with various mounted filesystems and Wine releases prior to 7.21.
|
||||
([github_issue 255])
|
||||
* On Windows, deduplicated files are now reported as regular files rather than reparse files. ([github_issue 262])
|
||||
|
||||
[heading 1.80.0]
|
||||
|
||||
* On Windows, added a fallback implementation for querying file attributes in case if the file cannot be opened with `ERROR_ACCESS_DENIED` error. This may allow
|
||||
`status` and `symlink_status` to succeed for system files and directories that are not reparse points or symlinks. ([github_issue 234])
|
||||
* On Windows, added a workaround for FAT\/exFAT filesystems that produce `ERROR_INVALID_PARAMETER` when querying file attributes. This affected `status` and
|
||||
`symlink_status`, which reported that files do not exist, and directory iterators, which failed to construct, as well as other dependent operations.
|
||||
([github_issue 236])
|
||||
* Worked around a compilation problem on [@https://www.rtems.org/ RTEMS]. ([github_pr 240])
|
||||
* On Linux, corrected switching to `sendfile` `copy_file` implementation if `copy_file_range` failed with `ENOSYS` in runtime. The `sendfile` fallback
|
||||
implementation used to skip the filesystem type check and could fail for some filesystems.
|
||||
* On POSIX systems supporting `openat` and related APIs defined in POSIX.1-2008 and on Windows Vista and later, improved protection of `remove_all` against
|
||||
[@https://www.cve.org/CVERecord?id=CVE-2022-21658 CVE-2022-21658] that was implemented in the previous release. The previous fix could still result in removing
|
||||
unintended files in [@https://github.com/boostorg/filesystem/issues/224#issuecomment-1183738097 certain conditions]. Other systems remain vulnerable.
|
||||
|
||||
[heading 1.79.0]
|
||||
|
||||
* [*v3:] `path::replace_extension` now works in terms of [*v3] definition of `path::extension` rather than [*v4].
|
||||
* Fixed compilation of path appending and concatenation operators with arguments of types convertible to `path` or compatible string type. ([github_issue 223])
|
||||
* On POSIX systems that support [@https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopendir.html `fdopendir`] and
|
||||
[@https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html `O_NOFOLLOW`] and on Windows, `remove_all` is now protected against
|
||||
[@https://www.cve.org/CVERecord?id=CVE-2022-21658 CVE-2022-21658]. The vulnerability is a race condition that allows a third party process to replace
|
||||
a directory that is being concurrently processed by `remove_all` with a directory symlink and cause `remove_all` to follow the symlink and remove files
|
||||
in the linked directory instead of removing the symlink itself. ([github_issue 224])
|
||||
* On Windows, in `remove` and `remove_all` implementation, use POSIX semantics for file removal, when supported by the OS (Windows 10 1709 and later).
|
||||
When POSIX semantics is supported, the file name is removed from the filesystem namespace as soon as the file is marked for deletion, even if it is still
|
||||
open and in use. With legacy Windows semantics, the file name remains present in the the filesystem namespace until the last file handle to the file is closed,
|
||||
which allows the file marked for deletion to be opened and prevents creating new files with the same name. ([github_issue 216])
|
||||
* On Windows, `remove` and `remove_all` now support deleting read-only directories. Support for removing read-only non-directory files was added previously.
|
||||
* On Windows, `directory_iterator` internal implementation has been reworked to better utilize modern Windows APIs, which may improve performance while
|
||||
handling symlinks.
|
||||
* On Windows, initialize internal WinAPI function pointers early, if possible, to allow Boost.Filesystem operations to be invoked in global constructors. This is
|
||||
only supported on MSVC, GCC, Clang and compatible compilers.
|
||||
* On Windows, `resize_file` should no longer fail with an error if the file to be resized is opened.
|
||||
* Disabled use of the `statx` syscall on Android prior to 11.0 (API version 30). The syscall is blacklisted by seccomp and causes process termination in runtime.
|
||||
([github_issue 229])
|
||||
* [*Deprecated:] `boost/filesystem/string_file.hpp` header is deprecated and will be removed in a future release. The header is no longer included by
|
||||
`boost/filesystem.hpp` by default. Users are advised to implement the functionality themselves or migrate to other implementations.
|
||||
* [*Deprecated:] Windows CE support is deprecated and will be removed in a future release. Windows CE has been untested for many years and is likely non-functional.
|
||||
|
||||
[heading 1.78.0]
|
||||
|
||||
* [*v4:] `path::filename` and `path::iterator` no longer return an implicit trailing dot ([^"."]) element if the path ends with a directory separator. Instead,
|
||||
an empty path is returned, similar to C++17 std::filesystem. This also affects other methods that are defined in terms of iterators or filename, such as
|
||||
`path::stem`, `path::compare` or `lexicographical_compare`. For example, `path("a/b/") == path("a/b/.")` no longer holds true. ([github_issue 193])
|
||||
* [*v4:] `path::lexically_normal` no longer produce a trailing dot ([^"."]) element and omits a directory separator after a trailing dot-dot ([^".."]) element
|
||||
in the normalized paths.
|
||||
* [*v4:] `path` append operations now consider root name and root directory in the appended path. If the appended path is absolute, or root name is present
|
||||
and differs from the source path, the resulting path is equivalent to the appended path. If root directory is present, the result is the root directory and
|
||||
relative path rebased on top of the root name of the source path. Otherwise, the behavior is similar to v3. ([github_issue 214])
|
||||
* `path::lexically_normal` now converts directory separators to preferred separators in the root name of the normalized paths.
|
||||
* Optimized overloads of `path::assign`, `path::append`, `path::concat` and the corresponding operators to avoid unnecessary path copying and reduce
|
||||
the amount of code redundancy.
|
||||
* On POSIX systems, fixed `absolute(p, base)` returning a path with root name `base.root_name()` if `p` starts with a root directory. In such a case `p`
|
||||
is already an absolute path and should be returned as is.
|
||||
* `create_directories` no longer reports an error if the input path consists entirely of dot ([^"."]) and dot-dot ([^".."]) elements. The implementation is no longer
|
||||
using recursion internally and therefore is better protected from stack overflow on extremely long paths.
|
||||
* On Windows, `remove` now supports deleting read-only files. The operation will attempt to reset the read-only attribute prior to removal. Note that this
|
||||
introduces a possibility of the read-only attribute being left unset, if the operation fails and the original value of the attribute fails to be restored.
|
||||
This also affects `remove_all`. ([github_issue 216])
|
||||
* `remove_all` now returns `static_cast< uintmax_t >(-1)` in case of error, similar to C++17 std::filesystem.
|
||||
* Fixed a linking error about unresolved references to Boost.ContainerHash functions when user's code includes `boost/filesystem/path.hpp` but not
|
||||
`boost/container_hash/hash.hpp` and the compiler is set to preserve unused inline functions. ([github_issue 215])
|
||||
* Added a workaround for MSVC and compatible compilers eliminating path globals cleanup in release builds. This could lead to a memory leak if Boost.Filesystem
|
||||
shared library was repeatedly loaded and unloaded in the process. ([github_issue 217])
|
||||
|
||||
[heading 1.77.0]
|
||||
|
||||
[*Introducing Boost.Filesystem v4.] This new version of the library removes all deprecated features of v3 and also makes a number of breaking API changes intended
|
||||
to make Boost.Filesystem more compatible with std::filesystem introduced in C++17 (original proposal: [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4099.html
|
||||
ISO C++ File System Technical Specification]). The differences are described in the release notes and documentation using [*v3] and [*v4] tags and are also
|
||||
summarised in a [link filesystem.v4 separate section]. Users can select Boost.Filesystem version by defining `BOOST_FILESYSTEM_VERSION` macro to either 3 or 4
|
||||
when compiling their code.
|
||||
|
||||
There is no need to separately compile Boost.Filesystem for each library version — a single binary supports both v3 and v4. Users should avoid using both v3 and v4
|
||||
in the same application as this can lead to subtle bugs.
|
||||
|
||||
Currently, v3 is the default. In a future release v4 will become the default, and eventually v3 will be removed. v4 is functional, but it is still a work in
|
||||
progress and there may be breaking API changes in the future.
|
||||
|
||||
Other changes in this release include:
|
||||
|
||||
* [*v4:] `path::filename`, `path::stem` and `path::extension` no longer consider root name or root directory of the path as a filename if the path only consists
|
||||
of those components. For example, on Windows `path("C:").filename()` used to return [^"C:"] and `path("C:\\").filename()` used to return [^"\\"] and both will return
|
||||
an empty path now. ([github_issue 88])
|
||||
* [*v4:] `path::stem` and `path::extension` no longer treat a filename that starts with a dot and has no other dots as an extension. Filenames starting with a dot
|
||||
are commonly treated as filenames with an empty extension. The leading dot is used to indicate a hidden file on most UNIX-like systems.
|
||||
([github_issue 88])
|
||||
* [*New:] Improved support for various path prefixes on Windows. Added support for local device prefix ([^"\\\\.\\"]) and experimental support for NT path prefix
|
||||
([^"\\??\\"]). The prefixes will be included in the root name of a path. Note that using the prefixes with Boost.Filesystem v3 can lead to surprising results
|
||||
(e.g. `path("\\\\.\\").stem() == "\\\\"`). It is recommended to use the prefixes only with Boost.Filesystem v4.
|
||||
* Reworked `path::lexically_normal` implementation to eliminate some cases of duplicate dot ([^"."]) elements in the normalized paths.
|
||||
* [*New:] Added runtime detection of the `statx` and `getrandom` system calls on Linux. This can be useful if the syscall is present at compile time but fails
|
||||
with `ENOSYS` at run time (for example, in Docker containers that restrict the syscall, even if available on the host). ([github_issue 172])
|
||||
* [*New:] Added support for disabling usage of various system APIs at library build time. This can be useful when a certain API is detected as present by
|
||||
the library configuration scripts but must not be used for some reason (for example, when runtime detection does not work on the target system). See
|
||||
the description of [link filesystem.install.config_macros configuration macros] for more details.
|
||||
* [*New:] Added `copy_options::synchronize_data` and `copy_options::synchronize` options for the `copy_file` operation. These options allow to synchronize
|
||||
the written data and attributes with the permanent storage. These options are expensive in terms of performance, but allow to ensure reliability of the copied
|
||||
data. Note that `copy_file` performed implicit data synchronization on POSIX systems since Boost.Filesystem 1.74.0. This release adds support for more platforms
|
||||
and disables data synchronization by default while allowing the caller to explicitly request it. ([github_issue 186])
|
||||
* Added handling of `EINTR` error code on POSIX systems for some system calls issued internally. In particular, `EINTR` could have been ignored on `close`,
|
||||
which on HP-UX would result in a leaked file descriptor.
|
||||
* In the `copy_file` implementations based on Linux `sendfile` and `copy_file_range` system calls, added handling of error codes indicating that a particular
|
||||
filesystem does not support the system call and fall back to the generic `read`\/`write` loop. This should fix `copy_file` failing on [@https://www.ecryptfs.org/
|
||||
eCryptFS] and possibly other filesystems. ([github_issue 184])
|
||||
* The `copy_file_range` system call is now used since Linux kernel 4.5, whereas previously it was only enabled since 5.3. The `copy_file` implementation will
|
||||
fall back to `sendfile` or `read`\/`write` loop if `copy_file_range` fails to copy a given file across filesystems.
|
||||
* The `copy_file` implementations based on Linux `sendfile` and `copy_file_range` system calls will not be used on filesystems that are known to contain files
|
||||
with generated content. These system calls are incompatible with such files, and copying them would result in zero-sized files. The generic `read`\/`write`
|
||||
loop will be used instead. Currently, the blacklisted filesystems are: procfs, sysfs, tracefs and debugfs.
|
||||
* In the `copy_file` implementation based on `read`\/`write` loop, increased the maximum size of the buffer used for temporary storage and take into account
|
||||
the target filesystem block size for more optimal performance.
|
||||
* On Windows CE, calling `current_path` to obtain the current path for a process will now fail with an error instead of returning successfully with a root path.
|
||||
This platform does not support current directory. Changing the current path was already failing similarly in previous releases of Boost.Filesystem.
|
||||
* In `canonical`, fixed the check for a symlink referencing a directory above root, if an earlier symlink was resolved to an absolute path with a different root
|
||||
from the original path.
|
||||
* In `canonical`, added a limit for the maximum number of symlinks that can be resolved during the call. The limit is currently at least 40 symlinks.
|
||||
* On Windows, `canonical` and `weakly_canonical` will now use `path::preferred_separator` for the root directory separator in the resulting paths. This fixes
|
||||
"file not found" errors caused by Windows API not handling generic separators in UNC paths and paths that start with the Win32 filesystem prefix ([^"\\\\?\\"]).
|
||||
([github_issue 87])
|
||||
* [*New:] Added `weakly_canonical` overloads taking `base` path as an argument.
|
||||
* On Windows, `weakly_canonical` no longer fails with an error if the input path contains elements that do not exist in the filesystem but are cancelled by
|
||||
a subsequent dot-dot ([^".."]) element. For example, `weakly_canonical("C:\\a\\..")` would previously fail if [^"C:\\a"] directory did not exist.
|
||||
([github_issue 201])
|
||||
* In `read_symlink` on Windows, corrected reparse point handling. The operation would return an empty path for some mount points (for example, created by
|
||||
[@https://www.box.com/ Box] cloud storage driver) and directory junction points that had empty print names. The new implementation now parses substitute
|
||||
name of the reparse point and attempts to reconstruct a Win32 path from it. ([github_issue 187])
|
||||
* On Windows, file streams provided in `boost/filesystem/fstream.hpp` will use wide character paths on libc++ versions 7.0 and higher, when the standard library
|
||||
supports opening files with wide character paths. ([github_issue 181])
|
||||
* On Windows, creating symlinks should no longer require elevated privileges, if Windows is configured in
|
||||
[@https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development Developer mode].
|
||||
* With some compilers, global objects used internally in Boost.Filesystem are now destroyed after user's global destructors are called. This allows to call
|
||||
Boost.Filesystem methods during the program termination stage. In particular, this concerns the path locale that is used for character code conversion
|
||||
and can be installed by calling `path::imbue`. The supported compilers include MSVC, GCC and Clang, as well as other compilers that support customizing
|
||||
program initialization order through `#pragma section` (for MSVC-compatible compilers) or `__attribute__ ((init_priority))` (for GCC-compatible compilers).
|
||||
|
||||
[heading 1.76.0]
|
||||
|
||||
* Updated compatibility with [@https://wasi.dev/ WASI] platform. ([github_pr 169])
|
||||
* Fixed an exception being thrown by `path::remove_filename` if the path is [^"\/\/\/\/"]. ([github_issue 176])
|
||||
* Fixed `create_directories` disregarding errors from file status query operations issued internally. This could result in incorrect error codes returned
|
||||
by `create_directories`. ([github_issue 182])
|
||||
|
||||
[heading 1.75.0]
|
||||
|
||||
* [*New:] Added `creation_time` operation, which allows to obtain file creation time. (Inspired by [github_pr 134])
|
||||
* The returned value of `last_write_time(p, ec)` operation in case of failure has been changed to a minimal value representable by `std::time_t` instead of -1.
|
||||
* The returned value of `hard_link_count(p, ec)` operation in case of failure has been changed to `static_cast<uintmax_t>(-1)` instead of 0.
|
||||
* On POSIX systems, `file_size` will now indicate error code `errc::function_not_supported` if the path resolves to a non-regular file. Previously,
|
||||
`errc::operation_not_permitted` was reported.
|
||||
* On Linux, many operations now use `statx` system call internally, when possible, which allows to reduce the amount of information queried from the filesystem
|
||||
and potentially improve performance. The `statx` system call was introduced in Linux kernel 4.11.
|
||||
* Removed `const`-qualification from return types of some `path` methods. This could prevent move construction and move assignment at the call site
|
||||
in some cases. ([github_issue 160])
|
||||
* On OpenBSD 4.4 and newer, use `statvfs` system call to obtain filesystem space information. (Inspired by [github_pr 162])
|
||||
* On Windows, `space` now returns with an error if the provided path does not idendify an existing file. ([github_issue 167])
|
||||
|
||||
[heading 1.74.0]
|
||||
|
||||
* Removed compile-time checks for support for symlinks and hardlink on Windows. Instead, a runtime check is used. ([github_pr 142])
|
||||
* Fixed handling of reparse points in `canonical` and `read_symlink` on Windows. This also affects other algorithms that involve `canonical` and `read_symlink`
|
||||
in their implementation. ([github_pr 100], [github_issue 99])
|
||||
* Fixed that `read_symlink` on Windows could potentially fail or cause failures elsewhere with a sharing violation error, if the same symlink was opened
|
||||
concurrently. ([github_issue 138])
|
||||
* Fixed that `is_symlink(directory_entry)` would always return `false`, even if the directory entry actually referred to a symlink. ([github_pr 148])
|
||||
* Added missing status inspection operation overloads for `directory_entry` and `error_code` (e.g. `is_directory(directory_entry, error_code&)`).
|
||||
Removed incorrect `noexcept` specifications for the overloads not taking the `error_code` arguments.
|
||||
* `copy_file` implementation has been updated to perform checks on the source and target files, as required by C++20 (\[fs.op.copy.file\]\/4.1). In particular,
|
||||
the operation will fail if the source or target file is not a regular file or the source and target paths identify the same file.
|
||||
* `copy_file` on POSIX systems will now also copy the source file permissions to the target file, if the target file is overwritten.
|
||||
* [*New:] Added `copy_file` implementations based on `sendfile` and `copy_file_range` system calls on Linux, which may improve file copying performance,
|
||||
especially on network filesystems.
|
||||
* [*Deprecated:] The `copy_option` enumeration that is used with the `copy_file` operation is deprecated. As a replacement, the new enum `copy_options`
|
||||
(note the trailing 's') has been added. The new enum contains values similar to the `copy_options` enum from C++20. The old enum values are mapped onto
|
||||
the new enum. The old enum will be removed in a future release.
|
||||
* [*New:] Added `copy_options::skip_existing` option, which allows `copy_file` operation to succeed without overwriting the target file, if it exists.
|
||||
* [*New:] Added `copy_options::update_existing` option, which allows `copy_file` operation to conditionally overwrite the target file, if it exists, if
|
||||
its last write time is older than that of the replacement file.
|
||||
* [*New:] `copy_file` now returns `bool`, which indicates whether the file was copied.
|
||||
* [*New, breaking change:] `copy` operation has been extended and reworked to implement behavior specified in C++20 \[fs.op.copy\]. This includes support
|
||||
for `copy_options::recursive`, `copy_options::copy_symlinks`, `copy_options::skip_symlinks`, `copy_options::directories_only`, `copy_options::create_symlinks`
|
||||
and `copy_options::create_hard_links` options. The operation performs additional checks based on the specified options. Applying `copy` to a directory with
|
||||
default `copy_options` will now also copy files residing in that directory (but not nested directories or files in those directories).
|
||||
* [*New:] Added `create_directory` overload taking two paths. The second path is a path to an existing directory, which is used as a source of permission
|
||||
attributes to use in the directory to create.
|
||||
* [*Deprecated:] `copy_directory` operation has been deprecated in favor of the new `create_directory` overload. Note that the two operations have reversed order
|
||||
of the path arguments.
|
||||
* `equivalent` on POSIX systems now returns the actual error code from the OS if one of the paths does not resolve to a file. Previously the function would return
|
||||
an error code of 1. ([github_issue 141])
|
||||
* `equivalent` no longer considers file size and last modification time in order to test whether the two paths refer to the same file. These checks could result
|
||||
in a false negative if the file was modified during the `equivalent` call.
|
||||
* [*New:] Added `absolute` overloads taking `error_code` argument.
|
||||
* Operations that have `current_path()` as the default value of their arguments and also have an `error_code` argument will use the `current_path(error_code& ec)`
|
||||
overload to obtain the current path, so that its failure is reported via the `error_code` argument instead of an exception.
|
||||
* `space` now initializes the `space_info` structure members to -1 values on error, as required by C++20 (\[fs.op.space\]\/1).
|
||||
* `space` on Windows now accepts paths referring to arbitrary files, not only directories. This is similar to POSIX systems and corresponds to the operation
|
||||
description in C++20. ([github_issue 73])
|
||||
* [*New:] Added implementation of `temp_directory_path` for Windows CE. ([github_pr 25])
|
||||
* [*New:] Improved compatibility with [@https://wasi.dev/ WASI] platform. ([github_pr 144])
|
||||
* [*New:] Improved support for Embarcadero compilers. ([github_pr 130])
|
||||
* [*New:] Added implementations of `unique_path` operation based on `getrandom` (Linux), `arc4random_buf` (OpenBSD\/FreeBSD\/CloudABI) and BCrypt (Windows) system APIs.
|
||||
* [*Deprecated:] Auto-linking against system libraries on Windows with MSVC-compatible compilers is deprecated and will be removed in a future release. This
|
||||
affects users linking against static library of Boost.Filesystem. Users are advised to update their project build systems to either use a shared library of
|
||||
Boost.Filesystem, or explicitly specify the dependencies of Boost.Filesystem in the linker command line. In the future, the dependency information may also be
|
||||
exposed through CMake config files.
|
||||
|
||||
[heading 1.72.0]
|
||||
|
||||
* Extracted `filesystem_error` to `exception.hpp`; `file_status` and associated enums and functions to `file_status.hpp`; `directory_entry`, `directory_iterator`
|
||||
and `recursive_directory_iterator` to `directory.hpp`.
|
||||
* [*Deprecated:] For backward compatibility `operations.hpp` still includes the new headers `exception.hpp`, `file_status.hpp` and `directory.hpp`, unless
|
||||
`BOOST_FILESYSTEM_NO_DEPRECATED` macro is defined. These implicit includes are considered deprecated and will be removed in a future release. Users are encouraged
|
||||
to include the new headers directly or include `filesystem.hpp`.
|
||||
* The `filesystem_error` exception is now implemented in the compiled library of Boost.Filesystem. Users may need to add linking with Boost.Filesystem library
|
||||
in their projects.
|
||||
* On POSIX.1-2008 platforms, use `utimensat` instead of `utime`. `utime` is declared obsolete in POSIX.1-2008 and can be disabled e.g. in uClibc-ng. ([github_pr 115])
|
||||
* `directory_iterator` is now left in the end state on memory allocation errors.
|
||||
* In `directory_iterator` on POSIX systems, support for `readdir`\/`readdir_r` has been reworked to avoid memory allocations for `dirent` structures when `readdir`
|
||||
is used. This reduces memory consumption and eliminates the possibility of buffer overruns in case if `readdir` produces a very long directory name.
|
||||
* On Windows, use Boost.WinAPI to select the target Windows version.
|
||||
* [*New:] Added `directory_options` enum, which reflects the same named enum from C++20. The enum is supported in `directory_iterator` and `recursive_directory_iterator`
|
||||
to customize iteration behavior. In particular, the iterators now support skipping directories that can't be opened due to insufficient permissions.
|
||||
The `symlink_option` enum is now deprecated and should be replaced with `directory_options`.
|
||||
* By default, `recursive_directory_iterator` is now reset to the end state in case of errors, as required by C++20. ([github_issue 112])
|
||||
* [*New:] Added `directory_options::pop_on_error` option, which configures `recursive_directory_iterator` so that it attempts to recover from iteration errors
|
||||
by repeatedly invoking `pop()` until it succeeds or the end state is reached. ([github_issue 113])
|
||||
* [*New:] Added `directory_options::skip_dangling_symlinks` option, which configures `recursive_directory_iterator` so that it doesn't follow dangling directory
|
||||
symlinks and continues iteration instead of reporting an error.
|
||||
* [*Deprecated:] The following members of `recursive_directory_iterator` are now marked as deprecated: `level()`, `no_push_pending()`, `no_push_request()`, `no_push()`.
|
||||
Users are advised to replace their use with the standard counterparts: `depth()`, `recursion_pending()`, `disable_recursion_pending()`. Note that
|
||||
`recursion_pending()` has the opposite meaning compared to `no_push_pending()` and `no_push_request()`. Deprecated methods will be removed in a future release.
|
||||
* Fixed `path::lexically_relative` (and any dependent algorithms) to correctly handle empty, dot and dot-dot path elements in its argument. The behavior is made
|
||||
closer to C++17 `std::path::lexically_relative` in that empty and dot path elements are ignored and dot-dot path elements are accounted by decreasing the number
|
||||
of dot-dot path elements to generate in the resulting relative path. ([github_issue 76])
|
||||
|
||||
[heading 1.71.0]
|
||||
|
||||
* [*New:] Added minimal support for CMake. ([github_pr 106])
|
||||
* Fixed incorrect `error_code` returned from directory iterator increment when `readdir_r` is used.
|
||||
* For `path`, fixed rvalue-aware `operator/` return type to return an rvalue instead of rvalue reference. This fixes leaving a dangling reference in the user's code
|
||||
if the result of `operator/` is bound to a const reference. ([github_issue 110])
|
||||
* Fixes for better compatibility with Windows CE. ([github_pr 24])
|
||||
|
||||
[heading 1.70.0]
|
||||
|
||||
* [*New:] Added support for movability to directory iterators.
|
||||
* [*New:] Added file status query overloads for directory_entry. This avoids a relatively expensive OS query when file status is requested for a result of
|
||||
dereferencing a directory iterator. ([github_pr 55])
|
||||
* Fixed a few instances of dereferencing `std::string::end()` in path implementation.
|
||||
* Fixed program termination in case of out of memory condition in directory iterators constructors and operations accepting a reference to `error_code`. ([github_issue 58])
|
||||
* Fixed possible linking errors caused by missing definitions of static members of `path`. ([trac_issue 12759])
|
||||
* Fixed possible use of uninitialized data in directory iterator increment operation on Linux. ([github_issue 97])
|
||||
* Reworked `current_path` and `read_symlink` implementation to avoid possible memory exhaustion on broken or tampered with filesystems. The functions
|
||||
now have an internal limit of the path size they will accept from the OS, which is currently 16 MiB.
|
||||
* Increased the size of the internal buffer used by `copy_file`.
|
||||
|
||||
[heading 1.69.0]
|
||||
|
||||
* Don't use `readdir_r` on Linux and Android since the `readdir` function is already thread-safe. ([github_pr 68], [github_issue 72])
|
||||
* Fixed crashes in `boost::filesystem::copy` due to undefined behavior in the implementation. ([github_pr 71])
|
||||
* Fixed undefined behavior in `boost::filesystem::directory_iterator` implementation. ([github_pr 77])
|
||||
* Fixed compilation errors when using directory iterators with `BOOST_FOREACH`.
|
||||
* Removed workarounds for older PGI C++ compiler versions to fix compilation on the newer ones. ([github_pr 49])
|
||||
* Fixed MSVC warnings about narrowing conversions. ([github_pr 44])
|
||||
|
||||
[heading 1.67.0]
|
||||
|
||||
* Fix static initialization issue that caused a crash if path operations were used before main(). ([github_pr 62], [github_pr 43])
|
||||
|
||||
[heading 1.66.0]
|
||||
|
||||
* Clean up some tutorial example code and fix the wording for it in the tutorial. Thanks to Anmol-Singh-Jaggi for pull request [github_pr 11].
|
||||
|
||||
[heading 1.64.0]
|
||||
|
||||
* `is_empty()`overload with `error_code` parameter should not throw on error. Thanks to ldqrk for pull request [github_pr 42].
|
||||
* Fix [trac_issue 10731], ['Evaluate path.extension only once]. Thanks to Daniel Krügler for pull request [github_pr 41].
|
||||
* Fix error propagation in `space(p, ec)`. Thanks to cmuellner for pull request [github_pr 39].
|
||||
* Add `test/config_info.cpp` to increase macro state reporting in hopes of easing debugging on remote machines.
|
||||
* Fix `operations_test` failure on MinGW: MinGW defines `__MINGW32__` rather than `_MSC_VER`, so also test for `__MINGW32__` to see if
|
||||
`setenv`\/`unsetenv` workaround needed.
|
||||
|
||||
[heading 1.63.0]
|
||||
|
||||
* [*Deprecated `generic()` function name]: The undocumented experimental class `path` member function `generic()` has been renamed `generic_path()`. Fixes
|
||||
[trac_issue 11855]. Unless the macro `BOOST_FILESYSTEM_NO_DEPRECATED` is defined, the original `generic()` will continue to be supplied as
|
||||
a workaround for existing user code. But `generic()` is deprecated. User code should migrate to the new name.
|
||||
* [*New:] Class `path` adds constexpr constants `separator` and `dot` of the type appropriate for the platform, and adds query functions
|
||||
[link filesystem.reference.filename_is_dot `filename_is_dot`] and [link filesystem.reference.filename_is_dot_dot `filename_is_dot_dot`].
|
||||
These add convenience and the implementations may be more efficient that user coded equivalent functions.
|
||||
* Fix [trac_issue 12578]. This bug in `directory_iterator` and `recursive_directory_iterator` equality testing has existed more than a dozen years.
|
||||
Nowadays test driven development would likely have detected the problem in early development. Sigh.
|
||||
* Fix [trac_issue 12495], from Samantha Ritter. Also affected `create_directory()`. Charles Olivi submitted a pull request with some particularly
|
||||
helpful test cases.
|
||||
* Fix [trac_issue 7307] This is a tough one to test. There are three internal function calls where errors might arise, and it would take too much time
|
||||
to write tests for each of those cases. Someday we will have Titus Winter's mock installable file system, but for now are relying on code inspection
|
||||
rather than testing.
|
||||
* Fix a cygwin warning and a cygwin error. Thanks to thtrummer for pull request [github_pr 30].
|
||||
* Fixed two broken links in reference docs. Thanks to tbeu for pull request [github_pr 34].
|
||||
* Fix reference doc signatures for `path` member functions `stem()`, `extension()`. Thanks to faithandbrave for pull request [github_pr 31].
|
||||
* Fix broken link to [trac_issue 7506] in 1.60.0 Release History (Daniel Krügler).
|
||||
* Refactor `push_directory()`internal logic so it is easier to reason about.
|
||||
|
||||
[heading 1.60.0]
|
||||
|
||||
* [*New:] Added functions [link filesystem.reference.lex-normal `lexically_normal`], [link filesystem.reference.lex-relative `lexically_relative`],
|
||||
[link filesystem.reference.relative `relative`], and [link filesystem.reference.weakly_canonical `weakly_canonical`]. Many thanks to Jamie Allsop
|
||||
for his help and perseverance. Resolves tickets [trac_issue 1976], [trac_issue 6249].
|
||||
* [*New:] Class `path` now has `path::reverse_iterator`, `path::const_reverse_iterator`, [member path::rbegin], and [member path::rend].
|
||||
* [*New:] C++11 `noexcept` supplied as specified in the Filesystem TS if supported by the compiler.
|
||||
* [*New:] C++11 move constructors and move assignments supplied as specified in the Filesystem TS if supported by the compiler. Resolves [trac_issue 10291].
|
||||
* [*New:] Existing functions whose names changed in the Filesystem TS are now supported under both the old and new names.
|
||||
* [*New:] Added [member path::size] function to class `path`. Resolves [trac_issue 6874].
|
||||
* Clear several spurious GCC warnings.
|
||||
* Fix [trac_issue 11733] by applying a patch from Idar Tollefsen.
|
||||
* Fix a race condition in `unique_path` by applying [github_pr 15] from Sebastian Redl. Also fixes [trac_issue 7506],
|
||||
['`unique_path` Fails on Windows for Temporary User Profiles].
|
||||
* Fix bug in `file_status` and `recursive_directory_iterator`: C++ turns an explicit constructor with all arguments except first defaulted into
|
||||
non-explicit single argument constructor.
|
||||
* Fix [trac_issue 10591], by applying a patch submitted by Daniel Seither.
|
||||
* Fix [trac_issue 9454] not compiling when `BOOST_FILESYSTEM_NO_DEPRECATED` is defined, by applying a patch submitted by Makesim.
|
||||
* Fix [trac_issue 11447], by applying a patch submitted by Jasper Lievisse Adriaanse.
|
||||
* Fix [trac_issue 11288], by applying a patch submitted by Yevhen Ivannikov.
|
||||
* Fix [trac_issue 11175], out-of-date documentation causing users to incorrectly expect that the library could be used with exceptions disabled.
|
||||
* Resolve [trac_issue 11175] by mitigating (i.e. reducing the likelihood of) a possible external file system race in `remove()`.
|
||||
* Fix [trac_issue 7258]. Also fix related issues if path contains ['dot] or ['dot-dot] elements, and added test cases to the test suite.
|
||||
* Reference docs editorial cleanups: Use same style sheet as the rest of the documentation. Tweak tab font size. Fix excessively long lines in
|
||||
tables, synopsis.
|
||||
* Resolve [trac_issue 10766], by adding examples and notes to the reference documentation to show why the returned value is in fact correct,
|
||||
and to provide rationale for that behavior. See [link filesystem.reference.path.iterators \[path.itr\]], and
|
||||
[link filesystem.reference.path-decomposition \[path.decompose\]] `parent_path()` and `filename()` sections of the reference docs.
|
||||
* Minor other fixes, including pull requests from Jonathan Wakely and Marcel Raad.
|
||||
* Closed several tickets as duplicates or otherwise resolved by the above changes:
|
||||
* [trac_issue 7607] ['path should not infer an invisible [^"."] at the end of a path that ends with a slash]
|
||||
* [trac_issue 7258]
|
||||
* [trac_issue 11061]
|
||||
* [trac_issue 11062] ['impossible to traverse the path of the reverse iterator]; this is effectively resolved by the addition of the class `path`
|
||||
reverse iteration feature. The reference documentation has also been updated with [link filesystem.reference.path.iterators a note] warning
|
||||
about the limitations of class `path` iterators.
|
||||
|
||||
[heading 1.59.0]
|
||||
|
||||
* Update the Tutorial:
|
||||
* Use C++11 in the example programs to improve clarity.
|
||||
* Update the example source code show to match the actual example source code in the cpp files.
|
||||
* Rerun all the examples and update the output shown in the tutorial accordingly.
|
||||
* Fix spacing and other HTML presentation issues.
|
||||
* Fix [trac_issue 11491].
|
||||
|
||||
[heading 1.58.0]
|
||||
|
||||
* Fix [trac_issue 6124], and [trac_issue 10038]. Cannot pass a `BOOST_SCOPED_ENUM` to a compiled function because it will result in an
|
||||
undefined reference if the library is compiled with -std=c++0x but the use is compiled in C++03 mode, or visa versa.
|
||||
* Rewrite Windows implementation of `temp_directory_path()` to (1) avoid `GetTempPath()` failure if path length > 130 (ticket [trac_issue 5300])
|
||||
and (2) provide a more sensible sequence of directories than provided by `GetTempPath()`, per boost list discussion "\[filesystem\]
|
||||
temp_directory_path() behavior on Windows". The new sequence is:
|
||||
# [^['%TMP%]]
|
||||
# [^['%TEMP%]]
|
||||
# [^['%LOCALAPPDATA%]\/Temp]
|
||||
# [^['%USERPROFILE%]\/Temp]
|
||||
# [^['`GetWindowsDirectoryW()`]\/Temp]
|
||||
|
||||
[heading 1.57.0]
|
||||
|
||||
* Rework class `path` locale and codecvt implementation for increased reliability. This change was SVN revision 83021, which should have gone into 1.56.0
|
||||
but unfortunately the merge didn't happen until too late.
|
||||
* Fix tickets [trac_issue 8930], [trac_issue 9214], and [trac_issue 10641], all related to locales and `codecvt` facets.
|
||||
* The net effect of the above changes and fixes should be to eliminate spurious "locale::facet::_S_create_c_locale name not valid" errors on Linux
|
||||
and other non-BSD POSIX-like systems. The error will continue to occur, as it should, when a path encoding conversion `char`-to-`wchar_t` or
|
||||
`wchar_t`-to-`char` is attempted in an environment without a valid C locale (for example, if the `LANG` environment variable is invalid or not defined).
|
||||
* Fix [trac_issue 6124], and [trac_issue 10038] - an undefined reference that occurred when the library was compiled for C++03 but
|
||||
the using program was compiled for C++11, or vice versa. The private library interface has been changed to use a plain-old C++03 enum. This is the fix
|
||||
suggested by Andy in [trac_issue 6779].
|
||||
* The Windows implementation now treats NTFS directory junctions (also known as junctions, also known as mount points) as symlinks. This has the effect of
|
||||
treating directory junctions as directories, and thus supporting all operations suitable for directories. This resolves [trac_issue 9016].
|
||||
Directory junctions are very similar to symlinks, but may have performance or other advantages in some situations. They can be created
|
||||
from the command line with "[^mklink \/j link target]". There is no plan for Boost.Filesystem to be able to create them directly other than by calling
|
||||
`std::system()`.
|
||||
|
||||
[heading 1.56.0]
|
||||
|
||||
* Reorganize `recursive_directory_iterator::increment`, adding an invariant that progress is always made, even if an error is reported by
|
||||
exception or error_code. Add a manually executed test, `test/issues/recurse_dir_iter_5403.cpp`. Adjust regular regression tests as needed.
|
||||
Thanks to Claudio Bley for the [github_pr 4] - the change was incorporated into the reorganized code. Fixes [trac_issue 5403].
|
||||
* Fix `canonical()` to treat parent of root as root. (Christian Hammerl) Fixes [trac_issue 9683] and [trac_issue 10187].
|
||||
* Added missing test for `__sun` macro which is defined on Solaris 10. (Chris Stylianou)
|
||||
* Minor fixes and code cleanup.
|
||||
* Update IDE projects to Visual Studio 2013.
|
||||
* Remove unused `const char colon` to clear clang warning. (J?gen Hunold)
|
||||
* Add BOOST_NOEXCEPT to `class filesystem_error`.
|
||||
* Change `perms::all_all` and `perms::perms_mask` to absolute values to quiet intellisense warnings, and conform to C++11.
|
||||
|
||||
[heading 1.54.0]
|
||||
|
||||
* Reimplement `path::codecvt()` and `path::imbue()` with portable code that is intended to be much more robust and maintainable. A
|
||||
section on [link filesystem.reference.path.usage path usage concerns] has been added to the reference documentation describing several
|
||||
concerns that arise in the context of multithreading and `path::codecvt()`.
|
||||
|
||||
[heading 1.52.0]
|
||||
|
||||
* Fix [trac_issue 7239]. The reported problem was a symptom of an internal bug that caused `path::filename()` and `path::parent_path()`
|
||||
to fail on Windows for `path(":")`, and that in turn caused other functions that depend on `filename()` or `parent_path()` to fail,
|
||||
such as `create_directories()`.
|
||||
|
||||
[heading 1.51.0]
|
||||
|
||||
* Add `begin()` and `end()` non-member functions for `directory_iterator` and `recursive_directory_iterator` so that C++11 range-based `for`
|
||||
statements work. Suggested by feature requests [trac_issue 5896], using the [trac_issue 5896] approach.
|
||||
* Add `range_begin()` and `range_end()` non-member functions for `directory_iterator` and `recursive_directory_iterator` so that
|
||||
[@https://www.boost.org/libs/foreach/ `BOOST_FOREACH`] works.
|
||||
* Fix a Linux `fchmodat` problem affecting symlink permissions reported during discussion of [trac_issue 6659].
|
||||
* Fix [trac_issue 6659], ['fchmodat supported only on Solaris 11]. Fix for both Sun and GCC compilers.
|
||||
|
||||
[heading 1.50.0]
|
||||
|
||||
* Remove Filesystem Version 2 from the distribution. Version 3 is now the only distributed version. Those still using V2 are urged
|
||||
to migrate to V3 as soon as possible.
|
||||
* Add `constexpr value_type preferred_separator` to class path.
|
||||
* Fix [trac_issue 5118]. The documentation, implementation, and test cases have all had fixes applied. The documentation had failed
|
||||
to mention that any existing extension is removed. The behavior for simple cases has been reverted to the Version 2 behavior, but
|
||||
with corrections so that complex replacements now work. Two test cases from [trac_issue 5118] have been added.
|
||||
* Fix [trac_issue 3737]. On Windows, `<sys/stat.h>` is no longer included.
|
||||
* Fix [trac_issue 4065]. This required multiple source code bug fixes and code cleanup, correcting problems not related to lexicographical issues.
|
||||
* Add class path member function `compare` for consistency with `std::string`.
|
||||
* Tighten `BOOST_FILESYSTEM_DYN_LINK` and `BOOST_FILESYSTEM_STATIC_LINK` logic in `filesystem/config.hpp` so that one or
|
||||
the other is always defined, and both being defined is an `#error`.
|
||||
* Fix [trac_issue 6690], resolving static linking related problems with VC++ 8 through 11. Note that this fix may reintroduce `codecvt`
|
||||
thread safety problems [trac_issue 4889], for these compilers if static linking is used.
|
||||
* Add `path::operator+=` and concat functions to tack on things like suffixes or numbers. Suggested by Ed Smith-Rowland and others.
|
||||
* Fix [trac_issue 6809], by adding `MOVEFILE_COPY_ALLOWED` to deal with renames across drives, volumes, file systems. Fix has no effect
|
||||
on non-Windows systems.
|
||||
* Fix [trac_issue 6819], A path operand with a source that was a one character array was treated as empty, even if it wasn't empty.
|
||||
Such arrays can occur in unions or in code using C variable length array idioms.
|
||||
* Fix [trac_issue 6932].
|
||||
|
||||
[heading 1.49.0]
|
||||
|
||||
* Fix [trac_issue 3714], added test cases and fixes for class path errors when assignment or append used self or portion of self as source.
|
||||
* Fix [trac_issue 4889], ['Locale codecvt_facet not thread safe on Windows]. Move Windows, Mac OS X, `locale` and `codecvt` facet back to
|
||||
namespace scope. POSIX except OS X uses local static initialization (i.e. lazy) to ensure exceptions are catchable if environmental variables
|
||||
are misconfigured and to avoid use of `locale("")` if not actually used.
|
||||
* Fix [trac_issue 5652]. Thanks to Daniel Aarno for the patch.
|
||||
* Fix [trac_issue 5653].
|
||||
* Fix [trac_issue 5900]. Thanks to Andreas Eckleder for the patch.
|
||||
* Fix [@https://svn.boost.org/trac/boost/ticket/5900#comment:2 #5900 comment 2], a bug in `director_iterator` construction with `error_code`
|
||||
argument that caused increment to be called without the `ec` argument being passed.
|
||||
* Fix [trac_issue 5900] by cleaning up test suite `path_test.cpp` code even though the ticket itself was not a defect, and clarifying docs;
|
||||
iteration over a path yields generic format.
|
||||
* Fix [trac_issue 5592].
|
||||
* Operations function fixes for PGI compiler, thanks to Noel Belcourt.
|
||||
* Relax permissions test to reflect reality, particularly on the Sandia test platforms.
|
||||
|
||||
[heading 1.48.0]
|
||||
|
||||
* Added operational function [link filesystem.reference.canonical `canonical()`], suggested by David Svoboda, who also provided pseudo-code.
|
||||
* Added [link filesystem.reference.hash_value `hash_value()`] function for paths. (Daniel James)
|
||||
* Fix path inserter problem ([trac_issue 5764]) reported for QNX6.3.2 host (gcc-3.3.5)
|
||||
* Fix problem of `locale("")` exception being thrown before `main()` starts on poorly configured (e.g. `LANG="bad name"`) POSIX systems.
|
||||
Resolves the most serious aspect of tickets [trac_issue 4688], [trac_issue 5289].
|
||||
|
||||
[heading 1.47.0]
|
||||
|
||||
* Program `file_status.cpp` added (V3). See [^['[*boost-root]]\/libs\/filesystem\/v3\/example]. Useful both as an example and to explore how
|
||||
Boost.Filesystem treats various status errors. Run "[^bjam]" (NOT "[^bjam install]") in the example directory to install in [^example\/bin].
|
||||
|
||||
[heading 1.46.1]
|
||||
|
||||
* Fix fstream problem for STLPort masquerading as Dinkumware ([trac_issue 5217]).
|
||||
|
||||
[heading 1.46.0]
|
||||
|
||||
* Version 3 of the library is now the default.
|
||||
* IBM vacpp: Workaround for compiler bug affecting `iterator_facade`. ([trac_issue 4912])
|
||||
* Verify, clarify, document that `<boost/config/user.hpp>` can be used to specify `BOOST_FILESYSTEM_VERSION`. ([trac_issue 4891])
|
||||
* Replaced C-style `assert` with `BOOST_ASSERT`.
|
||||
* Undeprecated `unique_path()`. Instead, add a note mentioning the workaround for lack of thread safety and possible change to cwd.
|
||||
`unique_path()` is just too convenient to deprecate!
|
||||
* Cleared several GCC warnings.
|
||||
* Changed V2 code to use `BOOST_THROW_EXCEPTION`.
|
||||
* Windows: Fix `status()` to report non-symlink reparse point correctly.
|
||||
* Add `symlink_option` to `recursive_directory_iterator`, allowing control over recursion into directory symlinks. Note that the default
|
||||
is changed to not recurse into directory symlinks.
|
||||
* [link filesystem.reference Reference] documentation cleanup, including fixing missing and broken links, and adding missing functions.
|
||||
* Miscellaneous implementation code cleanup.
|
||||
|
||||
[heading:v3 Version 3]
|
||||
|
||||
Boost 1.44.0 - June, 2010 - Internationalization via single class `path`. More uniform error handling.
|
||||
|
||||
[heading:v2 Version 2]
|
||||
|
||||
Boost 1.34.0 - May, 2007 - Internationalization via `basic_path` template.
|
||||
|
||||
[heading:v1 Version 1]
|
||||
|
||||
Boost 1.30.0 - March, 2003 - Initial official Boost release.
|
||||
|
||||
[endsect]
|
||||
225
doc/deprecated.qbk
Normal file
225
doc/deprecated.qbk
Normal file
@@ -0,0 +1,225 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:deprecated Deprecated Features]
|
||||
|
||||
As the library evolves over time, names sometimes change or old features are removed to make way for new features. To ease transition,
|
||||
Boost.Filesystem deprecates the old names and features, but by default continues to provide many of them. The deprecated names and other
|
||||
workarounds can be suppressed by defining macro `BOOST_FILESYSTEM_NO_DEPRECATED`, and this is recommended for all new code.
|
||||
|
||||
In the table below, \u2714 indicates a synonym or other workaround is provided unless `BOOST_FILESYSTEM_NO_DEPRECATED` is defined.
|
||||
|
||||
Additionally, when not disabled, most of the deprecated components will generate compilation warnings when used. These warnings are
|
||||
intended to highlight the library usage that needs to be updated. For convenience during the transition period, these warnings can be
|
||||
suppressed by defining `BOOST_FILESYSTEM_ALLOW_DEPRECATED` macro.
|
||||
|
||||
[table:deprecated-names Deprecated names and features
|
||||
[[Component or location] [Old name, now deprecated] [\u2714] [New name]]
|
||||
[[`class path`]
|
||||
[
|
||||
Construction, assignment and appending from container types.
|
||||
]
|
||||
[]
|
||||
[
|
||||
Use string types or iterators as the source for path construction, assignment and appending.
|
||||
]]
|
||||
[[`path.hpp`]
|
||||
[
|
||||
```
|
||||
template<class String, class Traits>
|
||||
class basic_path;
|
||||
```
|
||||
]
|
||||
[]
|
||||
[
|
||||
Class template `basic_path` is replaced by class `path`. No workaround for an explicitly coded `basic_path` is provided, but see the next
|
||||
row - `path`.
|
||||
]]
|
||||
[[`path.hpp`]
|
||||
[
|
||||
`typedef basic_path<std::string, path_traits> path`
|
||||
]
|
||||
[\u2714]
|
||||
[
|
||||
`class path`
|
||||
]]
|
||||
[[`operations.hpp`]
|
||||
[
|
||||
`initial_path()`
|
||||
]
|
||||
[\u2714]
|
||||
[
|
||||
Function removed. Cache `current_path()` early in the application startup.
|
||||
]]
|
||||
[[Build system]
|
||||
[
|
||||
Auto-linking on Windows
|
||||
]
|
||||
[]
|
||||
[
|
||||
No longer supported. When users are linking against static library of Boost.Filesystem, they are recommended to explicitly add Boost.Filesystem
|
||||
dependencies to their linker command line. Shared library of Boost.Filesystem is not affected by this as it is already linked with all its
|
||||
dependencies.
|
||||
]]
|
||||
]
|
||||
|
||||
Some library features were removed in one of the past releases. The table below lists some of those features along with suggested replacements.
|
||||
|
||||
[table Removed names and features
|
||||
[[Component or location] [Removed name] [Possible replacement]]
|
||||
[[`class path`]
|
||||
[`branch_path()`]
|
||||
[`parent_path()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`directory_string()`]
|
||||
[`string`]
|
||||
][
|
||||
[`class path`]
|
||||
[`external_directory_string()`]
|
||||
[`native()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`external_file_string()`]
|
||||
[`native()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`file_string()`]
|
||||
[`string()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`has_branch_path()`]
|
||||
[`has_parent_path()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`has_leaf()`]
|
||||
[`has_filename()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`is_complete()`]
|
||||
[`is_absolute()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`leaf()`]
|
||||
[`filename()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`native_directory_string()`]
|
||||
[`string()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`native_file_string()`]
|
||||
[`string()`]
|
||||
][
|
||||
[`class path`]
|
||||
[`normalize()`]
|
||||
[Replace `p.normalize()` with `p = p.lexically_normal()`.]
|
||||
][
|
||||
[`class path`]
|
||||
[`remove_leaf()`]
|
||||
[`remove_filename()`]
|
||||
][
|
||||
[`path.hpp`]
|
||||
[`typedef basic_path<std::wstring, wpath_traits> wpath`]
|
||||
[`class path`]
|
||||
][
|
||||
[`convenience.hpp`]
|
||||
[`std::string extension(const path& p)`]
|
||||
[Replace `extension(p)` with `p.extension().string()`.]
|
||||
][
|
||||
[`convenience.hpp`]
|
||||
[`std::string basename(const path& p)`]
|
||||
[Replace `basename(p)` with `p.stem().string()`.]
|
||||
][
|
||||
[`convenience.hpp`]
|
||||
[`path change_extension(const path& p, const path& new_extension)`]
|
||||
[Replace `path new_p = change_extension(p, ext);` with `path new_p = p; new_p.replace_extension(ext);`.]
|
||||
][
|
||||
[`operations.hpp`]
|
||||
[
|
||||
```
|
||||
template <class Path>
|
||||
Path complete(const Path& p, const Path& base=initial_path<Path>())
|
||||
```
|
||||
]
|
||||
[`path absolute(const path& p, const path& base=current_path())`]
|
||||
][
|
||||
[`operations.hpp`]
|
||||
[`is_regular(file_status f)`]
|
||||
[`is_regular_file(file_status f)`]
|
||||
][
|
||||
[`operations.hpp`]
|
||||
[`symbolic_link_exists(const path& ph)`]
|
||||
[Replace `symbolic_link_exists(p)` with `is_symlink(symlink_status(p))`.]
|
||||
][
|
||||
[`operations.hpp`]
|
||||
[`copy_directory(const path& from, const path& to)`]
|
||||
[`create_directory(const path& to, const path& from)`. Note the reversed order of arguments.]
|
||||
][
|
||||
[`class directory_entry`]
|
||||
[`filename()`]
|
||||
[Replace `de.filename()` with `de.path().filename()`.]
|
||||
][
|
||||
[`class directory_entry`]
|
||||
[`leaf()`]
|
||||
[Replace `de.leaf()` with `de.path().filename()`.]
|
||||
][
|
||||
[`class directory_entry`]
|
||||
[`string()`]
|
||||
[Replace `de.string()` with `de.path().string()`.]
|
||||
][
|
||||
[`class recursive_directory_iterator`]
|
||||
[`level()`]
|
||||
[`depth()`]
|
||||
][
|
||||
[`class recursive_directory_iterator`]
|
||||
[`no_push_pending()`]
|
||||
[`!recursion_pending()`]
|
||||
][
|
||||
[`class recursive_directory_iterator`]
|
||||
[`no_push()`]
|
||||
[`disable_recursion_pending()`]
|
||||
][
|
||||
[`directory.hpp`]
|
||||
[`enum class symlink_option`]
|
||||
[Use corresponding values of `enum class directory_options` instead.]
|
||||
][
|
||||
[`directory.hpp`]
|
||||
[`wrecursive_directory_iterator` typedef]
|
||||
[`class recursive_directory_iterator`.]
|
||||
][
|
||||
[`operations.hpp`]
|
||||
[
|
||||
The header provides `filesystem_error`, `file_status`, `directory_entry`, `directory_iterator`, `recursive_directory_iterator` and associated
|
||||
enums and functions.
|
||||
]
|
||||
[Explicitly include headers `exception.hpp`, `file_status.hpp` and/or `directory.hpp` to introduce the required components.]
|
||||
][
|
||||
[`path_traits.hpp`]
|
||||
[The header contained implementation details of class `path`.]
|
||||
[Remove the include.]
|
||||
][
|
||||
[`convenience.hpp`]
|
||||
[The header contained helper functions that were deprecated and then removed.]
|
||||
[Remove the include.]
|
||||
]
|
||||
]
|
||||
|
||||
[section:rationale Deprecation rationale]
|
||||
|
||||
[section:initial_path `initial_path` function]
|
||||
|
||||
Full implementation of `initial_path()` would require support from the C++ runtime startup code, and that doesn't seem likely to happen.
|
||||
Depending on the user to call `initial_path()` at the beginning of `main()` is too error prone. An equivalent function can trivially be provided
|
||||
by a user.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
243
doc/design.qbk
Normal file
243
doc/design.qbk
Normal file
@@ -0,0 +1,243 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:design Boost Filesystem Library Design]
|
||||
|
||||
[section:introduction Introduction]
|
||||
|
||||
The primary motivation for beginning work on the Filesystem Library was frustration with Boost administrative tools. Scripts were written in
|
||||
Python, Perl, Bash, and Windows command languages. There was no single scripting language familiar and acceptable to all Boost administrators.
|
||||
Yet they were all skilled C++ programmers - why couldn't C++ be used as the scripting language?
|
||||
|
||||
The key feature C++ lacked for script-like applications was the ability to perform portable filesystem operations on directories and their contents.
|
||||
The Filesystem Library was developed to fill that void.
|
||||
|
||||
The intent is not to compete with traditional scripting languages, but to provide a solution for situations where C++ is already the language
|
||||
of choice.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:requirements Requirements]
|
||||
|
||||
* Be able to write portable script-style filesystem operations in modern C++.
|
||||
|
||||
Rationale: This is a common programming need. It is both an embarrassment and a hardship that this is not possible with either the current
|
||||
C++ or Boost libraries. The need is particularly acute when C++ is the only toolset allowed in the tool chain. File system operations are
|
||||
provided by many languages used on multiple platforms, such as Perl and Python, as well as by many platform specific scripting languages.
|
||||
All operating systems provide some form of API for filesystem operations, and the POSIX bindings are increasingly available even on
|
||||
operating systems not normally associated with POSIX, such as the Mac, z\/OS, or OS\/390.
|
||||
|
||||
* Work within the [link filesystem.design.realities realities] described below.
|
||||
|
||||
Rationale: This isn't a research project. The need is for something that works on today's platforms, including some of the embedded operating
|
||||
systems with limited file systems. Because of the emphasis on portability, such a library would be much more useful if standardized. That means
|
||||
being able to work with a much wider range of platforms that just Unix or Windows and their clones.
|
||||
|
||||
* Avoid dangerous programming practices. Particularly, all-too-easy-to-ignore error notifications and use of global variables. If a dangerous
|
||||
feature is provided, identify it as such.
|
||||
|
||||
Rationale: Normally this would be covered by "the usual Boost requirements...", but it is mentioned explicitly because the equivalent native
|
||||
platform and scripting language interfaces often depend on all-too-easy-to-ignore error notifications and global variables like "current
|
||||
working directory".
|
||||
|
||||
* Structure the library so that it is still useful even if some functionality does not map well onto a given platform or directory tree.
|
||||
Particularly, much useful functionality should be portable even to flat (non-hierarchical) filesystems.
|
||||
|
||||
Rationale: Much functionality which does not require a hierarchical directory structure is still useful on flat-structure filesystems. There
|
||||
are many systems, particularly embedded systems, where even very limited functionality is still useful.
|
||||
|
||||
* Interface smoothly with current C++ Standard Library input\/output facilities. For example, paths should be easy to use in `std::basic_fstream`
|
||||
constructors.
|
||||
|
||||
Rationale: One of the most common uses of file system functionality is to manipulate paths for eventual use in input\/output operations.
|
||||
Thus the need to interface smoothly with standard library I\/O.
|
||||
|
||||
* Suitable for eventual standardization. The implication of this requirement is that the interface be close to minimal, and that great care be
|
||||
taken regarding portability.
|
||||
|
||||
Rationale: The lack of file system operations is a serious hole in the current standard, with no other known candidates to fill that hole.
|
||||
Libraries with elaborate interfaces and difficult to port specifications are much less likely to be accepted for standardization.
|
||||
|
||||
* The usual Boost [@https://www.boost.org/more/lib_guide.htm requirements and guidelines] apply.
|
||||
|
||||
* Encourage, but do not require, portability in path names.
|
||||
|
||||
Rationale: For paths which originate from user input it is unreasonable to require portable path syntax.
|
||||
|
||||
* Avoid giving the illusion of portability where portability in fact does not exist.
|
||||
|
||||
Rationale: Leaving important behavior unspecified or "implementation defined" does a great disservice to programmers using a library because
|
||||
it makes it appear that code relying on the behavior is portable, when in fact there is nothing portable about it. The only case where such
|
||||
under-specification is acceptable is when both users and implementors know from other sources exactly what behavior is required, yet for some
|
||||
reason it isn't possible to specify it exactly.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:realities Realities]
|
||||
|
||||
* Some operating systems have a single directory tree root, others have multiple roots.
|
||||
* Some file systems provide both a long and short form of filenames.
|
||||
* Some file systems have different syntax for file paths and directory paths.
|
||||
* Some file systems have different rules for valid file names and valid directory names.
|
||||
* Some file systems (ISO-9660, level 1, for example) use very restricted (so-called 8.3) file names.
|
||||
* Some operating systems allow file systems with different characteristics to be "mounted" within a directory tree. Thus an ISO-9660 or Windows
|
||||
file system may end up as a sub-tree of a POSIX directory tree.
|
||||
* Wide-character versions of directory and file operations are available on some operating systems, and not available on others.
|
||||
* There is no law that says directory hierarchies have to be specified in terms of left-to-right decent from the root.
|
||||
* Some file systems have a concept of file "version number" or "generation number". Some don't.
|
||||
* Not all operating systems use single character separators in path names. Some use paired notations. A typical fully-specified OpenVMS filename
|
||||
might look something like this:
|
||||
|
||||
[pre DISK$SCRATCH:\[GEORGE.PROJECT1.DAT\]BIG_DATA_FILE.NTP;5]
|
||||
|
||||
The general OpenVMS format is:
|
||||
|
||||
[pre Device:\[directories.dot.separated\]filename.extension;version_number]
|
||||
|
||||
* For common file systems, determining if two descriptors are for same entity is extremely difficult or impossible. For example, the concept of
|
||||
equality can be different for each portion of a path - some portions may be case or locale sensitive, others not. Case sensitivity is a property
|
||||
of the pathname itself, and not the platform. Determining collating sequence is even worse.
|
||||
* Race-conditions may occur. Directory trees, directories, files, and file attributes are in effect shared between all threads, processes, and
|
||||
computers which have access to the filesystem. That may well include computers on the other side of the world or in orbit around the world. This
|
||||
implies that file system operations may fail in unexpected ways. For example:
|
||||
|
||||
```
|
||||
assert(exists("foo") == exists("foo")); // may fail!
|
||||
|
||||
assert(is_directory("foo") == is_directory("foo")); // may fail!
|
||||
```
|
||||
|
||||
In the first example, the file may have been deleted between calls to `exists()`. In the second example, the file may have been deleted and then
|
||||
replaced by a directory of the same name between the calls to `is_directory()`.
|
||||
|
||||
* Even though an application may be portable, it still will have to traffic in system specific paths occasionally; user provided input is a common
|
||||
example.
|
||||
* Symbolic links cause canonical and normal form of some paths to represent different files or directories. For example, given the directory
|
||||
hierarchy [^"\/a\/b\/c"], with a symbolic link in [^"\/a"] named [^"x"] pointing to [^"b\/c"], then under POSIX Pathname Resolution rules a path
|
||||
of [^"\/a\/x\/.."] should resolve to [^"\/a\/b"]. If [^"\/a\/x\/.."] were first normalized to [^"\/a"], it would resolve incorrectly. (Case
|
||||
supplied by Walter Landry.)
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:rationale Rationale]
|
||||
|
||||
The [link filesystem.design.requirements Requirements] and [link filesystem.design.realities Realities] above drove much of the C++ interface design.
|
||||
In particular, the desire to make script-like code straightforward caused a great deal of effort to go into ensuring that apparently simple
|
||||
expressions like `exists("foo")` work as expected.
|
||||
|
||||
See the [link filesystem.faq FAQ] for the rationale behind many detailed design decisions.
|
||||
|
||||
Several key insights went into the `path` class design:
|
||||
|
||||
* Decoupling of the input formats, internal conceptual (`vector<string>` or other sequence) model, and output formats.
|
||||
* Providing two input formats (generic and O\/S specific) broke a major design deadlock.
|
||||
* Providing several output formats solved another set of previously intractable problems.
|
||||
* Several non-obvious functions (particularly decomposition and composition) are required to support portable code. (Peter Dimov, Thomas Witt, Glen
|
||||
Knowles, others.)
|
||||
|
||||
Error checking was a particularly difficult area. One key insight was that with file and directory names, portability isn't a universal truth.
|
||||
Rather, the programmer must think out the question "What operating systems do I want this path to be portable to?" By providing support for several
|
||||
answers to that question, the Filesystem Library alerts programmers of the need to ask it in the first place.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:abandoned_designs Abandoned Designs]
|
||||
|
||||
[section operations.hpp]
|
||||
|
||||
Dietmar Kühl's original `directory_iterator` design and implementation supported wide-character file and directory names. It was abandoned after
|
||||
extensive discussions among Library Working Group members failed to identify portable semantics for wide-character names on systems not providing
|
||||
native support.
|
||||
|
||||
Previous iterations of the interface design used explicitly named functions providing a large number of convenience operations, with no compile-time
|
||||
or run-time options. There were so many function names that they were very confusing to use, and the interface was much larger. Any benefits seemed
|
||||
theoretical rather than real.
|
||||
|
||||
Designs based on compile time (rather than runtime) flag and option selection (via policy, `enum`, or `int` template parameters) became so
|
||||
complicated that they were abandoned, often after investing quite a bit of time and effort. The need to qualify attribute or option names with
|
||||
namespaces, even aliases, made use in template parameters ugly; that wasn't fully appreciated until actually writing real code.
|
||||
|
||||
Yet another set of convenience functions (for example, `remove` with `permissive`, `prune`, `recurse`, and other options, plus predicate, and
|
||||
possibly other, filtering features) were abandoned because the details became both complex and contentious.
|
||||
|
||||
What is left is a toolkit of low-level operations from which the user can create more complex convenience operations, plus a very small number of
|
||||
convenience functions which were found to be useful enough to justify inclusion.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section path.hpp]
|
||||
|
||||
There were so many abandoned path designs, I've lost track. Policy-based class templates in several flavors, constructor supplied runtime policies,
|
||||
operation specific runtime policies, they were all considered, often implemented, and ultimately abandoned as far too complicated for any small
|
||||
benefits observed.
|
||||
|
||||
Additional design considerations apply to [link filesystem.v3.design Internationalization].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Error checking]
|
||||
|
||||
A number of designs for the error checking machinery were abandoned, some after experiments with implementations. Totally automatic error checking
|
||||
was attempted in particular. But automatic error checking tended to make the overall library design much more complicated.
|
||||
|
||||
Some designs associated error checking mechanisms with paths. Some with operations functions. A policy-based error checking template design was
|
||||
partially implemented, then abandoned as too complicated for everyday script-like programs.
|
||||
|
||||
The final design, which depends partially on explicit error checking function calls, is much simpler and straightforward, although it does depend
|
||||
to some extent on programmer discipline. But it should allow programmers who are concerned about portability to be reasonably sure that their
|
||||
programs will work correctly on their choice of target systems.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:references References]
|
||||
|
||||
[variablelist
|
||||
[
|
||||
[\[[#filesystem.design.references.ibm-01]IBM-01\]]
|
||||
[IBM Corporation, ['z\/OS V1R3.0 C\/C++ Run-Time Library Reference], SA22-7821-02, 2001, [@http://www-1.ibm.com/servers/eserver/zseries/zos/bkserv/
|
||||
www-1.ibm.com/servers/eserver/zseries/zos/bkserv/]]
|
||||
]
|
||||
[
|
||||
[\[[#filesystem.design.references.iso-9660]ISO-9660\]]
|
||||
[International Standards Organization, 1988]
|
||||
]
|
||||
[
|
||||
[\[[#filesystem.design.references.kuhn]Kuhn\]]
|
||||
[UTF-8 and Unicode FAQ for Unix\/Linux, [@https://www.cl.cam.ac.uk/~mgk25/unicode.html www.cl.cam.ac.uk/~mgk25/unicode.html]]
|
||||
]
|
||||
[
|
||||
[\[[#filesystem.design.references.msdn]MSDN\] ]
|
||||
[Microsoft Platform SDK for Windows, Storage Start Page, [@http://msdn.microsoft.com/library/en-us/fileio/base/storage_start_page.asp
|
||||
msdn.microsoft.com/library/en-us/fileio/base/storage_start_page.asp]]
|
||||
]
|
||||
[
|
||||
[\[[#filesystem.design.references.posix-01]POSIX-01\]]
|
||||
[IEEE Std 1003.1-2001, ISO\/IEC 9945:2002, and The Open Group Base Specifications, Issue 6. Also known as The Single UNIX® Specification, Version 3.
|
||||
Available from each of the organizations involved in its creation. For example, read online or download from
|
||||
[@http://www.unix.org/single_unix_specification/ www.unix.org/single_unix_specification/]. The ISO JTC1/SC22/WG15 - POSIX homepage is
|
||||
[@https://www.open-std.org/jtc1/sc22/WG15/ www.open-std.org/jtc1/sc22/WG15/]]
|
||||
]
|
||||
[
|
||||
[\[[#filesystem.design.references.uri]URI\]]
|
||||
[RFC-2396, Uniform Resource Identifiers (URI): Generic Syntax, [@https://www.ietf.org/rfc/rfc2396.txt www.ietf.org/rfc/rfc2396.txt]]
|
||||
]
|
||||
[
|
||||
[\[[#filesystem.design.references.utf-16]UTF-16\]]
|
||||
[Wikipedia, UTF-16, [@https://en.wikipedia.org/wiki/UTF-16 en.wikipedia.org/wiki/UTF-16]]
|
||||
]
|
||||
[
|
||||
[\[[#filesystem.design.references.wulf-shaw-73]Wulf-Shaw-73\]]
|
||||
[William Wulf, Mary Shaw, ['Global Variable Considered Harmful], ACM SIGPLAN Notices, 8, 2, 1973, pp. 23-34]
|
||||
]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
116
doc/faq.qbk
Normal file
116
doc/faq.qbk
Normal file
@@ -0,0 +1,116 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:faq Frequently Asked Questions]
|
||||
|
||||
[section:general General questions]
|
||||
|
||||
[heading Why not support a concept of specific kinds of file systems, such as posix_file_system or windows_file_system?]
|
||||
|
||||
Portability is one of the most important requirements for the library. Features specific to a particular operating system
|
||||
or file system can always be accessed by using the operating system's API.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:path Class `path` questions]
|
||||
|
||||
[heading Why base the generic pathname format on POSIX?]
|
||||
|
||||
[link filesystem.design.references.posix-01 POSIX] is an ISO Standard. It is the basis for the most familiar pathname formats,
|
||||
not just for POSIX-based operating systems but also for Windows and the URL portion of URIs. It is ubiquitous and familiar.
|
||||
On many systems, it is very easy to implement because it is either the native operating system format (Unix and Windows) or
|
||||
via an operating system supplied POSIX library (z/OS, OS/390, and many more.)
|
||||
|
||||
[heading Why not use a full URI (Universal Resource Identifier) based path?]
|
||||
|
||||
[link filesystem.design.references.uri URIs] would promise more than the Filesystem Library can actually deliver, since URIs
|
||||
extend far beyond what most operating systems consider a file or a directory. Thus for the primary "portable script-style file
|
||||
system operations" requirement of the Filesystem Library, full URIs appear to be over-specification.
|
||||
|
||||
[heading Why isn't `path` a base class with derived `directory_path` and `file_path` classes?]
|
||||
|
||||
Why bother? The behavior of all three classes is essentially identical. Several early versions did require users to identify
|
||||
each path as a file or directory path, and this seemed to increase coding errors and decrease code readability. There was no
|
||||
apparent upside benefit.
|
||||
|
||||
[heading Why do path decomposition functions yielding a single element return a path rather than a string?]
|
||||
|
||||
Interface simplicity. If they returned strings, flavors would be needed for different string and character types.
|
||||
|
||||
[heading Why don't `path` member functions have overloads with `error_code&` arguments?]
|
||||
|
||||
They have not been requested by users; the need for error reporting via `error_code` seems limited to filesystem operation
|
||||
failures rather than path failures.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:operations Operations function questions]
|
||||
|
||||
[heading Why not supply a 'handle' type, and let the file and directory operations traffic in it?]
|
||||
|
||||
It isn't clear there is any feasible way to meet the "portable script-style file system operations" requirement with such
|
||||
a system. File systems exist where operations are usually performed on some non-string handle type. The classic Mac OS has been
|
||||
mentioned explicitly as a case where trafficking in paths isn't always natural.
|
||||
|
||||
The case for the "handle" (opaque data type to identify a file) style may be strongest for directory iterator value type. (See
|
||||
Jesse Jones' Jan 28, 2002, Boost postings). However, as class `path` has evolved, it seems sufficient even as the directory
|
||||
iterator value type.
|
||||
|
||||
[heading Why are the operations functions so low-level?]
|
||||
|
||||
To provide a toolkit from which higher-level functionality can be created.
|
||||
|
||||
An extended attempt to add convenience functions on top of, or as a replacement for, the low-level functionality failed because
|
||||
there is no widely acceptable set of simple semantics for most convenience functions considered. Attempts to provide alternate
|
||||
semantics via either run-time options or compile-time polices became overly complicated in relation to the value delivered,
|
||||
or became contentious. On the other hand, the specific functionality needed for several trial applications was very easy for
|
||||
the user to construct from the lower-level toolkit functions. See [link filesystem.design.abandoned_designs Failed Attempts].
|
||||
|
||||
[heading Isn't it inconsistent then to provide a few convenience functions?]
|
||||
|
||||
Yes, but experience with both this library, POSIX, and Windows, indicates the utility of certain convenience functions, and
|
||||
that it is possible to provide simple, yet widely acceptable, semantics for them. For example, `remove_all()`.
|
||||
|
||||
[heading Why are there `directory_entry` overloads for `operations.hpp` predicate functions? Isn't two ways to do the same
|
||||
thing poor design?]
|
||||
|
||||
Yes, two ways to do the same thing is often a poor design practice. But the `directory_entry` versions are often much more
|
||||
efficient. Calling `status()` during iteration over a directory containing 15,000 files took 6 seconds for the path overload,
|
||||
and 1 second for the `directory_entry` overload, for tests on a freshly booted machine. Times were .90 seconds and .30 seconds,
|
||||
for tests after prior use of the directory. This performance gain is large enough to justify deviating from preferred design
|
||||
practices. Neither overload alone meets all needs.
|
||||
|
||||
[heading Why are the operations functions so picky about errors?]
|
||||
|
||||
Safety. The default is to be safe rather than sorry. This is particularly important given the reality that on many computer
|
||||
systems files and directories are globally shared resources, and thus subject to race conditions.
|
||||
|
||||
[heading Why are attributes accessed via named functions rather than property maps?]
|
||||
|
||||
For commonly used attributes (existence, directory or file, emptiness), simple syntax and guaranteed presence outweigh other
|
||||
considerations. Because access to many other attributes is inherently system dependent, property maps are viewed as the best hope
|
||||
for access and modification, but it is better design to provide such functionality in a separate library. (Historical note:
|
||||
even the apparently simple attribute "read-only" turned out to be so system dependent as to be disqualified as a "guaranteed
|
||||
presence" operation.)
|
||||
|
||||
[heading Why isn't automatic name portability error detection provided?]
|
||||
|
||||
A number (at least six) of designs for name validity error detection were evaluated, including at least four complete
|
||||
implementations. While the details for rejection differed, all of the more powerful name validity checking designs distorted
|
||||
other otherwise simple aspects of the library. Even the simple name checking provided in prior library versions was a constant
|
||||
source of user complaints. While name checking can be helpful, it isn't important enough to justify added a lot of additional
|
||||
complexity.
|
||||
|
||||
[heading Why are paths sometimes manipulated by member functions and sometimes by non-member functions?]
|
||||
|
||||
The design rule is that purely lexical operations are supplied as class `path` member functions, while operations performed
|
||||
by the operating system are provided as free functions.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
55
doc/filesystem.qbk
Normal file
55
doc/filesystem.qbk
Normal file
@@ -0,0 +1,55 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[library Boost.Filesystem
|
||||
[quickbook 1.7]
|
||||
[authors [Dawes, Beman], [Semashev, Andrey]]
|
||||
[copyright 2002-2015 Beman Dawes]
|
||||
[copyright 2019-2024 Andrey Semashev]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
[@https://www.boost.org/LICENSE_1_0.txt]).
|
||||
]
|
||||
[id filesystem]
|
||||
[source-mode c++]
|
||||
[version 4]
|
||||
]
|
||||
|
||||
[c++]
|
||||
|
||||
[def __boost_build__ [@https://www.boost.org/doc/libs/release/tools/build/doc/html/index.html Boost.Build]]
|
||||
[def __boost_system__ [@https://www.boost.org/doc/libs/release/libs/system/doc/html/system.html Boost.System]]
|
||||
|
||||
[template github_issue[key][@https://github.com/boostorg/filesystem/issues/[key] #[key]]]
|
||||
[template github_pr[key][@https://github.com/boostorg/filesystem/pull/[key] PR#[key]]]
|
||||
[template trac_issue[key][@https://svn.boost.org/trac/boost/ticket/[key] #[key]]]
|
||||
|
||||
[template super[x]'''<superscript>'''[x]'''</superscript>''']
|
||||
[template sub[x]'''<subscript>'''[x]'''</subscript>''']
|
||||
|
||||
[template header[x][headerref [x] [^[x]]]]
|
||||
[template enum[x][enumref boost::filesystem::[x] [^[x]]]]
|
||||
[template class[x][classref boost::filesystem::[x] [^[x]]]]
|
||||
[template member[x][memberref boost::filesystem::[x] [^[x]]]]
|
||||
[template func[x][funcref boost::filesystem::[x] [^[x]]]]
|
||||
|
||||
[include intro.qbk]
|
||||
[include install.qbk]
|
||||
[include tutorial.qbk]
|
||||
[include cautions.qbk]
|
||||
[include portability_guide.qbk]
|
||||
[include reference.qbk]
|
||||
[include faq.qbk]
|
||||
[include design.qbk]
|
||||
[include v3.qbk]
|
||||
[include v4.qbk]
|
||||
[include deprecated.qbk]
|
||||
[include issue_reporting.qbk]
|
||||
[include changelog.qbk]
|
||||
[include acknowledgements.qbk]
|
||||
212
doc/install.qbk
Normal file
212
doc/install.qbk
Normal file
@@ -0,0 +1,212 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:install Installing and using the library]
|
||||
|
||||
[section:platform_requirements Supported compilers and platforms]
|
||||
|
||||
The library requires a C++11 compiler as a minimum and is regularly tested with the following
|
||||
compilers:
|
||||
|
||||
* GCC 4.8 and newer on Linux.
|
||||
* Clang 3.5 and newer with libstdc++ and libc++ on Linux.
|
||||
* Apple Clang 13 on Mac OS.
|
||||
* MSVC 14.0 and newer on Windows.
|
||||
* Clang-cl 16.0.6 on Windows.
|
||||
* MinGW-w64 with GCC 8 and newer on Windows.
|
||||
* GCC 7 on Cygwin and Cygwin64.
|
||||
|
||||
The library supports POSIX systems and Windows 10 and newer. Note that many operating systems
|
||||
not normally thought of as POSIX systems, such as mainframe legacy operating systems or
|
||||
embedded operating systems, support POSIX compatible file systems and so will work with
|
||||
the Filesystem Library.
|
||||
|
||||
Besides the operating systems mentioned above, the library has been used on HP-UX, IBM AIX,
|
||||
SGI IRIX, OpenBSD, FreeBSD and Sun Solaris operating systems using a variety of compilers.
|
||||
It is also used by several smart phone operating systems.
|
||||
|
||||
[section:cygwin_notes Notes for Cygwin users]
|
||||
|
||||
[@https://www.cygwin.com/ Cygwin] version 1.7 or later is required because
|
||||
only versions of GCC with wide character strings are supported.
|
||||
|
||||
The library's implementation code treats Cygwin as a POSIX platform, and
|
||||
thus uses the POSIX API and path syntax as the native path syntax.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:building Building the library]
|
||||
|
||||
Boost.Filesystem is implemented as a separately compiled library, so you must install
|
||||
binaries in a location that can be found by your linker. If you followed the
|
||||
[@https://www.boost.org/doc/libs/release/more/getting_started/index.html Boost Getting Started]
|
||||
instructions, that's already been done for you.
|
||||
|
||||
Otherwise, the library can also be built manually using __boost_build__ or CMake using the project
|
||||
files in the library directory. For example, using __boost_build__ one can build a release version
|
||||
of the library with the following command line in the Boost root directory:
|
||||
|
||||
[pre
|
||||
b2 --with-filesystem variant=release stage
|
||||
]
|
||||
|
||||
With CMake, the library can be built with the following commands, also in the Boost root directory:
|
||||
|
||||
[pre
|
||||
mkdir build_static_release
|
||||
cd build_static_release
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DBOOST_INCLUDE_LIBRARIES=filesystem
|
||||
cmake --build .
|
||||
]
|
||||
|
||||
The library can be built for static or dynamic (shared/dll) linking. For Boost.Build,
|
||||
this is controlled with the `link` [@https://www.boost.org/doc/libs/release/tools/build/doc/html/index.html#bbv2.overview.builtins.features
|
||||
property] which can have values `shared` and `static`. For example, to build shared
|
||||
libraries:
|
||||
|
||||
[pre
|
||||
b2 --with-filesystem variant=release link=shared stage
|
||||
]
|
||||
|
||||
For CMake, the `BUILD_SHARED_LIBS` option enables building shared libraries. Note that
|
||||
with CMake users typically have to create a separate build directory for every
|
||||
build configuration.
|
||||
|
||||
[pre
|
||||
mkdir build_shared_release
|
||||
cd build_shared_release
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 -DBOOST_INCLUDE_LIBRARIES=filesystem
|
||||
cmake --build .
|
||||
]
|
||||
|
||||
When using Boost.Filesystem as a shared library, users should define `BOOST_ALL_DYN_LINK` or
|
||||
`BOOST_FILESYSTEM_DYN_LINK` macros when compiling their code. This will configure the auto-linking
|
||||
process to link with the shared library instead of the static one. See the
|
||||
[@https://www.boost.org/development/separate_compilation.html Separate Compilation] page for more details.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:config_macros Configuration Macros]
|
||||
|
||||
Users may define the following macros if desired. Sensible defaults are
|
||||
provided, so users can ignore these macros unless they have special needs.
|
||||
|
||||
Some of the macros can be defined when compiling user's code, which will affect library interfaces.
|
||||
Other macros can be defined during Boost.Filesystem compilation, which affect library implementation.
|
||||
Those macros need not be defined when building code that uses Boost.Filesystem.
|
||||
|
||||
[table
|
||||
[[Macro Name] [Default] [Affects library usage] [Affects library build] [Effect if defined]]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_VERSION`]
|
||||
[3]
|
||||
[\u2714][]
|
||||
[Selects the Boost.Filesystem library version. Can have values of 3 or 4.
|
||||
Defining to 4 also implies `BOOST_FILESYSTEM_NO_DEPRECATED`.]
|
||||
]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_NO_DEPRECATED`]
|
||||
[Not defined]
|
||||
[\u2714][]
|
||||
[Deprecated features are excluded from headers.]
|
||||
]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_DYN_LINK`]
|
||||
[Defined if `BOOST_ALL_DYN_LINK` is defined, otherwise not defined.]
|
||||
[\u2714][]
|
||||
[The Boost.Filesystem library is dynamically linked. If not defined,
|
||||
static linking is assumed.]
|
||||
]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_NO_LIB`]
|
||||
[Defined if `BOOST_ALL_NO_LIB` is defined, otherwise not defined.]
|
||||
[\u2714][]
|
||||
[Boost.Filesystem library does not use the Boost auto-link
|
||||
facility.]
|
||||
]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_DISABLE_SENDFILE`]
|
||||
[Not defined. `sendfile` API presence detected at library build time.]
|
||||
[][\u2714]
|
||||
[Boost.Filesystem library does not use the `sendfile` system call on Linux.
|
||||
The `sendfile` system call started accepting regular file descriptors as the target in Linux 2.6.33.]
|
||||
]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_DISABLE_COPY_FILE_RANGE`]
|
||||
[Not defined. `copy_file_range` API presence detected at library build time.]
|
||||
[][\u2714]
|
||||
[Boost.Filesystem library does not use the `copy_file_range` system call on Linux.
|
||||
The `copy_file_range` system call was introduced in Linux kernel 4.5 and started operating across filesystems in 5.3.]
|
||||
]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_DISABLE_STATX`]
|
||||
[Not defined. `statx` presence detected at library build time.]
|
||||
[][\u2714]
|
||||
[Boost.Filesystem library does not use the `statx` system call on Linux.
|
||||
The `statx` system call was introduced in Linux kernel 4.11.]
|
||||
]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_DISABLE_GETRANDOM`]
|
||||
[Not defined. `getrandom` API presence detected at library build time.]
|
||||
[][\u2714]
|
||||
[Boost.Filesystem library does not use the `getrandom` system call on Linux.
|
||||
The `getrandom` system call was introduced in Linux kernel 3.17.]
|
||||
]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_DISABLE_ARC4RANDOM`]
|
||||
[Not defined. `arc4random` API presence detected at library build time.]
|
||||
[][\u2714]
|
||||
[Boost.Filesystem library does not use the `arc4random_buf` system call on BSD systems.
|
||||
The `arc4random` API was introduced in OpenBSD 2.1 and FreeBSD 8.0.]
|
||||
]
|
||||
[
|
||||
[`BOOST_FILESYSTEM_DISABLE_BCRYPT`]
|
||||
[Not defined. BCrypt API presence detected at library build time.]
|
||||
[][\u2714]
|
||||
[Boost.Filesystem library does not use the BCrypt API on Windows. Has no effect on other platforms.]
|
||||
]
|
||||
]
|
||||
|
||||
In order to define macros when building Boost.Filesystem one can use `define` property with
|
||||
Boost.Build or `-D` option with CMake. For example:
|
||||
|
||||
[pre
|
||||
b2 --with-filesystem variant=release define=BOOST_FILESYSTEM_DISABLE_STATX stage
|
||||
]
|
||||
|
||||
or:
|
||||
|
||||
[pre
|
||||
mkdir build_static_release
|
||||
cd build_static_release
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DBOOST_INCLUDE_LIBRARIES=filesystem -DBOOST_FILESYSTEM_DISABLE_STATX
|
||||
cmake --build .
|
||||
]
|
||||
|
||||
For new code using Boost.Filesystem, defining `BOOST_FILESYSTEM_NO_DEPRECATED` before including
|
||||
filesystem headers is strongly recommended. This prevents inadvertent use of old features,
|
||||
particularly legacy function names, that have been replaced and are going to go away in the future.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:headers Headers and namespaces]
|
||||
|
||||
Library components can be introduced by including one of the headers in the `boost/filesystem`
|
||||
directory or `boost/filesystem.hpp`, which includes all headers in `boost/filesystem`.
|
||||
|
||||
Library components are defined in the `boost::filesystem` namespace.
|
||||
|
||||
Do not include headers from `boost/filesystem/detail` directory or use symbols from
|
||||
the `boost::filesystem::detail` namespace. Those are implementation details of the library,
|
||||
they are not part of the public interface and may be changed or removed without notice.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
75
doc/intro.qbk
Normal file
75
doc/intro.qbk
Normal file
@@ -0,0 +1,75 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:intro Introduction]
|
||||
|
||||
The Boost.Filesystem library provides facilities to manipulate files and directories,
|
||||
and the paths that identify them.
|
||||
|
||||
The features of the library include:
|
||||
|
||||
* A modern C++ interface, highly compatible with the C++ standard library.
|
||||
|
||||
Many users say the interface is their primary motivation for using
|
||||
Boost.Filesystem. They like its use of familiar idioms based on standard library
|
||||
containers, iterators, and algorithms. They like having errors reported by
|
||||
throwing exceptions.
|
||||
|
||||
* Portability between operating systems.
|
||||
* At the C++ syntax level, it is convenient to learn and use one interface
|
||||
regardless of the operating system.
|
||||
* At the semantic level, behavior of code is reasonably portable across
|
||||
operating systems.
|
||||
* Dual generic or native path format support encourages program
|
||||
portability, yet still allows communication with users in system specific
|
||||
formats.
|
||||
* Error handling and reporting via C++ exceptions (the default) or error codes.
|
||||
* C++ exceptions are the preferred error reporting mechanism for most
|
||||
applications. The exception thrown includes the detailed error code
|
||||
information important for diagnosing the exact cause of file system errors.
|
||||
* Error reporting via error code allows user code that provides detailed
|
||||
error recovery to avoid becoming so littered with try-catch blocks as to be
|
||||
unmaintainable.
|
||||
* Suitable for a broad spectrum of applications, ranging from simple
|
||||
script-like operations to extremely complex production code.
|
||||
* At the simple script-like end of the spectrum, the intent is not to
|
||||
compete with Python, Perl, or shell languages, but rather to provide
|
||||
filesystem operations when C++ is already the language of choice.
|
||||
* Finer grained control over operations and error handling is available to
|
||||
support more complex applications or other cases where throwing exceptions
|
||||
isn't desired.
|
||||
* Forms the basis for [@https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf ISO/IEC TS 18822],
|
||||
the C++ standard library Filesystem Technical Specification.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:docs Documentation]
|
||||
|
||||
This documentation consists of a number of sections describing the library interface
|
||||
and usage, as well as historical insight and rationale behind the current design.
|
||||
|
||||
* [link filesystem.tutorial Tutorial] - A gentle introduction to the library,
|
||||
with example programs provided for you to experiment with. This section
|
||||
is recommended for developers new to the library.
|
||||
* [link filesystem.reference Reference] - Formal documentation in the
|
||||
style of the C++ standard for every component of the library. This section
|
||||
is useful during active usage of the library, for detailed description
|
||||
of library interfaces.
|
||||
* [link filesystem.faq FAQ] - Frequently asked questions.
|
||||
* [link filesystem.portability_guide Portability Guide] - Help for those
|
||||
concerned with writing code to run on multiple operating systems.
|
||||
* [link filesystem.deprecated Deprecated Features] - Identifies
|
||||
deprecated features and their replacements.
|
||||
* [link filesystem.v4 Version 4 Description] - Summary of changes from
|
||||
Version 3.
|
||||
* [link filesystem.v3 Version 3 Description] - Historical documents,
|
||||
aimed at users of prior Boost.Filesystem versions.
|
||||
* [link filesystem.design Original Design] - Historical document from
|
||||
the start of the Version 1 design process.
|
||||
|
||||
[endsect]
|
||||
194
doc/issue_reporting.qbk
Normal file
194
doc/issue_reporting.qbk
Normal file
@@ -0,0 +1,194 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:issue_reporting Issue reporting]
|
||||
|
||||
Boost.Filesystem issues such as bug reports or feature requests should be reported via a [@https://github.com/boostorg/filesystem/issues/new
|
||||
GitHub ticket].
|
||||
|
||||
[@https://github.com/boostorg/filesystem/pulls GitHub pull requests] are encouraged, too, although anything beyond really trivial fixes needs
|
||||
a ticket.
|
||||
|
||||
A timely response to your bug report is much more likely if [*the problem can be immediately reproduced without guesswork and regression tests
|
||||
can be easily created].
|
||||
|
||||
You need to provide the following:
|
||||
|
||||
# A simple test program that:
|
||||
* Illustrates the problem, and
|
||||
* Automatically yields an unambiguous pass or fail result - returning zero for pass and non-zero for fail is preferred, and
|
||||
* Can be used as the basis for adding tests to Boost.Filesystem's regression test suite.
|
||||
# The compiler, standard library, platform, and Boost version you used to build and run your test program.
|
||||
# A description of how to build and run the test program.
|
||||
# A copy of the output from the test program, if any.
|
||||
|
||||
See [link filesystem.issue_reporting.rationale Rationale] to find out why the above is needed.
|
||||
|
||||
For a mostly automatic framework to provide the above, read on!
|
||||
|
||||
[section:framework Bug reporting framework]
|
||||
|
||||
The directory [^['[*boost-root]]\/libs\/filesystem\/bug] provides a bug test program ([link filesystem.issue_reporting.using_framework.bug_cpp
|
||||
`bug.cpp`]) and a build file (`Jamfile.v2`). Here is what you need to do:
|
||||
|
||||
# Add one or more test cases to [link filesystem.issue_reporting.using_framework.bug_cpp `bug.cpp`] using any text or program editor.
|
||||
# [link filesystem.issue_reporting.using_framework.build_and_test Build and test].
|
||||
# Attach copies of the [link filesystem.issue_reporting.using_framework.test_output Test output] and test program to the
|
||||
[@https://github.com/boostorg/filesystem/issues/new GitHub ticket].
|
||||
|
||||
That's it! When you complete those steps, you will be done!
|
||||
|
||||
The test output supplies all of the basic information about the compiler, std library, platform, Boost version, and command line, and the test
|
||||
cases you have added should make it easy for the library maintainer to reproduce the problem.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:using_framework Using the framework]
|
||||
|
||||
[section:bug_cpp `bug.cpp`]
|
||||
|
||||
Here is `bug.cpp` as supplied. To report a real bug, use `BOOST_TEST` and `BOOST_TEST_EQ` macros to build your own test cases. You can delete
|
||||
the three tests already in `bug.cpp`:
|
||||
|
||||
[import ../bug/bug.cpp]
|
||||
[bug_cpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:build_and_test Build and test]
|
||||
|
||||
[table
|
||||
[[POSIX-like systems] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
cd <boost-root>\/libs\/filesystem\/bug
|
||||
..\/..\/..\/b2 -a
|
||||
bin\/bug
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
cd <boost-root>\\libs\\filesystem\\bug
|
||||
..\\..\\..\\b2 -a
|
||||
bin\\bug
|
||||
]
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:test_output Test output]
|
||||
|
||||
Running the test on Windows produced this test output:
|
||||
|
||||
[pre
|
||||
Microsoft Visual C++ version 14.0
|
||||
Dinkumware standard library version 610
|
||||
Win32
|
||||
Boost version 1.58.0
|
||||
Command line: bin\\bug
|
||||
bug.cpp(10): test '2 + 2 == 5' failed in function
|
||||
'int __cdecl test_main(int,char *\[\])'
|
||||
bug.cpp(11): test '4 + 4 == 9' failed in function
|
||||
'int __cdecl test_main(int,char *\[\])': '8' != '9'
|
||||
2 errors detected.
|
||||
]
|
||||
|
||||
The test framework runs `test_main()` from a `try` block with a `catch` block that reports exceptions via `std::exception::what()`. So the output
|
||||
will differ if an exception is thrown.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:background_info Background information]
|
||||
|
||||
You should now have enough information to file an easy-to-reproduce bug report. So you can skip reading the rest of this page unless you need
|
||||
to do something a bit out of the ordinary.
|
||||
|
||||
[section:b2_command_line_options `b2` command line]
|
||||
|
||||
`b2` (formerly `bjam`) usage:
|
||||
|
||||
[pre
|
||||
b2 \[options\] \[properties\] \[target\]
|
||||
]
|
||||
|
||||
__boost_build__ `b2` has many options, properties, and targets, but you will not need most of them for bug reporting. Here are a few you might
|
||||
find helpful:
|
||||
|
||||
[table `b2` Options
|
||||
[[Option] [Effect]]
|
||||
[[[pre -a]]
|
||||
[
|
||||
Rebuild everything rather than just out-of-date targets. Used in the example build above to ensure libraries are built with the same setup
|
||||
as the test program.
|
||||
]]
|
||||
]
|
||||
|
||||
[table `b2` Properties
|
||||
[[Property] [Effect]]
|
||||
[[[pre address-model=['n]]
|
||||
|
||||
where ['n] is 32 or 64.]
|
||||
[
|
||||
Explicitly request either 32-bit or 64-bit code generation. This typically requires that your compiler is appropriately configured.
|
||||
]]
|
||||
[[[pre variant=['string]]
|
||||
|
||||
where ['string] is `debug` or `release`.]
|
||||
[
|
||||
Request debug or release build.
|
||||
]]
|
||||
[[[pre toolset=['string]]
|
||||
|
||||
where ['string] is composed of the compiler name and optionally, a version.]
|
||||
[
|
||||
The C++ compiler to use. For example, `gcc`, `gcc-4.9`, `clang-3.3`, or `msvc-14.0`. If the version is imitted, the default compiler version
|
||||
is used.
|
||||
]]
|
||||
[[[pre include=['string]]]
|
||||
[
|
||||
Additional include paths for C and C++ compilers.
|
||||
]]
|
||||
[[[pre cxxflags=['string]]]
|
||||
[
|
||||
Custom options to pass to the C++ compiler.
|
||||
]]
|
||||
[[[pre define=['string]]]
|
||||
[
|
||||
Additional macro definitions for C and C++ compilers. ['string] should be either `SYMBOL` or `SYMBOL=VALUE`
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:rationale Rationale]
|
||||
|
||||
Here is the request list again, with rationale added:
|
||||
|
||||
# A simple test program that:
|
||||
* Illustrates the problem ['\[Code communicates more clearly than prose. If it looks like it will it will take some time to figure out
|
||||
exactly what the problem is, or worse yet, might result in a wild-goose chase, the bug report gets set aside to be worked on later and
|
||||
then is often forgotten.\]] and
|
||||
* Automatically yields an unambiguous pass or fail result - returning zero for pass and non-zero for fail is preferred ['\[Prevents
|
||||
miscommunications and allows use in automatic regression tests.\]], and
|
||||
* Can be used as the basis for adding tests to Boost.Filesystem's regression test suite ['\[With good test cases fixes come easier and
|
||||
regressions become less likely\]].
|
||||
# The compiler, standard library, platform, and Boost version you used to build and run your test program. ['\[The implementation includes
|
||||
much platform dependent code, and also depends on the other factors mentioned. Know these things upfront brings the bug report into focus
|
||||
without having to ask for more information.\]]
|
||||
# A description of how to build and run the test program. ['\[If `b2` (formerly known as `bjam`) is used as the build engine, this is not
|
||||
a concern, but otherwise much more information is needed.\]]
|
||||
# A copy of the output from the test program, if any. ['\[Avoids misinterpreting results.\]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
205
doc/portability_guide.qbk
Normal file
205
doc/portability_guide.qbk
Normal file
@@ -0,0 +1,205 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:portability_guide Portability Guide]
|
||||
|
||||
[section:introduction Introduction]
|
||||
|
||||
Like any other C++ program which performs I/O operations, there is no guarantee that a program using Boost.Filesystem will be
|
||||
portable between operating systems. Critical aspects of I/O such as how the operating system interprets paths are unspecified
|
||||
by the C and C++ Standards.
|
||||
|
||||
It is not possible to know if a file or directory name will be valid (and thus portable) for an unknown operating system.
|
||||
There is always the possibility that an operating system could use names which are unusual (numbers less than 4096, for example)
|
||||
or very limited in size (maximum of six character names, for example). In other words, portability is never absolute; it is
|
||||
always relative to specific operating systems or file systems.
|
||||
|
||||
It is possible, however, to know in advance if a directory or file name is likely to be valid for a particular operating system.
|
||||
It is also possible to construct names which are likely to be portable to a large number of modern and legacy operating systems.
|
||||
|
||||
Almost all modern operating systems support multiple file systems. At the minimum, they support a native file system plus
|
||||
a CD-ROM file system (Generally ISO-9669, often with Joliet extensions).
|
||||
|
||||
Each file system may have its own naming rules. For example, modern versions of Windows support NTFS, FAT, FAT32, and ISO-9660
|
||||
file systems, among others, and the naming rules for those file systems differ. Each file system may also have differing rules
|
||||
for overall path validity, such as a maximum length or number of sub-directories. Some legacy systems have different rules for
|
||||
directory names versus regular file names.
|
||||
|
||||
As a result, Boost.Filesystem's name checking functions cannot guarantee directory and file name portability. Rather, they are
|
||||
intended to give the programmer a "fighting chance" to achieve portability by early detection of common naming problems.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:name_check_functions Name checking functions]
|
||||
|
||||
A name checking function returns `true` if its argument is valid as a directory and regular file name for a particular operating
|
||||
or file system. A number of these functions are provided.
|
||||
|
||||
The [link filesystem.portability_guide.name_check_functions.portable_name `portable_name`] function is of particular interest
|
||||
because it has been carefully designed to provide wide portability yet not overly restrict expressiveness.
|
||||
|
||||
[table Library Supplied Name Checking Functions
|
||||
[[Function] [Description]]
|
||||
[[[#filesystem.portability_guide.name_check_functions.portable_posix_name]`bool portable_posix_name(const std::string& name)`]
|
||||
[
|
||||
[*Returns:] `true` if `!name.empty()` and `name` contains only the characters specified in ['Portable Filename Character Set]
|
||||
rules as defined in by POSIX ([@https://pubs.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap03.html
|
||||
www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap03.html]).
|
||||
|
||||
The allowed characters are "0-9", "a-z", "A-Z", ".", "_", and "-".
|
||||
|
||||
[*Use:] applications which must be portable to any POSIX system.
|
||||
]]
|
||||
[[[#filesystem.portability_guide.name_check_functions.windows_name]`bool windows_name(const std::string& name)`]
|
||||
[
|
||||
[*Returns:] `true` if
|
||||
|
||||
* `!name.empty()`, and
|
||||
* `name` contains only the characters specified by the Windows platform SDK as valid regardless of the file system, and
|
||||
* `name` is "." or ".." or does not end with a trailing space or period.
|
||||
|
||||
The allowed characters are anything except `0x0-0x1F`, "<", ">", ":", """, "/", "\\", and "|".
|
||||
|
||||
[*Use:] applications which must be portable to Windows.
|
||||
|
||||
[note Reserved device names are not valid as file names, but are not being detected because they are still valid as a path.
|
||||
Specifically, "CON", "PRN", "AUX", "CLOCK$", "NUL", "COM\[1-9\]", "LPT\[1-9\]", and these names followed by an extension
|
||||
(for example, "NUL.tx7").]
|
||||
]]
|
||||
[[[#filesystem.portability_guide.name_check_functions.portable_name]`bool portable_name(const std::string& name)`]
|
||||
[
|
||||
[*Returns:] `true` if
|
||||
|
||||
* `windows_name(name)`, and
|
||||
* `portable_posix_name(name)`, and
|
||||
* `name` is "." or "..", or the first character of `name` is not a period or hyphen.
|
||||
|
||||
[*Use:] applications which must be portable to a wide variety of modern operating systems, large and small, and to some
|
||||
legacy OSs. The first character not a period or hyphen restriction is a requirement of several older operating systems.
|
||||
]]
|
||||
[[[#filesystem.portability_guide.name_check_functions.portable_directory_name]`bool portable_directory_name(const std::string& name)`]
|
||||
[
|
||||
[*Returns:] `true` if `portable_name(name)` and `name` is "." or ".." or contains no periods.
|
||||
|
||||
[*Use:] applications which must be portable to a wide variety of platforms, including OpenVMS.
|
||||
]]
|
||||
[[[#filesystem.portability_guide.name_check_functions.portable_file_name]`bool portable_file_name(const std::string& name)`]
|
||||
[
|
||||
[*Returns:] `true` if
|
||||
|
||||
* `portable_name(name)`, and
|
||||
* any period is followed by one to three additional non-period characters.
|
||||
|
||||
[*Use:] applications which must be portable to a wide variety of platforms, including OpenVMS and other systems which have
|
||||
a concept of "file extension" but limit its length.
|
||||
]]
|
||||
[[[#filesystem.portability_guide.name_check_functions.native]`bool native(const std::string& name)`]
|
||||
[
|
||||
[*Returns:] Implementation defined. Returns `true` for names considered valid by the operating system's native file systems.
|
||||
|
||||
[*Note:] May return `true` for some names not considered valid by the operating system under all conditions (particularly
|
||||
on operating systems which support multiple file systems.)
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:recommendations File and directory name recommendations]
|
||||
|
||||
[table
|
||||
[[Recommendation] [Rationale]]
|
||||
[[
|
||||
Limit file and directory names to the characters "A-Z", "a-z", "0-9", period, hyphen, and underscore.
|
||||
|
||||
Use any of the `portable_` [link filesystem.portability_guide.name_check_functions name checking functions] to enforce this
|
||||
recommendation.
|
||||
]
|
||||
[
|
||||
These are the characters specified by the POSIX standard for portable directory and file names, and are also valid for Windows,
|
||||
Mac OS, and many other modern file systems.
|
||||
]]
|
||||
[[
|
||||
Do not use a period or hyphen as the first character of a name. Do not use period as the last character of a name.
|
||||
|
||||
Use [link filesystem.portability_guide.name_check_functions.portable_name `portable_name`],
|
||||
[link filesystem.portability_guide.name_check_functions.portable_directory_name `portable_directory_name`], or
|
||||
[link filesystem.portability_guide.name_check_functions.portable_file_name `portable_file_name`] to enforce this
|
||||
recommendation.
|
||||
]
|
||||
[
|
||||
Some operating systems treat have special rules for the first character of names. POSIX, for example. Windows does not permit
|
||||
period as the last character.
|
||||
]]
|
||||
[[
|
||||
Do not use periods in directory names.
|
||||
|
||||
Use [link filesystem.portability_guide.name_check_functions.portable_directory_name `portable_directory_name`] to enforce
|
||||
this recommendation.
|
||||
]
|
||||
[
|
||||
Requirement for ISO-9660 without Juliet extensions, OpenVMS filesystem, and other legacy systems.
|
||||
]]
|
||||
[[
|
||||
Do not use more that one period in a file name, and limit the portion after the period to three characters.
|
||||
|
||||
Use [link filesystem.portability_guide.name_check_functions.portable_file_name `portable_file_name`] to enforce this
|
||||
recommendation.
|
||||
]
|
||||
[
|
||||
Requirement for ISO-9660 level 1, OpenVMS filesystem, and other legacy systems.
|
||||
]]
|
||||
[[
|
||||
Do not assume names are case sensitive. For example, do not expected a directory to be able to hold separate elements named
|
||||
"Foo" and "foo".
|
||||
]
|
||||
[
|
||||
Some file systems are case insensitive. For example, Windows NTFS is case preserving in the way it stores names, but case
|
||||
insensitive in searching for names (unless running under the POSIX sub-system, it which case it does case sensitive searches).
|
||||
]]
|
||||
[[
|
||||
Do not assume names are case insensitive. For example, do not expect a file created with the name of "Foo" to be opened
|
||||
successfully with the name of "foo".
|
||||
]
|
||||
[
|
||||
Some file systems are case sensitive. This is typically the case on POSIX systems. Even on Windows, NTFS supports creating
|
||||
files with names in [@https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions POSIX convention],
|
||||
which makes them case sensitive.
|
||||
]]
|
||||
[[
|
||||
Don't use hyphens in names.
|
||||
]
|
||||
[
|
||||
ISO-9660 level 1, and possibly some legacy systems, do not permit hyphens.
|
||||
]]
|
||||
[[
|
||||
Limit the length of the string returned by `path::string()` to 255 characters. Note that ISO 9660 has an explicit directory
|
||||
tree depth limit of 8, although this depth limit is removed by the Juliet extensions.
|
||||
]
|
||||
[
|
||||
Some operating systems place limits on the total path length. For example, Windows 2000 limits paths to 260 characters total
|
||||
length.
|
||||
]]
|
||||
[[
|
||||
Limit the length of any one name in a path. Pick the specific limit according to the operating systems and/or file systems
|
||||
you wish to maintain portability to:
|
||||
|
||||
* Not a concern: POSIX, Windows, MAC OS X.
|
||||
* 31 characters: Classic Mac OS
|
||||
* 8 characters + period + 3 characters: ISO 9660 level 1
|
||||
* 32 characters: ISO 9660 level 2 and 3
|
||||
* 128 characters (64 if Unicode): ISO 9660 with Juliet extensions
|
||||
]
|
||||
[
|
||||
Limiting name length can markedly reduce the expressiveness of file names, yet placing only very high limits on lengths inhibits
|
||||
widest portability.
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
9030
doc/reference-full.qbk
Normal file
9030
doc/reference-full.qbk
Normal file
File diff suppressed because it is too large
Load Diff
582
doc/reference.qbk
Normal file
582
doc/reference.qbk
Normal file
@@ -0,0 +1,582 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024-2025.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:reference Reference]
|
||||
|
||||
[section:intro Introduction]
|
||||
|
||||
This reference documentation describes components that C++ programs may use to perform operations involving file systems, including paths, regular files,
|
||||
and directories.
|
||||
|
||||
[section:conformance Conformance]
|
||||
|
||||
[section:iso_iec_9945 ISO/IEC 9945 conformance]
|
||||
|
||||
Some behavior in this reference documentation is specified by reference to ISO/IEC 9945. How such behavior is actually implemented is unspecified.
|
||||
|
||||
[note This constitutes an "as if" rule for implementation of operating system dependent behavior. In practice implementations will usually call native
|
||||
operating system API's.]
|
||||
|
||||
Implementations are encouraged to provide such behavior as it is defined by ISO/IEC 9945. Implementations shall document any behavior that differs from
|
||||
the behavior defined by ISO/IEC 9945. Implementations that do not support exact ISO/IEC 9945 behavior are encouraged to provide behavior as close
|
||||
to ISO/IEC 9945 behavior as is reasonable given the limitations of actual operating systems and file systems. If an implementation cannot provide any
|
||||
reasonable behavior, the implementation shall report an error in an implementation-defined manner.
|
||||
|
||||
[note Such errors might be reported by an `#error` directive, a `static_assert`, a [class_filesystem_filesystem_error] exception, a special return value,
|
||||
or some other manner.]
|
||||
|
||||
Implementations are not required to provide behavior that is not supported by a particular file system.
|
||||
|
||||
[tip The [@https://en.wikipedia.org/wiki/FAT_filesystem FAT file system] used by some memory cards, camera memory, and floppy discs does not support
|
||||
hard links, symlinks, and many other features of more capable file systems. Implementations are only required to support the FAT features supported
|
||||
by the host operating system.]
|
||||
|
||||
The behavior of functions described in this reference may differ from their specification in the presence of
|
||||
[link filesystem.reference.intro.defs.file-system-race file system races]. No diagnostic is required.
|
||||
|
||||
If the possibility of a file system race would make it unreliable for a program to test for a precondition before calling a function described in this
|
||||
reference documentation, [*Requires] is not specified for the condition. Instead, the condition is specified as a [*Throws] condition.
|
||||
|
||||
[note As a design practice, preconditions are not specified when it is unreasonable for a program to detect them prior to calling the function.]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:os Operating system dependent conformance]
|
||||
|
||||
Some behavior is specified in this reference documentation as being operating system dependent (\[fs.def.osdep\]). The operation system an implementation
|
||||
is dependent upon is implementation defined.
|
||||
|
||||
It is permissible for an implementation to be dependent upon an operating system emulator rather than the actual operating system.
|
||||
|
||||
[tip ['Example:] An implementation uses [@https://cygwin.com/ Cygwin], a Linux® API emulator for some Windows® operating system versions. The implementation
|
||||
would define Cygwin as its operating system. Users could refer to the Cygwin documentation to find details of the operating system dependent behavior.
|
||||
|
||||
It is user and conformance test detectable that such an implementation is running on Cygwin. Users would be misled and conformance tests would fail
|
||||
if the implementation defined Linux or Windows rather than Cygwin as the operating system, since real behavior is a blend of the two.]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:defs Definitions]
|
||||
|
||||
The following definitions shall apply throughout this reference documentation:
|
||||
|
||||
[variablelist
|
||||
[
|
||||
[operating system dependent behavior]
|
||||
[Behavior that is dependent upon the behavior and characteristics of an operating system. See [link filesystem.reference.intro.conformance.os here].]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.file]file]
|
||||
[An object that can be written to, or read from, or both. A file has certain attributes, including type. File types include regular files
|
||||
and directories. Other types of files, such as symbolic links, may be supported by the implementation.]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.filesystem]file system]
|
||||
[A collection of files and their attributes.]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.filename]filename]
|
||||
[The name of a file. Filenames "." and ".." have special meaning. The following characteristics of filenames are operating system dependent:
|
||||
|
||||
* The permitted characters. See [link filesystem.reference.path.os-examples here] for examples.
|
||||
* Specific filenames that are not permitted.
|
||||
* Additional filenames that have special meaning.
|
||||
* Case awareness and sensitivity during path resolution.
|
||||
* Special rules that may apply to file types other than regular files, such as directories.
|
||||
]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.path]path]
|
||||
[A sequence of elements that identify the location of a file within a filesystem. The elements are the ['root-name[sub opt]],
|
||||
['root-directory[sub opt]], and an optional sequence of filenames.
|
||||
[note A [link filesystem.reference.intro.defs.pathname pathname] is the concrete representation of a path.]
|
||||
]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.absolute-path]absolute path]
|
||||
[A path that unambiguously identifies the location of a file without reference to an additional starting location. The elements of a path
|
||||
that determine if it is absolute are operating system dependent.]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.relative-path]relative path]
|
||||
[A path that is not absolute, and so only unambiguously identifies the location of a file when resolved relative to an implied starting location.
|
||||
The elements of a path that determine if it is relative are operating system dependent.
|
||||
[note Paths "." and ".." are relative paths.]
|
||||
]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.canonical-path]canonical path]
|
||||
[An absolute path that has no elements that are symbolic links, and no "." or ".." elements.]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.pathname]pathname]
|
||||
[A character string that represents the name of a path. Pathnames are formatted according to the generic pathname grammar or an operating system
|
||||
dependent native pathname format.]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.native-format]native pathname format]
|
||||
[The operating system dependent pathname format accepted by the host operating system.]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.normal-form]normal form path]
|
||||
[A path with no redundant directory separators, current directory (['dot]) or parent directory (['dot-dot]) elements. The normal form for
|
||||
an empty path is an empty path. \[[*v3:] The normal form for a path ending in a ['directory-separator] that is not the root directory
|
||||
is the same path with a current directory (['dot]) element appended.\]]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.link]link]
|
||||
[A directory entry object that associates a filename with a file. On some file systems, several directory entries can associate names with
|
||||
the same file.]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.hard-link]hard link]
|
||||
[A link to an existing file. Some file systems support multiple hard links to a file. If the last hard link to a file is removed, the file
|
||||
itself is removed.
|
||||
[note A hard link can be thought of as a shared-ownership smart pointer to a file.]
|
||||
]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.symbolic-link]symbolic link]
|
||||
[A type of file with the property that when the file is encountered during pathname resolution, a string stored by the file is used to modify
|
||||
the pathname resolution.
|
||||
[note A symbolic link can be thought of as a raw pointer to a file. If the file pointed to does not exist, the symbolic link is said to be a
|
||||
"dangling" symbolic link.]
|
||||
]
|
||||
]
|
||||
[
|
||||
[[#filesystem.reference.intro.defs.file-system-race]file system race]
|
||||
[The condition that occurs when multiple threads, processes, or computers interleave access and modification of the same object within
|
||||
a file system.]
|
||||
]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:path Path]
|
||||
|
||||
[section:generic-pathname-format Generic pathname format]
|
||||
|
||||
Following is the formal grammar of a generic pathname.
|
||||
|
||||
[pre
|
||||
pathname:
|
||||
root-name[sub opt] root-directory[sub opt] relative-path[sub opt]
|
||||
|
||||
root-name:
|
||||
['An operating system dependent name that identifies the starting location for absolute paths.]
|
||||
|
||||
root-directory:
|
||||
directory-separator
|
||||
|
||||
relative-path:
|
||||
filename
|
||||
relative-path directory-separator
|
||||
relative-path directory-separator filename
|
||||
|
||||
filename:
|
||||
name
|
||||
"."
|
||||
".."
|
||||
|
||||
preferred-separator:
|
||||
['An operating system dependent directory separator character. May be a synonym for "/".]
|
||||
|
||||
directory-separator:
|
||||
"/"
|
||||
"/" directory-separator
|
||||
preferred-separator
|
||||
preferred-separator directory-separator
|
||||
]
|
||||
|
||||
[note Many operating systems define a name beginning with two ['directory-separator] characters as a ['root-name] that identifies network
|
||||
or other resource locations. Some operating systems define a single letter followed by a colon as a drive specifier - a ['root-name]
|
||||
identifying a specific device such as a disc drive.]
|
||||
|
||||
Multiple successive ['directory-separator] characters are considered to be the same as one ['directory-separator] character.
|
||||
|
||||
The ['filename] "." is considered to be a reference to the current directory. The ['filename] ".." is considered to be a reference to the
|
||||
parent directory. Specific ['filenames] may have special meanings for a particular operating system.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:os-examples Operating system dependent examples (Informative)]
|
||||
|
||||
Certain features are specified in this reference documentation as being operating system dependent. The following table shows the application
|
||||
of those specifications for operating systems that use the ISO/IEC 9945 or Windows application program interfaces (APIs).
|
||||
[link filesystem.reference.path.os-examples.footnote1 [super \[1\]]]
|
||||
|
||||
[table
|
||||
[[Feature] [Section] [ISO/IEC 9945 POSIX API] [Windows API] [Notes]]
|
||||
[[
|
||||
`path::value_type`
|
||||
]
|
||||
[
|
||||
[class path]
|
||||
]
|
||||
[
|
||||
`char`
|
||||
]
|
||||
[
|
||||
`wchar_t`
|
||||
]
|
||||
[
|
||||
]]
|
||||
[[
|
||||
`path::preferred_separator`
|
||||
]
|
||||
[
|
||||
[class path]
|
||||
]
|
||||
[
|
||||
`'/'`
|
||||
]
|
||||
[
|
||||
`L'\\\\'` (single backslash)
|
||||
]
|
||||
[
|
||||
]]
|
||||
[[
|
||||
`path("/").is_absolute()`
|
||||
]
|
||||
[
|
||||
[member path::is_absolute]
|
||||
]
|
||||
[
|
||||
`true`
|
||||
]
|
||||
[
|
||||
`false`
|
||||
]
|
||||
[
|
||||
]]
|
||||
[[
|
||||
`path("c:/").is_absolute()`
|
||||
]
|
||||
[
|
||||
[member path::is_absolute]
|
||||
]
|
||||
[
|
||||
`false`
|
||||
]
|
||||
[
|
||||
`true`
|
||||
]
|
||||
[
|
||||
]]
|
||||
[[
|
||||
`path` argument disambiguation between generic format and native format
|
||||
]
|
||||
[
|
||||
[link filesystem.reference.path.conversions.format Format conversions]
|
||||
]
|
||||
[
|
||||
Not required
|
||||
]
|
||||
[
|
||||
Not required
|
||||
]
|
||||
[
|
||||
There is no need to distinguish between the generic format and native format for these operating systems.
|
||||
]]
|
||||
[[
|
||||
`path` argument format conversion
|
||||
]
|
||||
[
|
||||
[link filesystem.reference.path.conversions.format Format conversions]
|
||||
]
|
||||
[
|
||||
No conversion performed
|
||||
]
|
||||
[
|
||||
No conversion performed
|
||||
]
|
||||
[
|
||||
The generic format is already acceptable to the native API of these operating systems.
|
||||
]]
|
||||
[[
|
||||
`path("/cats/jane").c_str()`
|
||||
]
|
||||
[
|
||||
[link filesystem.reference.path.conversions.format Format conversions]
|
||||
]
|
||||
[
|
||||
`"/cats/jane"`
|
||||
]
|
||||
[
|
||||
`L"/cats/jane"`
|
||||
]
|
||||
[
|
||||
These operating systems accept the same native separator between directory names and a final file name, so no format conversion is performed.
|
||||
Other operating systems might require conversion.
|
||||
]]
|
||||
[[
|
||||
`path("/cats/jane/").c_str()`
|
||||
]
|
||||
[
|
||||
[link filesystem.reference.path.conversions.format Format conversions]
|
||||
]
|
||||
[
|
||||
`"/cats/jane/"`
|
||||
]
|
||||
[
|
||||
`L"/cats/jane/"`
|
||||
]
|
||||
[
|
||||
These operating systems accept the same native separator between directory names and a final file name, so no format conversion is performed.
|
||||
Other operating systems might require conversion.
|
||||
]]
|
||||
[[
|
||||
Format conversion by `path` native format observers
|
||||
]
|
||||
[
|
||||
[member path::native]
|
||||
]
|
||||
[
|
||||
No conversion performed
|
||||
]
|
||||
[
|
||||
No conversion performed
|
||||
]
|
||||
[
|
||||
For efficiency, `path` objects are required to store pathnames in the native format regardless of operating system.
|
||||
]]
|
||||
[[
|
||||
Format conversion by `path` generic format observers
|
||||
]
|
||||
[
|
||||
[member path::generic_path]
|
||||
]
|
||||
[
|
||||
No conversion performed
|
||||
]
|
||||
[
|
||||
Backslashes converted to slashes
|
||||
]
|
||||
[
|
||||
]]
|
||||
[[
|
||||
`p.make_preferred()`
|
||||
]
|
||||
[
|
||||
[member path::make_preferred]
|
||||
]
|
||||
[
|
||||
No change
|
||||
]
|
||||
[
|
||||
Slashes converted to backslashes
|
||||
]
|
||||
[
|
||||
]]
|
||||
[[
|
||||
Characters prohibited in filenames
|
||||
]
|
||||
[
|
||||
[link filesystem.reference.intro.defs.filename filename]
|
||||
]
|
||||
[
|
||||
0x00, `'/'`
|
||||
]
|
||||
[
|
||||
0x00-0x1F, `'"'`, `'*'`,` '*'`, `'<'`, `'>'`, `'?'`, `'\\\\'` (single backslash), `'/'`, `'|'`
|
||||
]
|
||||
[
|
||||
Many operating systems prohibit the ASCII control characters (0x00-0x1F) in filenames.
|
||||
]]
|
||||
[[
|
||||
Initial imbued `path` locale
|
||||
]
|
||||
[
|
||||
[member path::imbue], [member path::codecvt]
|
||||
]
|
||||
[
|
||||
`std::locale("")`[link filesystem.reference.path.os-examples.footnote2 [super \[2\]]]
|
||||
]
|
||||
[
|
||||
Implementation supplied locale using `MultiByteToWideChar` and `WideCharToMultiByte` with a codepage of `CP_ACP`
|
||||
if `AreFileApisANSI` is true, otherwise codepage `CP_OEMCP`.[link filesystem.reference.path.os-examples.footnote3 [super \[3\]]]
|
||||
]
|
||||
[
|
||||
Apple OS X®: Implementation supplied locale providing UTF-8 `codecvt` facet.[link filesystem.reference.path.os-examples.footnote4 [super \[4\]]]
|
||||
]]
|
||||
]
|
||||
|
||||
[#filesystem.reference.path.os-examples.footnote1][super \[1\]] OS X® and Windows® are examples of commercially available operating systems. This information
|
||||
is given for the convenience of users of this document and does not constitute an endorsement by ISO or IEC of these products.
|
||||
|
||||
[#filesystem.reference.path.os-examples.footnote2][super \[2\]] Rationale: ISO C specifies `std::locale("")` as "the locale-specific native environment",
|
||||
while ISO/IEC 9945 says it "Specifies an implementation-defined native environment."
|
||||
|
||||
[#filesystem.reference.path.os-examples.footnote3][super \[3\]] Rationale: This is the current behavior of C and C++ standard library functions that perform
|
||||
file operations using narrow character strings to identify paths. Changing this behavior would be surprising and at variance with existing code,
|
||||
particularly where user input is involved.
|
||||
|
||||
[#filesystem.reference.path.os-examples.footnote4][super \[4\]] Rationale: Vendor's documentation states "All BSD system functions expect their string parameters
|
||||
to be in UTF-8 encoding and nothing else."
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:usage Usage concerns]
|
||||
|
||||
[section:multithreading Multithreading concerns]
|
||||
|
||||
Filesystem library functions are not protected against data races. Modifying an object of a Filesystem library type that is shared between threads risks
|
||||
undefined behavior unless objects of that type are explicitly specified as being sharable without data races or the user supplies a locking mechanism.
|
||||
|
||||
Class `path` uses a global locale object to perform character code conversion, when needed. This means that changing the locale in one thread may affect
|
||||
library behavior in other threads. It is recommended to configure the `path` locale once, early during the application startup, before multiple threads
|
||||
have started using the library.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:init_order Global initialization and destruction concerns]
|
||||
|
||||
Given that class `path` uses a global locale, as well as some other internal objects, using the Filesystem library in global constructors and destructors
|
||||
(i.e. before or after `main`) may be problematic because the global objects do not exist. The Filesystem library attempts to mitigate the problem using
|
||||
various compiler and platform-specific and mechanisms, such as enforcing early initialization of the internal global objects. The currently supported
|
||||
configurations include MSVC on Windows and GCC and compatible compilers supporting the
|
||||
[@https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#index-init_005fpriority-variable-attribute `init_priority`] attribute on the target platform.
|
||||
|
||||
However, being non-portable, such workarounds cannot be guaranteed to work in every configuration. Portable programs should avoid using the Filesystem
|
||||
library in global constructors and destructors.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:posix POSIX concerns]
|
||||
|
||||
Filesystem library initialization may throw an exception on POSIX systems (e.g. Linux, but not Mac OS X) that use environmental variables to
|
||||
determine the encoding of paths. This happens when `std::locale("")` throws because an environmental variable such as `LANG` is set to an invalid
|
||||
value, so it can affect any use of `std::locale("")`, not just the Filesystem library. Filesystem uses lazy initialization so the exception is
|
||||
only thrown if a valid `std::locale("")` is actually needed, and also so that the exception is thrown after `main()` starts.
|
||||
|
||||
Rather than waiting until a call to some Filesystem library function unexpectedly triggers the exception when it calls `path::codecvt()`,
|
||||
a program that needs be highly robust against environmental variable problems may want to preemptively call `std::locale("")` within a try block,
|
||||
catch the exception, and diagnose or repair the invalid environmental variable.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:conversions Conversions]
|
||||
|
||||
[section:format Path format conversions]
|
||||
|
||||
Member function arguments that take character sequences representing paths may use the [link filesystem.reference.path.generic-pathname-format
|
||||
generic pathname format] or the [link filesystem.reference.intro.defs.native-format native pathname format]. Iff such arguments are in
|
||||
the generic format and the generic format is not acceptable to the operating system as a native path, conversion to native format shall be performed
|
||||
during the processing of the argument. See [link filesystem.reference.path.os-examples OS-specific examples].
|
||||
|
||||
[note Depending on the operating system, there may be no unambiguous way for an implementation to always be able to distinguish between native format
|
||||
and generic format arguments. This is by design as it simplifies use for operating systems that do not require disambiguation. Should
|
||||
an implementation encounter an operating system where disambiguation is required, an implementation can define an extension to distinguish between
|
||||
the formats.]
|
||||
|
||||
If the native format requires paths for regular files to be formatted differently from paths for directories, the path shall be treated as a directory
|
||||
path if last element is a separator, otherwise it shall be treated as a regular file path.
|
||||
|
||||
Generic format observer functions shall return strings formatted according to the [link filesystem.reference.path.generic-pathname-format generic
|
||||
pathname format] using ['preferred-separator]. See [link filesystem.reference.path.os-examples OS-specific examples].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:encoding Character encoding conversions]
|
||||
|
||||
For `path` member function arguments that take character sequences representing paths, if the value type of the argument is not `value_type`, character
|
||||
encoding conversion to `value_type` shall be performed. Such conversions shall be performed by the `path::codecvt()` facet by default, unless another
|
||||
facet is specified in the operation.
|
||||
|
||||
The default character encoding facet is set globally for all `path` objects. It can be set as part of the locale object passed to the `path::imbue()`
|
||||
method.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:requirements Argument requirements]
|
||||
|
||||
Some of the class `path` member function templates have parameters with the following requirements.
|
||||
|
||||
[#filesystem.reference.path.requirements.InputIterator]Template parameters named `InputIterator` are required to meet the requirements for a
|
||||
C++ standard library `InputIterator` compliant iterator. The iterator's value type is required to be one of: `char`, `wchar_t`. Collectively,
|
||||
these types are referred to as ['supported path character types].
|
||||
|
||||
[#filesystem.reference.path.requirements.Source]Template parameters named `Source` are required to be one of:
|
||||
|
||||
* A `std::basic_string`, `std::basic_string_view`, `boost::container::basic_string` or `boost::basic_string_view` specialization with a value
|
||||
type of one of the supported path character types.
|
||||
* [*v3, deprecated:] A container with a value type of one of the supported path character types.
|
||||
* A pointer into a null terminated string. The value type is required to be a supported path character type.
|
||||
* A C-array of supported path character type containing a null terminated string.
|
||||
* A `boost::filesystem::directory_entry`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:composition Composition]
|
||||
|
||||
Class `path` supports a variety of methods for observing and modifying the path. Among the modifiers, there are two groups of methods for
|
||||
performing concatenation and appending. The important distinction between these two groups is that concatenation is performed on the path as if
|
||||
the path was a simple string (i.e. the concatenated characters are placed immediately at the end of the path), while appending maintains path
|
||||
structure and may insert a directory separator before the appended characters. The rules for inserting the separator depend on the library version
|
||||
and are documented in the `path::append()` method description.
|
||||
|
||||
Class `path` also supports operators `+` and `/` for concatenation and appending, respectively, as well as the corresponding assigning versions
|
||||
thereof.
|
||||
|
||||
```
|
||||
p1 = "foo";
|
||||
std::cout << (p + "bar") << std::endl; // outputs "foobar"
|
||||
std::cout << (p / "bar") << std::endl; // outputs "foo/bar"
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:iterators Iterators]
|
||||
|
||||
Class `path` supports iterators `iterator`, `const_iterator`, `reverse_iterator`, and `const_reverse_iterator` to iterate over the elements
|
||||
of the stored pathname.
|
||||
|
||||
Path iterators are constant iterators satisfying the requirements of a bidirectional iterator (C++ Std, 24.1.4 Bidirectional
|
||||
iterators \[lib.bidirectional.iterators\]). The `value_type` of an iterator is `path`.
|
||||
|
||||
[note Path iterators store their value objects internally and when dereferenced return references to those internal objects. They cannot
|
||||
be used with iterator adaptors such as `std::reverse_iterator` that assume references obtained by dereferencing an iterator point to objects
|
||||
that out-live the iterator itself.]
|
||||
|
||||
Calling any non-const member function of a `path` object invalidates all iterators referring to elements of that object.
|
||||
|
||||
The forward traversal order is as follows:
|
||||
|
||||
* The ['root-name] element, if present.
|
||||
* The ['root-directory] element, if present, in the generic format.
|
||||
[note The generic format is required to ensure lexicographical comparison works correctly.]
|
||||
* Each successive ['filename] element, if present.
|
||||
* \[[*v3:] ['Dot]\] \[[*v4:] Empty path\], if one or more trailing non-root directory separators are present.
|
||||
|
||||
[note Treating the last element during iteration as \[[*v3:] ['dot]\] \[[*v4:] an empty path\] when there is a trailing directory separator
|
||||
enables lexical (i.e. syntactic) distinction between paths to directories versus paths to regular files. Such a distinction is usually
|
||||
irrelevant on POSIX and Windows based operating systems, but may be a requirement on other operating systems.]
|
||||
|
||||
The backward traversal order is the reverse of forward traversal.
|
||||
|
||||
[endsect]
|
||||
|
||||
[xinclude path_reference.xml]
|
||||
|
||||
[endsect]
|
||||
|
||||
[xinclude operations_reference.xml]
|
||||
[xinclude directory_reference.xml]
|
||||
[xinclude file_status_reference.xml]
|
||||
[xinclude exception_reference.xml]
|
||||
[xinclude io_reference.xml]
|
||||
|
||||
[endsect]
|
||||
964
doc/relative_proposal.qbk
Normal file
964
doc/relative_proposal.qbk
Normal file
@@ -0,0 +1,964 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ http://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[template super[x]'''<superscript>'''[x]'''</superscript>''']
|
||||
[template sub[x]'''<subscript>'''[x]'''</subscript>''']
|
||||
|
||||
[h1 Filesystem Relative Proposal]
|
||||
|
||||
|
||||
|
||||
|
||||
[table
|
||||
|
||||
[
|
||||
[
|
||||
[@../../../index.htm
|
||||
[$../../../boost.png]]]
|
||||
[
|
||||
Filesystem Relative
|
||||
|
||||
Draft Proposal
|
||||
]
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
[table
|
||||
|
||||
[
|
||||
[[@index.htm Home]
|
||||
[@tutorial.html Tutorial]
|
||||
[@reference.html Reference]
|
||||
[@faq.htm FAQ]
|
||||
[@release_history.html Releases]
|
||||
[@portability_guide.htm Portability]
|
||||
[@v4.html V4]
|
||||
[@v3.html V3 Intro]
|
||||
[@v3_design.html V3 Design]
|
||||
[@deprecated.html Deprecated]
|
||||
[@issue_reporting.html Bug Reports ]
|
||||
]
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
[@#Introduction
|
||||
Introduction]
|
||||
|
||||
[@#Acknowledgement Acknowledgement]
|
||||
|
||||
[@#Preliminary-implementation Preliminary implementation]
|
||||
|
||||
[@#Requirements Requirements]
|
||||
|
||||
[@#Issues Issues]
|
||||
|
||||
[@#Design-decisions
|
||||
Design decisions]
|
||||
|
||||
[@#Provide-separate-relative Provide separate lexical and
|
||||
operational `relative` functions]
|
||||
|
||||
[@#Provide-separate-proximate Provide
|
||||
separate lexical and operational `proximate` functions]
|
||||
|
||||
[@#Add-lexical-functions Add lexical functions as `path` member functions]
|
||||
|
||||
[@#Provide-normal Provide a non-member function
|
||||
`lexically_normal` returning a
|
||||
normal form path]
|
||||
|
||||
[@#Provide-weakly Provide a `weakly_canonical` operational function]
|
||||
|
||||
[@#just-work Resolve issues in ways that "just work" for users]
|
||||
|
||||
[@#mismatch Specify `lexical relative` in terms
|
||||
of `std::mismatch`]
|
||||
|
||||
[@#Specify-op-rel-weakly Specify operational `relative` in terms of `
|
||||
weakly_canonical`]
|
||||
|
||||
[@#Specify-op-rel-lex-rel Specify operational `relative` in terms of
|
||||
`lexically
|
||||
relative`]
|
||||
|
||||
[@#Proposed-wording Proposed wording]
|
||||
|
||||
[@#Define-normal-form Define ['normal form]]
|
||||
|
||||
[@#New-class-path-member-functions New class path member functions]
|
||||
|
||||
[@#Synopsis-path Synopsis]
|
||||
|
||||
[@#Specification-path Specification]
|
||||
|
||||
[@#operational-functions New operational functions]
|
||||
|
||||
[@#Synopsis-ops Synopsis]
|
||||
|
||||
[@#Specification-ops Specification]
|
||||
|
||||
|
||||
|
||||
|
||||
[h2
|
||||
[#Introduction]Introduction]
|
||||
|
||||
|
||||
|
||||
|
||||
There have been requests for a Filesystem library relative function for at
|
||||
least ten years.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The requested functionality seems simple - given two paths with a common
|
||||
prefix, return the non-common suffix portion of one of the paths such that
|
||||
it is relative to the other path.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
In terms of the Filesystem library,
|
||||
|
||||
|
||||
|
||||
[:
|
||||
|
||||
```
|
||||
path p("/a/b/c");
|
||||
path base("/a/b");
|
||||
path rel = relative(p, base); // the requested function
|
||||
cout << rel << endl; // outputs "c"
|
||||
assert(absolute(rel, base) == p);
|
||||
```
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
If that was all there was to it, the Filesystem library would have had a
|
||||
`relative` function years ago.
|
||||
|
||||
|
||||
[:
|
||||
|
||||
|
||||
Blocking issues: Clashing requirements, symlinks, directory placeholders (['dot],
|
||||
['dot-dot]), user-expectations, corner cases.
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
[h3 [#Acknowledgement]Acknowledgement]
|
||||
|
||||
|
||||
|
||||
A paper by Jamie Allsop, ['Additions to Filesystem supporting Relative Paths],
|
||||
is what broke my mental logjam. Much of what follows is based directly on
|
||||
Jamie's analysis and proposal. The `weakly_canonical` function and
|
||||
aspects of the semantic specifications are my contributions. Mistakes, of
|
||||
course, are mine.
|
||||
|
||||
|
||||
|
||||
[h3 [#Preliminary-implementation]Preliminary implementation]
|
||||
|
||||
|
||||
|
||||
A preliminary implementation is available in the
|
||||
[@https://github.com/boostorg/filesystem/tree/feature/relative2
|
||||
feature/relative2] branch of the Boost Filesystem Git repository. See
|
||||
[@https://github.com/boostorg/filesystem/tree/feature/relative2
|
||||
github.com/boostorg/filesystem/tree/feature/relative2]
|
||||
|
||||
|
||||
|
||||
[h2 [#Requirements]Requirements]
|
||||
|
||||
|
||||
|
||||
[*[#Requirement-1]Requirement 1:] Some uses require symlinks be followed; i.e. the path must be resolved in
|
||||
the actual file system.
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Requirement-2]Requirement 2: ]Some uses require symlinks not be followed; i.e. the path must not be
|
||||
resolved in the actual file system.
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Requirement-3]Requirement 3: ]Some uses require removing redundant current directory (['dot])
|
||||
or parent directory (['dot-dot]) placeholders.
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Requirement-4]Requirement 4: ]Some uses do not require removing redundant current directory (['dot])
|
||||
or parent directory (['dot-dot]) placeholders since the path is known to be already in normal form.
|
||||
|
||||
|
||||
|
||||
[h2 [#Issues]Issues]
|
||||
|
||||
|
||||
|
||||
[*[#Issue-1]Issue 1:] What happens if `p`
|
||||
and `base` are themselves relative?
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Issue-2]Issue 2:] What happens if there is no common prefix? Is this an error, the whole of
|
||||
`p` is relative to `base`, or something else?
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Issue-3]Issue 3:] What happens if `p`, `base`, or both are empty?
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Issue-4]Issue 4:] What happens if `p` and `base` are the same?
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Issue-5]Issue 5:] How is the "common prefix" determined?
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Issue-6]Issue 6:] What happens if portions of `p` or `base` exist but
|
||||
the entire path does not exist and yet symlinks need to be followed?
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Issue-7]Issue 7:] What happens when a symlink in the existing portion of a path is affected
|
||||
by a directory (['dot-dot]) placeholder in a later non-existent portion of
|
||||
the path?
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Issue-8]Issue 8:] Overly complex semantics (and thus
|
||||
specifications) in preliminary designs made reasoning about uses difficult.
|
||||
|
||||
|
||||
|
||||
|
||||
[*[#Issue-9]Issue 9: ]Some uses never have redundant current directory (['dot])
|
||||
or parent directory (['dot-dot]) placeholders, so a removal operation
|
||||
would be an unnecessary expense although otherwise harmless.
|
||||
|
||||
|
||||
|
||||
|
||||
[h2
|
||||
[#Design-decisions]Design decisions]
|
||||
|
||||
|
||||
|
||||
[h4
|
||||
[#Provide-separate-relative]Provide separate lexical and
|
||||
operational `relative` functions]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Resolves the conflict between [@#Requirement-1 requirement 1]
|
||||
and [@#Requirement-2 requirement 2] and ensures both
|
||||
requirements are met.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
A purely lexical function is needed by users working with directory
|
||||
hierarchies that do not actually exist.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
An operational function that queries the current file system for existence
|
||||
and follows symlinks is needed by users working with actual existing
|
||||
directory hierarchies.
|
||||
|
||||
|
||||
|
||||
|
||||
[h4
|
||||
[#Provide-separate-proximate]Provide separate lexical and operational
|
||||
`proximate` functions]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Although not the only possibility, a likely fallback when the relative
|
||||
functions cannot find a relative path is to return the path being made relative. As
|
||||
a convenience, the `proximate` functions do just that.
|
||||
|
||||
|
||||
|
||||
|
||||
[h4
|
||||
[#Add-lexical-functions]Add lexical functions as
|
||||
`path` member functions]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The Filesystem library is unusual in that it has several functions with
|
||||
both lexical (i.e. cheap) and operational (i.e. expensive due to file
|
||||
system access) forms with differing semantics. It is important that users
|
||||
choose the form that meets their application's specific needs. The library
|
||||
has always made the distinction via the convention of lexical functions
|
||||
being members of class `path`, while operational functions are
|
||||
non-member functions. The lexical functions proposed here also use the
|
||||
name prefix `lexically_` to drive home the distinction.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
For the contrary argument, see Sutter and Alexandrescu, ['C++ Coding Standards], 44:
|
||||
"Prefer writing nonmember nonfriend functions", and Meyers, ['Effective C++ Third Edition], 23:
|
||||
"Prefer non-member non-friend functions to member functions."
|
||||
|
||||
|
||||
|
||||
|
||||
[h4
|
||||
[#Provide-normal]Provide[* ]a non-member function `
|
||||
[@#normal lexically_normal]` returning a
|
||||
[@#normal-form normal form] path]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Enables resolution of [@#Requirement-3 requirement 3] and
|
||||
[@#Requirement-4 requirement 4] in a way consistent with
|
||||
[@#Issue-9 issue 9]. Is a contributor to the resolution of
|
||||
[@#Issue-8 issue 8].
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"Normalization" is the process of removing redundant current directory (['dot])
|
||||
, parent
|
||||
directory (['dot-dot]), and directory separator elements.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Normalization is a byproduct the current `canonical` function.
|
||||
But for the path returned by the
|
||||
proposed `[@#weakly_canonical weakly_canonical]` function,
|
||||
only any leading canonic portion is in canonical form. So any trailing
|
||||
portion of the returned path has not been normalized.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Jamie Allsop has proposed adding a separate normalization function returning a
|
||||
path, and I agree with him.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Boost.filesystem has a deprecated non-const normalization function that
|
||||
modifies the path, but I agree with Jamie that a function returning a path
|
||||
is a better solution.
|
||||
|
||||
|
||||
|
||||
|
||||
[h4
|
||||
[#Provide-weakly]Provide[* ]a `[@#weakly_canonical weakly_canonical]` operational function]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Resolves [@#Issue-6 issue 6], [@#Issue-7 issue 7],
|
||||
[@#Issue-9 issue 9], and is a contributor to the resolution of
|
||||
[@#Issue-8 issue 8].
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The operational function
|
||||
`weakly_canonical(p)` returns a path composed of `
|
||||
canonical(x)/y`, where `x` is a path composed of the
|
||||
longest leading sequence of elements in `p` that exist, and
|
||||
`y` is a path composed of the remaining trailing non-existent elements of
|
||||
`p` if any. "`weakly`" refers to weakened existence
|
||||
requirements compared to the existing canonical function.
|
||||
|
||||
|
||||
|
||||
|
||||
* Having `weakly_canonical` as a separate function, and then
|
||||
specifying the processing of operational `relative` arguments in
|
||||
terms of calls to `weakly_canonical` makes it much easier to
|
||||
specify the operational `relative` function and reason about it.
|
||||
The difficulty of reasoning about operational `relative`
|
||||
semantics before the invention of `weakly_canonical` was what led to its
|
||||
initial development.
|
||||
* Having `weakly_canonical` as a separate function also allows
|
||||
use in other contexts.
|
||||
* Specifying the return be in [@#normal-form normal form] is an
|
||||
engineering trade-off to resolve [@#Issue-7 issue 7] in a way that
|
||||
just works for most use cases.
|
||||
* Specifying normative encouragement to not perform unneeded normalization
|
||||
is a reasonable resolution for [@#Issue-9 issue 9].
|
||||
|
||||
|
||||
|
||||
[h4
|
||||
Resolve issues in ways that "[#just-work]just work" for users]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Resolves issues [@#Issue-1 1], [@#Issue-2 2],
|
||||
[@#Issue-3 3], [@#Issue-4 4], [@#Issue-7 6],
|
||||
and [@#Issue-7 7]. Is a contributor to the resolution of
|
||||
[@#Issue-8 issue 8].
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The "just works" approach was suggested by Jamie Allsop. It is implemented
|
||||
by specifying a reasonable return value for all of the "What happens
|
||||
if..." corner case issues, rather that treating them as hard errors
|
||||
requiring an exception or error code.
|
||||
|
||||
|
||||
|
||||
|
||||
[h4
|
||||
Specify [@#lex-proximate `lexically relative`] in terms
|
||||
of `std::[#mismatch]mismatch`]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Resolves [@#Issue-5 issue 5]. Is a contributor to the
|
||||
resolution of [@#Issue-8 issue 8].
|
||||
|
||||
|
||||
|
||||
|
||||
[h4
|
||||
[#Specify-op-rel-weakly]Specify [@#op-proximate operational `relative`] in terms of `
|
||||
[@#weakly_canonical weakly_canonical]`]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Is a contributor to the resolution of [@#Issue-8 issue 8].
|
||||
|
||||
|
||||
|
||||
|
||||
* Covers a wide range of uses cases since a single function works for
|
||||
existing, non-existing, and partially existing paths.
|
||||
* Works correctly for partially existing paths that contain symlinks.
|
||||
|
||||
|
||||
|
||||
[h4
|
||||
[#Specify-op-rel-lex-rel]Specify [@#op-proximate operational `relative`] in terms of
|
||||
[@#lex-proximate `lexically
|
||||
relative`]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Is a contributor to the resolution of [@#Issue-5 issue 5] and
|
||||
[@#Issue-8 issue 8].
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
If would be confusing to users and difficult to specify correctly if the
|
||||
two functions had differing semantics:
|
||||
|
||||
|
||||
|
||||
* When either or both paths are empty.
|
||||
* When all elements of the two paths match exactly.
|
||||
* Because different matching algorithms were used.
|
||||
* Because although the same matching algorithm was used, it was applied in different ways.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
These problems are avoided by specifying operational `relative`
|
||||
in terms of lexical `relative` after preparatory
|
||||
calls to operational functions.
|
||||
|
||||
|
||||
|
||||
|
||||
[h2 [#Proposed-wording]Proposed wording]
|
||||
|
||||
|
||||
|
||||
|
||||
['"Overview:" sections below are
|
||||
non-normative experiments attempting to make the normative reference
|
||||
specifications easier to grasp.]
|
||||
|
||||
|
||||
|
||||
|
||||
[h3 [#Define-normal-form]Define ['normal form]]
|
||||
|
||||
|
||||
|
||||
|
||||
A path is in [*['[#normal-form]normal form]] if it has no
|
||||
redundant current directory (['dot]) or parent directory (['dot-dot])
|
||||
elements. The normal form for an empty path is an empty path. The normal form
|
||||
for a path ending in a ['directory-separator] that is not the root directory
|
||||
is the same path with a current directory (['dot]) element appended.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
['The last sentence above is not
|
||||
necessary for POSIX-like or Windows-like operating systems, but supports systems
|
||||
like OpenVMS that use different syntax for directory and regular-file names.]
|
||||
|
||||
|
||||
|
||||
|
||||
[h3 [#New-class-path-member-functions]New class path member functions]
|
||||
|
||||
|
||||
|
||||
[h4 [#Synopsis-path]Synopsis]
|
||||
|
||||
|
||||
|
||||
```
|
||||
path lexically_normal() const;
|
||||
path lexically_relative(const path& base) const;
|
||||
path lexically_proximate(const path& base) const;
|
||||
```
|
||||
|
||||
|
||||
|
||||
[h4 [#Specification-path]Specification]
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
path [#lex-normal]lexically_normal() const;
|
||||
```
|
||||
|
||||
[:
|
||||
|
||||
|
||||
['Overview:] Returns `*this` with redundant current directory
|
||||
(['dot]), parent directory (['dot-dot]), and ['directory-separator] elements removed.
|
||||
|
||||
|
||||
|
||||
|
||||
['Returns:] `*this` in [@#normal-form normal form].
|
||||
|
||||
|
||||
|
||||
|
||||
['Remarks:] Uses `operator/=` to compose the returned path.
|
||||
|
||||
|
||||
|
||||
|
||||
\[['Example:]
|
||||
|
||||
|
||||
|
||||
|
||||
`assert(path("foo/./bar/..").lexically_normal() == "foo");
|
||||
|
||||
assert(path("foo/.///bar/../").lexically_normal() == "foo/.");`
|
||||
|
||||
|
||||
|
||||
|
||||
The above assertions will succeed.[' ]On Windows, the
|
||||
returned path's ['directory-separator] characters will be backslashes rather than slashes, but that
|
||||
does not affect `path` equality.[' —end example]\]
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
path [#lex-relative]lexically_relative(const path& base) const;
|
||||
```
|
||||
|
||||
[:
|
||||
|
||||
|
||||
['Overview:] Returns `*this` made relative to `base`.
|
||||
Treats empty or identical paths as corner cases, not errors. Does not resolve
|
||||
symlinks. Does not first normalize `*this` or `base`.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
['Remarks:] Uses `std::mismatch(begin(), end(), base.begin(), base.end())`, to determine the first mismatched element of
|
||||
`*this` and `base`. Uses `operator==` to
|
||||
determine if elements match.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
['Returns:]
|
||||
|
||||
|
||||
|
||||
|
||||
*
|
||||
`path()` if the first mismatched element of `*this` is equal to `
|
||||
begin()` or the first mismatched element
|
||||
of `base` is equal to `base.begin()`, or
|
||||
|
||||
|
||||
*
|
||||
`path(".")` if the first mismatched element of `
|
||||
*this` is equal to `
|
||||
end()` and the first mismatched element
|
||||
of `base` is equal to `base.end()`, or
|
||||
|
||||
|
||||
* An object of class `path` composed via application of `
|
||||
operator/= path("..")` for each element in the half-open
|
||||
range \[first
|
||||
mismatched element of `base`, `base.end()`), and then
|
||||
application of `operator/=` for each element in the half-open
|
||||
range
|
||||
\[first mismatched element of `*this`, `end()`).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\[['Example:]
|
||||
|
||||
|
||||
|
||||
|
||||
`assert(path("/a/d").lexically_relative("/a/b/c") == "../../d");
|
||||
|
||||
assert(path("/a/b/c").lexically_relative("/a/d") == "../b/c");
|
||||
|
||||
assert(path("a/b/c").lexically_relative("a") == "b/c");
|
||||
|
||||
assert(path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");
|
||||
|
||||
assert(path("a/b/c").lexically_relative("a/b/c") == ".");
|
||||
|
||||
assert(path("a/b").lexically_relative("c/d") == "");`
|
||||
|
||||
|
||||
|
||||
|
||||
The above assertions will succeed.[' ]On Windows, the
|
||||
returned path's ['directory-separator]s will be backslashes rather than
|
||||
forward slashes, but that
|
||||
does not affect `path` equality.[' —end example]\]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\[['Note:] If symlink following semantics are desired, use the operational function `
|
||||
[@#op-proximate relative]` ['—end note]\]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\[['Note:] If [@#normal normalization] is needed to ensure
|
||||
consistent matching of elements, apply `[@#normal lexically_normal()]`
|
||||
to `*this`, `base`, or both. ['—end note]\]
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
path [#lex-proximate]lexically_proximate(const path& base) const;
|
||||
```
|
||||
|
||||
|
||||
[:
|
||||
|
||||
|
||||
|
||||
['Returns:] If the value of `lexically_relative(base)` is
|
||||
not an empty path, return it. Otherwise return `*this`.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\[['Note:] If symlink following semantics are desired, use the operational function
|
||||
`[@#op-proximate proximate]` ['—end note]\]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\[['Note:] If [@#normal normalization] is needed to ensure
|
||||
consistent matching of elements, apply `[@#normal lexically_normal()]`
|
||||
to `*this`, `base`, or both. ['—end note]\]
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[h3 New [#operational-functions]operational functions]
|
||||
|
||||
|
||||
|
||||
|
||||
[h4 [#Synopsis-ops]Synopsis]
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
path weakly_canonical(const path& p);
|
||||
path weakly_canonical(const path& p, system::error_code& ec);
|
||||
path relative(const path& p, system::error_code& ec);
|
||||
path relative(const path& p, const path& base=current_path());
|
||||
path relative(const path& p, const path& base, system::error_code& ec);
|
||||
path proximate(const path& p, system::error_code& ec);
|
||||
path proximate(const path& p, const path& base=current_path());
|
||||
path proximate(const path& p, const path& base, system::error_code& ec);
|
||||
|
||||
```
|
||||
|
||||
|
||||
[h4 [#Specification-ops]Specification]
|
||||
|
||||
|
||||
|
||||
```
|
||||
path [#weakly_canonical]weakly_canonical(const path& p);
|
||||
path weakly_canonical(const path& p, system::error_code& ec);
|
||||
```
|
||||
|
||||
[:
|
||||
['Overview:] Returns `p` with symlinks resolved and the result
|
||||
normalized.
|
||||
|
||||
|
||||
['Returns: ]
|
||||
A path composed of the result of calling the `canonical` function on
|
||||
a path composed of the leading elements of `p` that exist, if any,
|
||||
followed by the elements of `p` that do not exist, if any.
|
||||
|
||||
|
||||
|
||||
|
||||
['Postcondition:] The returned path is in [@#normal normal form].
|
||||
|
||||
|
||||
|
||||
|
||||
['Remarks:] Uses `operator/=` to compose the returned path.
|
||||
Uses the `status` function to determine existence.
|
||||
|
||||
|
||||
|
||||
|
||||
['Remarks:] Implementations are encouraged to avoid unnecessary
|
||||
normalization such as when `canonical` has already been called on the
|
||||
entirety of `p`.
|
||||
|
||||
|
||||
|
||||
|
||||
['Throws:] As specified in Error reporting.
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
```
|
||||
path [#op-relative]relative(const path& p, system::error_code& ec);
|
||||
```
|
||||
|
||||
[:
|
||||
|
||||
|
||||
['Returns:] `relative(p, current_path(), ec)`.
|
||||
|
||||
|
||||
|
||||
|
||||
['Throws:] As specified in Error reporting.
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
```
|
||||
path relative(const path& p, const path& base=current_path());
|
||||
path relative(const path& p, const path& base, system::error_code& ec);
|
||||
```
|
||||
|
||||
[:
|
||||
|
||||
|
||||
['Overview:] Returns `p` made relative to `
|
||||
base`. Treats empty or identical paths as corner cases, not errors.
|
||||
Resolves symlinks and normalizes both `p` and `base`
|
||||
before other processing.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
['Returns:] `[@#weakly_canonical weakly_canonical](p).l[@#lex-proximate exically_relative]([@#weakly_canonical weakly_canonical](base))`. The second form returns `path()` if an error occurs.
|
||||
|
||||
|
||||
|
||||
|
||||
['Throws:] As specified in Error reporting.
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
path [#op-proximate]proximate(const path& p, system::error_code& ec);
|
||||
```
|
||||
|
||||
[:
|
||||
|
||||
|
||||
['Returns:] `proximate(p, current_path(), ec)`.
|
||||
|
||||
|
||||
|
||||
|
||||
['Throws:] As specified in Error reporting.
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
```
|
||||
path proximate(const path& p, const path& base=current_path());
|
||||
path proximate(const path& p, const path& base, system::error_code& ec);
|
||||
```
|
||||
|
||||
[:
|
||||
|
||||
|
||||
|
||||
['Returns:] `[@#weakly_canonical weakly_canonical](p).l[@#lex-proximate exically_proximate]([@#weakly_canonical weakly_canonical](base))`. The second form returns `path()` if an error occurs.
|
||||
|
||||
|
||||
|
||||
|
||||
['Throws:] As specified in Error reporting.
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
© Copyright Beman Dawes 2015
|
||||
|
||||
|
||||
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. See
|
||||
[@http://www.boost.org/LICENSE_1_0.txt www.boost.org/LICENSE_1_0.txt]
|
||||
|
||||
|
||||
|
||||
835
doc/tutorial.qbk
Normal file
835
doc/tutorial.qbk
Normal file
@@ -0,0 +1,835 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ https://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:tutorial Tutorial]
|
||||
|
||||
[section:introduction Introduction]
|
||||
|
||||
This tutorial develops a little command line program to list information about files and directories - essentially
|
||||
a much simplified version of the POSIX `ls` or Windows `dir` commands. We'll start with the simplest possible version
|
||||
and progress to more complex functionality. Along the way we'll digress to cover topics you'll need to know about
|
||||
to understand Boost.Filesystem.
|
||||
|
||||
Source code for each of the tutorial programs is available, and you are encouraged to compile, test, and experiment
|
||||
with it. To conserve space, we won't always show boilerplate code here, but the provided source is complete and
|
||||
ready to build.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:preliminaries Preliminaries]
|
||||
|
||||
Install the Boost distribution if you haven't already done so. See the [link filesystem.install.building building
|
||||
instructions].
|
||||
|
||||
This tutorial assumes you have bootstrapped Boost.Build and compiled Boost.Filesystem as described in the building
|
||||
instructions. The `b2` executable is expected to be available in `PATH`. In the code samples below, ['[*boost-root]]
|
||||
denotes the root directory of your Boost installation tree.
|
||||
|
||||
Fire up your command line interpreter, and type the following commands:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ cd ['[*boost-root]]\/libs\/filesystem\/example
|
||||
|
||||
$ b2 tutorial
|
||||
Compiling example programs...
|
||||
|
||||
$ .\/tut1
|
||||
Usage: tut1 path
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>cd ['[*boost-root]]\\libs\\filesystem\\example
|
||||
|
||||
>b2.exe tutorial
|
||||
Compiling example programs...
|
||||
|
||||
>tut1
|
||||
Usage: tut1 path
|
||||
]
|
||||
]]
|
||||
]
|
||||
|
||||
If the `tut1` command outputs "`Usage: tut1 path`", all is well. The tutorial example programs are available in
|
||||
[^['[*boost-root]]\/libs\/filesystem\/example]. Should you modify and experiment with them as the tutorial progresses,
|
||||
just invoke `b2 tutorial` again to rebuild.
|
||||
|
||||
If something didn't work right, here are some troubleshooting suggestions:
|
||||
|
||||
* If the `b2` program executable isn't being found, check your path environmental variable or see
|
||||
[@https://www.boost.org/more/getting_started/windows.html Boost Getting Started].
|
||||
* Look at Boost bootstrap output to try to spot an indication of the problem.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:reporting-size Reporting the size of a file]
|
||||
|
||||
Let's get started. Our first example program, [@../example/tut1.cpp `tut1.cpp`], reports the size of a file:
|
||||
|
||||
[import ../example/tut1.cpp]
|
||||
[example_tut1]
|
||||
|
||||
The Boost.Filesystem [link filesystem.reference.file_size `file_size`] function returns a `uintmax_t`
|
||||
containing the size of the file named by the argument. The declaration looks like this:
|
||||
|
||||
```
|
||||
uintmax_t file_size(const path& p);
|
||||
```
|
||||
|
||||
For now, all you need to know is that `class path` has constructors that take `const char *` and other
|
||||
string types. (If you can't wait to find out more, skip ahead to the [link filesystem.tutorial.class-path-constructors class path]
|
||||
section of the tutorial.)
|
||||
|
||||
Please take a minute to try out `tut1` on your system, using a file that is known to exist, such as `tut1.cpp`.
|
||||
Here is what the results look like on two different operating systems:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ .\/tut1 tut1.cpp
|
||||
tut1.cpp 569
|
||||
|
||||
$ ls -l tut1.cpp
|
||||
-rw-rw-r-- 1 beman beman 569 Jul 26 12:04 tut1.cpp
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>tut1 tut1.cpp
|
||||
tut1.cpp 592
|
||||
|
||||
>dir tut1.cpp
|
||||
...
|
||||
07\/26\/2015 07:20 AM 592 tut1.cpp
|
||||
...
|
||||
]
|
||||
]]
|
||||
]
|
||||
|
||||
So far, so good. The reported Linux and Windows sizes are different because the Linux tests used "\\n"
|
||||
line endings, while the Windows tests used "\\r\\n" line endings. The sizes reported may differ from
|
||||
the above if changes have been made to `tut1.cpp`.
|
||||
|
||||
Now try again, but give a path that doesn't exist:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ .\/tut1 foo
|
||||
terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
|
||||
what(): boost::filesystem::file_size: No such file or directory: "foo"
|
||||
Aborted (core dumped)
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>tut1 foo
|
||||
]
|
||||
|
||||
['An exception is thrown; the exact form of the response depends on Windows system options.]
|
||||
]]
|
||||
]
|
||||
|
||||
What happens? There's no file named `foo` in the current directory, so by default an exception
|
||||
is thrown. See [link filesystem.tutorial.error-reporting Error reporting] to learn about error reporting
|
||||
via error codes rather than exceptions.
|
||||
|
||||
Try this:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ .\/tut1 .
|
||||
terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
|
||||
what(): boost::filesystem::file_size: Operation not permitted: "."
|
||||
Aborted (core dumped)
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>tut1 .
|
||||
]
|
||||
|
||||
['An exception is thrown; the exact form of the response depends on Windows system options.]
|
||||
]]
|
||||
]
|
||||
|
||||
The current directory exists, but `file_size()` works on regular files, not directories, so again
|
||||
an exception is thrown.
|
||||
|
||||
We'll deal with those situations in `tut2.cpp`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:using-status-queries Using status queries to determine file existence and type]
|
||||
|
||||
Boost.Filesystem includes status query functions such as [link filesystem.reference.exists-path `exists`],
|
||||
[link filesystem.reference.is_directory-path `is_directory`], and [link filesystem.reference.is_regular_file-path `is_regular_file`].
|
||||
These return `bool`s, and will return `true` if the condition described by their name is met. Otherwise they
|
||||
return `false`, including when any element of the path argument can't be found.
|
||||
|
||||
[@../example/tut2.cpp `tut2.cpp`] uses several of the status query functions to cope with non-existent
|
||||
files and with different kinds of files:
|
||||
|
||||
[import ../example/tut2.cpp]
|
||||
[example_tut2]
|
||||
|
||||
Give it a try:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ .\/tut2 tut2.cpp
|
||||
"tut2.cpp" size is 997
|
||||
|
||||
$ .\/tut2 foo
|
||||
"foo" does not exist
|
||||
|
||||
$ .\/tut2 .
|
||||
"." is a directory
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>tut2 tut2.cpp
|
||||
tut2.cpp size is 1039
|
||||
|
||||
>tut2 foo
|
||||
"foo" does not exist
|
||||
|
||||
>tut2 .
|
||||
"." is a directory
|
||||
]
|
||||
]]
|
||||
]
|
||||
|
||||
Although `tut2` works OK in these tests, the output is less than satisfactory for a directory. We'd typically
|
||||
like to see a list of the directory's contents. In `tut3.cpp` we will see how to iterate over directories.
|
||||
|
||||
But first, let's try one more test:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ ls \/home\/jane\/foo
|
||||
ls: cannot access \/home\/jane\/foo: No such file or directory
|
||||
|
||||
$ .\/tut2 \/home\/jane\/foo
|
||||
terminate called after throwing an instance of 'boost::
|
||||
filesystem::filesystem_error>'
|
||||
what(): boost::filesystem::status: Permission denied:
|
||||
"\/home\/jane\/foo"
|
||||
Aborted
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>dir e:\\
|
||||
The device is not ready.
|
||||
|
||||
>tut2 e:\\
|
||||
]
|
||||
|
||||
['An exception is thrown; the exact form of the response depends on Windows system options.]
|
||||
]]
|
||||
]
|
||||
|
||||
On the Linux system, the test was being run from an account that did not have permission to access
|
||||
[^\/home\/jane\/foo]. On the Windows system, [^e:] was a Compact Disc reader\/writer that was not ready. End users
|
||||
shouldn't have to interpret cryptic exceptions reports, so as we move on to `tut3.cpp` we will increase
|
||||
the robustness of the code, too.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:directory-iteration Directory iteration plus catching exceptions]
|
||||
|
||||
Boost.Filesystem's [link filesystem.reference.directory_iterator `directory_iterator`] class is just
|
||||
what we need here. It follows the general pattern of the standard library's `istream_iterator`. Constructed
|
||||
from a path, it iterates over the contents of the directory. A default constructed `directory_iterator`
|
||||
acts as the end iterator.
|
||||
|
||||
The value type of `directory_iterator` is [link filesystem.reference.directory_entry `directory_entry`].
|
||||
A `directory_entry` object contains `path` and [link filesystem.reference.file_status `file_status`]
|
||||
information. A `directory_entry` object can be used directly, but can also be passed to `path` arguments
|
||||
in function calls.
|
||||
|
||||
The other need is increased robustness in the face of the many kinds of errors that can affect file system
|
||||
operations. We could do that at the level of each call to a Boost.Filesystem function (see
|
||||
[link filesystem.tutorial.error-reporting Error reporting]), but for simplicity [@../example/tut3.cpp
|
||||
`tut3.cpp`] uses an overall `try`\/`catch` block.
|
||||
|
||||
[import ../example/tut3.cpp]
|
||||
[example_tut3]
|
||||
|
||||
Give `tut3` a try, passing it a path to a directory as a command line argument. Here is a run on a checkout
|
||||
of the Boost Git develop branch, followed by a repeat of the test cases that caused exceptions on Linux and
|
||||
Windows:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ .\/tut3 ~\/boost\/develop
|
||||
"\/home\/beman\/boost\/develop" is a directory containing:
|
||||
"\/home\/beman\/boost\/develop\/rst.css"
|
||||
"\/home\/beman\/boost\/develop\/boost"
|
||||
"\/home\/beman\/boost\/develop\/boost.png"
|
||||
"\/home\/beman\/boost\/develop\/libs"
|
||||
"\/home\/beman\/boost\/develop\/doc"
|
||||
"\/home\/beman\/boost\/develop\/project-config.jam.2"
|
||||
"\/home\/beman\/boost\/develop\/.gitmodules"
|
||||
"\/home\/beman\/boost\/develop\/boostcpp.py"
|
||||
"\/home\/beman\/boost\/develop\/.travis.yml"
|
||||
"\/home\/beman\/boost\/develop\/.gitattributes"
|
||||
"\/home\/beman\/boost\/develop\/index.htm"
|
||||
"\/home\/beman\/boost\/develop\/index.html"
|
||||
"\/home\/beman\/boost\/develop\/bjam"
|
||||
"\/home\/beman\/boost\/develop\/project-config.jam.1"
|
||||
"\/home\/beman\/boost\/develop\/LICENSE_1_0.txt"
|
||||
"\/home\/beman\/boost\/develop\/.git"
|
||||
"\/home\/beman\/boost\/develop\/tools"
|
||||
"\/home\/beman\/boost\/develop\/stage"
|
||||
"\/home\/beman\/boost\/develop\/boostcpp.jam"
|
||||
"\/home\/beman\/boost\/develop\/Jamroot"
|
||||
"\/home\/beman\/boost\/develop\/.gitignore"
|
||||
"\/home\/beman\/boost\/develop\/INSTALL"
|
||||
"\/home\/beman\/boost\/develop\/more"
|
||||
"\/home\/beman\/boost\/develop\/bin.v2"
|
||||
"\/home\/beman\/boost\/develop\/project-config.jam"
|
||||
"\/home\/beman\/boost\/develop\/boost-build.jam"
|
||||
"\/home\/beman\/boost\/develop\/bootstrap.bat"
|
||||
"\/home\/beman\/boost\/develop\/bootstrap.sh"
|
||||
"\/home\/beman\/boost\/develop\/status"
|
||||
"\/home\/beman\/boost\/develop\/boost.css"
|
||||
|
||||
$ .\/tut3 \/home\/jane\/foo
|
||||
boost::filesystem::status: Permission denied: "\/home\/jane\/foo"
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>tut3 \\boost\\develop
|
||||
"\\boost\\develop" is a directory containing:
|
||||
"\\boost\\develop\\.git"
|
||||
"\\boost\\develop\\.gitattributes"
|
||||
"\\boost\\develop\\.gitignore"
|
||||
"\\boost\\develop\\.gitmodules"
|
||||
"\\boost\\develop\\.travis.yml"
|
||||
"\\boost\\develop\\bin.v2"
|
||||
"\\boost\\develop\\boost"
|
||||
"\\boost\\develop\\boost-build.jam"
|
||||
"\\boost\\develop\\boost.css"
|
||||
"\\boost\\develop\\boost.png"
|
||||
"\\boost\\develop\\boostcpp.jam"
|
||||
"\\boost\\develop\\boostcpp.py"
|
||||
"\\boost\\develop\\bootstrap.bat"
|
||||
"\\boost\\develop\\bootstrap.sh"
|
||||
"\\boost\\develop\\doc"
|
||||
"\\boost\\develop\\index.htm"
|
||||
"\\boost\\develop\\index.html"
|
||||
"\\boost\\develop\\INSTALL"
|
||||
"\\boost\\develop\\Jamroot"
|
||||
"\\boost\\develop\\libs"
|
||||
"\\boost\\develop\\LICENSE_1_0.txt"
|
||||
"\\boost\\develop\\more"
|
||||
"\\boost\\develop\\project-config.jam"
|
||||
"\\boost\\develop\\rst.css"
|
||||
"\\boost\\develop\\stage"
|
||||
"\\boost\\develop\\status"
|
||||
"\\boost\\develop\\tools"
|
||||
|
||||
>tut3 e:\\
|
||||
boost::filesystem::status: The device is not ready: "e:\\"
|
||||
]
|
||||
]]
|
||||
]
|
||||
|
||||
Not bad, but we can make further improvements:
|
||||
|
||||
* The listing would be much easier to read if only the filename was displayed, rather than the full path.
|
||||
* The Linux listing isn't sorted. That's because the ordering of directory iteration is unspecified.
|
||||
Ordering depends on the underlying operating system API and file system specifics. So we need to sort the
|
||||
results ourselves.
|
||||
|
||||
The next sections show how those changes play out, so read on!
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:using-path-decomposition Using path decomposition, plus sorting results]
|
||||
|
||||
For directories, [@../example/tut4.cpp `tut4.cpp`] builds a `std::vector` of all the entries and then sorts
|
||||
it before writing to `std::cout`.
|
||||
|
||||
[import ../example/tut4.cpp]
|
||||
[example_tut4]
|
||||
|
||||
The only difference between `tut3.cpp` and `tut4.cpp` is what happens for directories. We changed:
|
||||
|
||||
```
|
||||
for (directory_entry const& x : directory_iterator(p))
|
||||
std::cout << " " << x.path() << std::endl;
|
||||
```
|
||||
|
||||
to:
|
||||
|
||||
```
|
||||
std::vector<path> v;
|
||||
|
||||
for (auto&& x : directory_iterator(p))
|
||||
v.push_back(x.path());
|
||||
|
||||
std::sort(v.begin(), v.end());
|
||||
|
||||
for (auto&& x : v)
|
||||
std::cout << " " << x.filename() << std::endl;
|
||||
```
|
||||
|
||||
[member path::filename] is one of several class `path` decomposition functions. It extracts the filename portion
|
||||
from a path (i.e. [^"index.html"] from [^"\/home\/beman\/boost\/trunk\/index.html"]). These decomposition functions
|
||||
are more fully explored in the [link filesystem.tutorial.path-iterators-etc Path iterators, observers, composition,
|
||||
decomposition and query] portion of this tutorial.
|
||||
|
||||
The above was written as two lines of code for clarity. It could have been written more concisely as:
|
||||
|
||||
```
|
||||
v.push_back(it->path().filename()); // we only care about the filename
|
||||
```
|
||||
|
||||
Here is the output from a test of [@../example/tut4.cpp `tut4.cpp`]:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ .\/tut4 ~\/boost\/develop
|
||||
"\/home\/beman\/boost\/develop" is a directory containing:
|
||||
".git"
|
||||
".gitattributes"
|
||||
".gitignore"
|
||||
".gitmodules"
|
||||
".travis.yml"
|
||||
"INSTALL"
|
||||
"Jamroot"
|
||||
"LICENSE_1_0.txt"
|
||||
"bin.v2"
|
||||
"boost"
|
||||
"boost-build.jam"
|
||||
"boost.css"
|
||||
"boost.png"
|
||||
"boostcpp.jam"
|
||||
"boostcpp.py"
|
||||
"bootstrap.bat"
|
||||
"bootstrap.sh"
|
||||
"doc"
|
||||
"index.htm"
|
||||
"index.html"
|
||||
"libs"
|
||||
"more"
|
||||
"project-config.jam"
|
||||
"project-config.jam.1"
|
||||
"project-config.jam.2"
|
||||
"rst.css"
|
||||
"stage"
|
||||
"status"
|
||||
"tools"
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>tut4 \\boost\\develop
|
||||
"\\boost\\develop" is a directory containing:
|
||||
".git"
|
||||
".gitattributes"
|
||||
".gitignore"
|
||||
".gitmodules"
|
||||
".travis.yml"
|
||||
"INSTALL"
|
||||
"Jamroot"
|
||||
"LICENSE_1_0.txt"
|
||||
"bin.v2"
|
||||
"boost"
|
||||
"boost-build.jam"
|
||||
"boost.css"
|
||||
"boost.png"
|
||||
"boostcpp.jam"
|
||||
"boostcpp.py"
|
||||
"bootstrap.bat"
|
||||
"bootstrap.sh"
|
||||
"doc"
|
||||
"index.htm"
|
||||
"index.html"
|
||||
"libs"
|
||||
"more"
|
||||
"project-config.jam"
|
||||
"project-config.jam.1"
|
||||
"project-config.jam.2"
|
||||
"rst.css"
|
||||
"stage"
|
||||
"status"
|
||||
"tools"
|
||||
]
|
||||
]]
|
||||
]
|
||||
|
||||
That completes the main portion of this tutorial. If you haven't already worked through the
|
||||
[link filesystem.tutorial.class-path-constructors Class path] sections of this tutorial, dig into them now.
|
||||
The [link filesystem.tutorial.error-reporting Error reporting] section may also be of interest, although it can be
|
||||
skipped unless you are deeply concerned about error handling issues.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:class-path-constructors Class path: Constructors, including Unicode]
|
||||
|
||||
Traditional C interfaces pass paths as `const char*` arguments. C++ interfaces may add `const std::string&` overloads,
|
||||
but adding overloads becomes untenable if wide characters, containers, and iterator ranges need to be supported.
|
||||
|
||||
Passing paths as `const path&` arguments is far simpler, yet far more flexible because class `path` itself is far more flexible:
|
||||
|
||||
# Class `path` supports multiple character types and encodings, including Unicode, to ease internationalization.
|
||||
# Class `path` supports multiple source types, such as null terminated character sequences, iterator ranges, string class types
|
||||
(including `std::basic_string` and `std::basic_string_view`), and [link filesystem.reference.class-directory_entry
|
||||
`directory_entry`]s, so functions taking paths don't need to provide several overloads.
|
||||
# Class `path` supports both native and generic pathname formats, so programs can be portable between operating systems
|
||||
yet use native formats where desirable.
|
||||
# Class `path` supplies a full set of iterators, observers, composition, decomposition, and query functions, making pathname
|
||||
manipulations easy, convenient, reliable, and portable.
|
||||
|
||||
Here is how (1) and (2) work. Class path constructors, assignments, and appends have member templates for sources. For example,
|
||||
here are the constructors that take sources:
|
||||
|
||||
```
|
||||
template <class Source>
|
||||
path(Source const& source);
|
||||
|
||||
template <class InputIterator>
|
||||
path(InputIterator begin, InputIterator end);
|
||||
```
|
||||
|
||||
Let's look at [@../example/tut5.cpp `tut5.cpp`] sample program that shows how comfortable class `path` is with both narrow
|
||||
and wide characters in C-style strings, C++ strings, and via C++ iterators:
|
||||
|
||||
[import ../example/tut5.cpp]
|
||||
[example_tut5]
|
||||
|
||||
Testing `tut5`:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ .\/tut5
|
||||
|
||||
$ ls smile*
|
||||
smile smile☺ smile2 smile2☺ smile3 smile3☺ smile4 smile4☺
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>tut5
|
||||
|
||||
>dir \/b smile*
|
||||
smile
|
||||
smile2
|
||||
smile2☺
|
||||
smile3
|
||||
smile3☺
|
||||
smile4
|
||||
smile4☺
|
||||
smile☺
|
||||
]
|
||||
]]
|
||||
]
|
||||
|
||||
The exact appearance of the smiling face will depend on the font, font size, and other settings for your command line
|
||||
window. The above tests were run with out-of-the-box Ubuntu 14.04 and Windows 7, US Edition. If you don't get the above
|
||||
results, take a look at the [^['[*boost-root]]\/libs\/filesystem\/example] directory with your system's GUI file browser,
|
||||
such as Linux Nautilus, Mac OS X Finder, or Windows Explorer. These tend to be more comfortable with international
|
||||
character sets than command line interpreters.
|
||||
|
||||
Class `path` takes care of whatever character type or encoding conversions are required by the particular operating system.
|
||||
Thus as `tut5` demonstrates, it's no problem to pass a wide character string to a Boost.Filesystem operational function
|
||||
even if the underlying operating system uses narrow characters, and visa versa. And the same applies to user supplied
|
||||
functions that take `const path&` arguments.
|
||||
|
||||
Class `path` also provides path syntax that is portable across operating systems, element iterators, and observer,
|
||||
composition, decomposition, and query functions to manipulate the elements of a path. The next section of this
|
||||
tutorial deals with path syntax.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:class-path-formats Class path: Generic format vs. Native format]
|
||||
|
||||
Class `path` deals with two different pathname formats - generic format and native format. For POSIX-like file systems,
|
||||
these formats are the same. But for users of Windows and other non-POSIX file systems, the distinction is important. Even
|
||||
programmers writing for POSIX-like systems need to understand the distinction if they want their code to be portable
|
||||
to non-POSIX systems.
|
||||
|
||||
The [*generic format] is the familiar [^\/my_directory\/my_file.txt] format used by POSIX-like operating systems such as
|
||||
the Unix variants, Linux, and Mac OS X. Windows also recognizes the generic format, and it is the basis for the familiar
|
||||
Internet URL format. The directory separator character is always one or more slash characters.
|
||||
|
||||
The [*native format] is the format as defined by the particular operating system. For Windows, either the slash or
|
||||
the backslash can be used as the directory separator character, so [^\/my_directory\\\\my_file.txt] would work fine. Of
|
||||
course, if you write that in a C++ string literal, it becomes `"/my_directory\\\\my_file.txt"`.
|
||||
|
||||
If a drive specifier or a backslash appears in a pathname on a Windows system, it is always treated as the native format.
|
||||
|
||||
Class `path` has observer functions that allow you to obtain the string representation of a path object in either the native
|
||||
format or the generic format. See the [link filesystem.tutorial.path-iterators-etc next section] for how that plays out.
|
||||
|
||||
The distinction between generic format and native format is important when communicating with native C-style API's and
|
||||
with users. Both tend to expect paths in the native format and may be confused by the generic format. The generic format
|
||||
is great, however, for writing portable programs that work regardless of operating system.
|
||||
|
||||
The next section covers class `path` observers, composition, decomposition, query, and iteration over the elements of a path.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:path-iterators-etc Class path: Iterators, observers, composition, decomposition, and query]
|
||||
|
||||
The [@../example/path_info.cpp `path_info.cpp`] program is handy for learning how class `path` iterators, observers,
|
||||
composition, decomposition, and query functions work on your system.
|
||||
|
||||
[import ../example/path_info.cpp]
|
||||
[example_path_info]
|
||||
|
||||
Run the examples below on your system, and try some different path arguments as we go along. Here is the invocation
|
||||
we will talk about in detail:
|
||||
|
||||
[table
|
||||
[[Ubuntu Linux] [Microsoft Windows]]
|
||||
[[
|
||||
[pre
|
||||
$ .\/path_info \/foo bar baa.txt
|
||||
|
||||
composed path:
|
||||
operator<<()---------: "\/foo\/bar\/baa.txt"
|
||||
make_preferred()-----: "\/foo\/bar\/baa.txt"
|
||||
|
||||
elements:
|
||||
"\/"
|
||||
"foo"
|
||||
"bar"
|
||||
"baa.txt"
|
||||
|
||||
observers, native format:
|
||||
native()-------------: \/foo\/bar\/baa.txt
|
||||
c_str()--------------: \/foo\/bar\/baa.txt
|
||||
string()-------------: \/foo\/bar\/baa.txt
|
||||
wstring()------------: \/foo\/bar\/baa.txt
|
||||
|
||||
observers, generic format:
|
||||
generic_string()-----: \/foo\/bar\/baa.txt
|
||||
generic_wstring()----: \/foo\/bar\/baa.txt
|
||||
|
||||
decomposition:
|
||||
root_name()----------: ""
|
||||
root_directory()-----: "\/"
|
||||
root_path()----------: "\/"
|
||||
relative_path()------: "foo\/bar\/baa.txt"
|
||||
parent_path()--------: "\/foo\/bar"
|
||||
filename()-----------: "baa.txt"
|
||||
stem()---------------: "baa"
|
||||
extension()----------: ".txt"
|
||||
|
||||
query:
|
||||
empty()--------------: false
|
||||
is_absolute()--------: true
|
||||
has_root_name()------: false
|
||||
has_root_directory()-: true
|
||||
has_root_path()------: true
|
||||
has_relative_path()--: true
|
||||
has_parent_path()----: true
|
||||
has_filename()-------: true
|
||||
has_stem()-----------: true
|
||||
has_extension()------: true
|
||||
]
|
||||
]
|
||||
[
|
||||
[pre
|
||||
>path_info \\foo bar baa.txt
|
||||
|
||||
composed path:
|
||||
operator<<()---------: "\\foo\\bar\\baa.txt"
|
||||
make_preferred()-----: "\\foo\\bar\\baa.txt"
|
||||
|
||||
elements:
|
||||
"\/"
|
||||
"foo"
|
||||
"bar"
|
||||
"baa.txt"
|
||||
|
||||
observers, native format:
|
||||
native()-------------: \\foo\\bar\\baa.txt
|
||||
c_str()--------------: \\foo\\bar\\baa.txt
|
||||
string()-------------: \\foo\\bar\\baa.txt
|
||||
wstring()------------: \\foo\\bar\\baa.txt
|
||||
|
||||
observers, generic format:
|
||||
generic_string()-----: \/foo\/bar\/baa.txt
|
||||
generic_wstring()----: \/foo\/bar\/baa.txt
|
||||
|
||||
decomposition:
|
||||
root_name()----------: ""
|
||||
root_directory()-----: "\\"
|
||||
root_path()----------: "\\"
|
||||
relative_path()------: "foo\\bar\\baa.txt"
|
||||
parent_path()--------: "\\foo\\bar"
|
||||
filename()-----------: "baa.txt"
|
||||
stem()---------------: "baa"
|
||||
extension()----------: ".txt"
|
||||
|
||||
query:
|
||||
empty()--------------: false
|
||||
is_absolute()--------: false
|
||||
has_root_name()------: false
|
||||
has_root_directory()-: true
|
||||
has_root_path()------: true
|
||||
has_relative_path()--: true
|
||||
has_parent_path()----: true
|
||||
has_filename()-------: true
|
||||
has_stem()-----------: true
|
||||
has_extension()------: true
|
||||
]
|
||||
]]
|
||||
]
|
||||
|
||||
We will go through the above code in detail to gain a better understanding of what is going on.
|
||||
|
||||
A common need is to compose a path from its constituent directories. Class `path` uses `/` and `/=` operators to
|
||||
append elements. That's a reminder that these operations append the operating system's preferred directory
|
||||
separator if needed. The preferred directory separator is a slash on POSIX-like systems, and a backslash on
|
||||
Windows-like systems.
|
||||
|
||||
That's what this code does before displaying the resulting `path p` using the `class path` stream inserter:
|
||||
|
||||
```
|
||||
path p;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
p /= argv[i]; // compose path p from the command line arguments
|
||||
|
||||
std::cout << "\ncomposed path:" << std::endl;
|
||||
std::cout << " operator<<()---------: " << p << std::endl;
|
||||
std::cout << " make_preferred()-----: " << p.make_preferred() << std::endl;
|
||||
```
|
||||
|
||||
One abstraction for thinking about a path is as a sequence of elements, where the elements are directory and
|
||||
file names. To support this abstraction, class `path` provides iterators and also `begin()` and `end()` functions.
|
||||
|
||||
Here is the code that produced the list of elements in the above output listing:
|
||||
|
||||
```
|
||||
std::cout << "\nelements:" << std::endl;
|
||||
for (auto element : p)
|
||||
std::cout << " " << element << std::endl;
|
||||
```
|
||||
|
||||
Let's look at class path observer functions:
|
||||
|
||||
```
|
||||
std::cout << "\nobservers, native format:" << std::endl;
|
||||
#ifdef BOOST_FILESYSTEM_POSIX_API
|
||||
std::cout << " native()-------------: " << p.native() << std::endl;
|
||||
std::cout << " c_str()--------------: " << p.c_str() << std::endl;
|
||||
#else // BOOST_FILESYSTEM_WINDOWS_API
|
||||
std::wcout << L" native()-------------: " << p.native() << std::endl;
|
||||
std::wcout << L" c_str()--------------: " << p.c_str() << std::endl;
|
||||
#endif
|
||||
std::cout << " string()-------------: " << p.string() << std::endl;
|
||||
std::wcout << L" wstring()------------: " << p.wstring() << std::endl;
|
||||
|
||||
std::cout << "\nobservers, generic format:" << std::endl;
|
||||
std::cout << " generic_string()-----: " << p.generic_string() << std::endl;
|
||||
std::wcout << L" generic_wstring()----: " << p.generic_wstring() << std::endl;
|
||||
```
|
||||
|
||||
Native format observers should be used when interacting with the operating system or with users; that's what
|
||||
they expect.
|
||||
|
||||
Generic format observers should be used when the results need to be portable and uniform regardless of
|
||||
the operating system.
|
||||
|
||||
`path` objects always hold pathnames in the native format, but otherwise leave them unchanged from their source.
|
||||
The [link filesystem.reference.preferred `preferred()`] function will convert to the preferred form, if the native
|
||||
format has several forms. Thus on Windows, it will convert slashes to backslashes.
|
||||
|
||||
Moving on to decomposition:
|
||||
|
||||
```
|
||||
std::cout << "\ndecomposition:" << std::endl;
|
||||
std::cout << " root_name()----------: " << p.root_name() << std::endl;
|
||||
std::cout << " root_directory()-----: " << p.root_directory() << std::endl;
|
||||
std::cout << " root_path()----------: " << p.root_path() << std::endl;
|
||||
std::cout << " relative_path()------: " << p.relative_path() << std::endl;
|
||||
std::cout << " parent_path()--------: " << p.parent_path() << std::endl;
|
||||
std::cout << " filename()-----------: " << p.filename() << std::endl;
|
||||
std::cout << " stem()---------------: " << p.stem() << std::endl;
|
||||
std::cout << " extension()----------: " << p.extension() << std::endl;
|
||||
```
|
||||
|
||||
And, finally, query functions:
|
||||
|
||||
```
|
||||
std::cout << "\nquery:" << std::endl;
|
||||
std::cout << " empty()--------------: " << p.empty() << std::endl;
|
||||
std::cout << " is_absolute()--------: " << p.is_absolute() << std::endl;
|
||||
std::cout << " has_root_name()------: " << p.has_root_name() << std::endl;
|
||||
std::cout << " has_root_directory()-: " << p.has_root_directory() << std::endl;
|
||||
std::cout << " has_root_path()------: " << p.has_root_path() << std::endl;
|
||||
std::cout << " has_relative_path()--: " << p.has_relative_path() << std::endl;
|
||||
std::cout << " has_parent_path()----: " << p.has_parent_path() << std::endl;
|
||||
std::cout << " has_filename()-------: " << p.has_filename() << std::endl;
|
||||
std::cout << " has_stem()-----------: " << p.has_stem() << std::endl;
|
||||
std::cout << " has_extension()------: " << p.has_extension() << std::endl;
|
||||
```
|
||||
|
||||
These are pretty self-evident, but do note the difference in the result of `is_absolute()` between Linux and Windows.
|
||||
Because there is no root name (i.e. drive specifier or network name), a lone slash (or backslash) is a relative path
|
||||
on Windows but an absolute path on POSIX-like operating systems.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:error-reporting Error reporting]
|
||||
|
||||
The Boost.Filesystem `file_size` function, like many of the operational functions, has two overloads:
|
||||
|
||||
```
|
||||
uintmax_t file_size(const path& p);
|
||||
uintmax_t file_size(const path& p, system::error_code& ec);
|
||||
```
|
||||
|
||||
The only significant difference between the two is how they report errors.
|
||||
|
||||
The first signature will throw exceptions to report errors. A [link filesystem.reference.class-filesystem_error
|
||||
`filesystem_error`] exception will be thrown on an operational error. `filesystem_error` is derived from
|
||||
`std::runtime_error`. It has a member function to obtain the `error_code` (defined in __boost_system__) reported by
|
||||
the source of the error. It also has member functions to obtain the path or paths that caused the error.
|
||||
|
||||
[blurb [*Motivation for the second signature:]
|
||||
|
||||
Throwing exceptions on errors was the entire error reporting story for the earliest versions of Boost.Filesystem,
|
||||
and indeed throwing exceptions on errors works very well for many applications. But user reports trickled in that
|
||||
some code became so littered with try and catch blocks as to be unreadable and unmaintainable. In some applications
|
||||
I/O errors aren't exceptional, and that's the use case for the second signature.
|
||||
]
|
||||
|
||||
Functions with a `system::error_code&` argument set that argument to report operational error status, and so do not
|
||||
throw exceptions when I\/O related errors occur. For a full explanation, see [link filesystem.reference.error-reporting
|
||||
Error reporting] in the reference documentation.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
197
doc/v3.qbk
Normal file
197
doc/v3.qbk
Normal file
@@ -0,0 +1,197 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ http://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:v3 Boost Filesystem Version 3]
|
||||
|
||||
Version 3 is a major revision of the Boost Filesystem library. Important changes include:
|
||||
|
||||
* A single class `path` handles all aspects of internationalization, replacing the previous template and its `path` and `wpath`
|
||||
instantiations. Character types `char` and `wchar_t` are supported. This is a major simplification of the path abstraction,
|
||||
particularly for functions that take path arguments.
|
||||
* New `class path` members include:
|
||||
* [member path::has_stem]
|
||||
* [member path::has_extension]
|
||||
* [member path::is_absolute]. This renames `is_complete()`, which is now deprecated.
|
||||
* [member path::is_relative]
|
||||
* [member path::make_preferred]
|
||||
* New or improved operations functions include:
|
||||
* [link filesystem.reference.absolute `absolute()`]. This replaces the operations function `complete()`, which is now
|
||||
deprecated. Semantics are now provided for a Windows corner case where the `base` argument was not an absolute path.
|
||||
Previously this resulted in an exception being thrown.
|
||||
* [link filesystem.reference.create_symlink `create_symlink()`] now supported on both POSIX and Windows.
|
||||
* [link filesystem.reference.read_symlink `read_symlink()`] function added. Supported on both POSIX and Windows. Used
|
||||
to read the contents of a symlink itself.
|
||||
* [link filesystem.reference.resize_file `resize_file()`] function added. Supported on both POSIX and Windows. Used to shrink
|
||||
or grow a regular file.
|
||||
* [link filesystem.reference.unique_path `unique_path()`] function added. Supported on both POSIX and Windows. Used to generate
|
||||
a secure temporary pathname.
|
||||
* Support for error reporting via `error_code` is now uniform throughout the operation functions.
|
||||
* Documentation has been reworked, including re-writes of major portions.
|
||||
* A new [link filesystem.tutorial Tutorial] provides a hopefully much gentler and more complete introduction for new users.
|
||||
Current users might want to review the three sections related to class path.
|
||||
|
||||
[section:deprecated Deprecated names and other features]
|
||||
|
||||
See the [link filesystem.deprecated Deprecated Features page] for transition aids that allow much existing code to compile
|
||||
without change using Version 3.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:breaking_changes Breaking changes]
|
||||
|
||||
To ease the transition, Versions 2 and 3 both used to be included in the next several Boost releases. Version 2 was removed in
|
||||
Boost 1.50.0.
|
||||
|
||||
[section:path Class `path`]
|
||||
|
||||
* Class template `basic_path` and its specializations are replaced by a single class `path`. Thus any code, such as overloaded
|
||||
functions, that depend on `path` and `wpath` being two distinct types will fail to compile and must be restructured.
|
||||
Restructuring may be as simple as removing one of the overloads, but also might require more complex redesign.
|
||||
* Certain functions now return `path` objects rather than `string` or `wstring` objects:
|
||||
* `root_name()`
|
||||
* `root_directory()`
|
||||
* `filename()`
|
||||
* `stem()`
|
||||
* `extension()`
|
||||
Not all uses will fail; if the function is being called in a context that accepts a `path`, all is well. If the result is being
|
||||
used in a context requiring a `std::string` or `std::wstring`, then `.string()` or `.wstring()` respectively must be appended
|
||||
to the function call.
|
||||
* `path::iterator::value_type` and `path::const_iterator::value_type` is `path` rather than `std::basic_string`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:compilers Compiler support]
|
||||
|
||||
* Compilers and standard libraries that do not fully support wide characters and wide character strings (`std::wstring`) are
|
||||
no longer supported.
|
||||
* Cygwin versions prior to 1.7 are no longer supported because they lack wide string support. Cygwin now compiles only for
|
||||
the POSIX API and path syntax.
|
||||
* MinGW versions not supporting wide strings are no longer supported.
|
||||
* Microsoft VC++ 7.1 and earlier are no longer supported.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:design Design]
|
||||
|
||||
[warning This section documents thinking early in the V3 development process, and is intended to serve historical purposes.
|
||||
It is not updated to reflect the current state of the library.]
|
||||
|
||||
[note Some parts of the discussion in this section are spoken from the perspective of the original author of Boost.Filesystem,
|
||||
Beman Dawes. This text is preserved, with minor editorial and formatting changes, for historical reasons.]
|
||||
|
||||
[section:introduction Introduction]
|
||||
|
||||
During the review of Boost.Filesystem.V2 (Internationalization), Peter Dimov suggested that the `basic_path` class template
|
||||
was unwieldy, and that a single path type that accommodated multiple character types and encodings would be more flexible. Although
|
||||
I wasn't willing to stop development at that time to explore how this idea might be implemented, or to break from the pattern for
|
||||
Internationalization used the C++ standard library, I've often thought about Peter's suggestion. With the advent of C++0x `char16_t`
|
||||
and `char32_t` character types, the `basic_path` class template approach becomes even more unwieldy, so it is time to revisit
|
||||
the problem in light of Peter's suggestion.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:problem Problem]
|
||||
|
||||
With Filesystem.V2, a path argument to a user defined function that is to accommodate multiple character types and encodings must
|
||||
be written as a template. Do-the-right-thing overloads or template metaprogramming must be employed to allow arguments to be written
|
||||
as string literals. Here's what it looks like:
|
||||
|
||||
```
|
||||
template<class Path>
|
||||
void foo(const Path& p);
|
||||
|
||||
inline void foo(const path& p)
|
||||
{
|
||||
foo<path>(p);
|
||||
}
|
||||
|
||||
inline void foo(const wpath& p)
|
||||
{
|
||||
foo<wpath>(p);
|
||||
}
|
||||
```
|
||||
|
||||
That's really ugly for such a simple need, and there would be a combinatorial explosion if the function took multiple `Path`
|
||||
arguments and each could be either narrow or wide. It gets even worse if the C++0x `char16_t` and `char32_t` types are to be
|
||||
supported.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:solution Solution]
|
||||
|
||||
Overview:
|
||||
|
||||
* A single, non-template, class `path`.
|
||||
* Each member function is a template accommodating the various applicable character types, including user-defined character types.
|
||||
* Hold the path internally in a string of the type used by the operating system API; `std::string` for POSIX, `std::wstring` for
|
||||
Windows.
|
||||
|
||||
The signatures presented in [link filesystem.v3.design.problem Problem] collapse to simply:
|
||||
|
||||
```
|
||||
void foo(const path& p);
|
||||
```
|
||||
|
||||
That's a significant reduction in code complexity. Specification becomes simpler, too. I believe it will be far easier to teach,
|
||||
and result in much more flexible user code.
|
||||
|
||||
Other benefits:
|
||||
|
||||
* All the polymorphism still occurs at compile time.
|
||||
* Efficiency is increased, in that conversions of the encoding, if required, only occur once at the time of creation, not each time
|
||||
the path is used.
|
||||
* The size of the implementation code drops approximately in half and becomes much more readable.
|
||||
|
||||
Possible problems:
|
||||
|
||||
* The combination of member function templates and implicit constructors can result in unclear error messages when the user makes
|
||||
simple commonplace coding errors. This should be much less of a problem with C++ concepts, but in the meantime work continues
|
||||
to restrict over aggressive templates via `enable_if`/`disable_if`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:details Details]
|
||||
|
||||
[table Encoding Conversions
|
||||
[[Host system] [char string path arguments] [wide string path arguments]]
|
||||
[[
|
||||
Systems with `char` as the native API path character type (i.e. POSIX-like systems)
|
||||
]
|
||||
[
|
||||
No conversion.
|
||||
]
|
||||
[
|
||||
Conversion occurs, performed by the current path locale's `codecvt` facet.
|
||||
]]
|
||||
[[
|
||||
Systems with `wchar_t` as the native API path character type (i.e. Windows-like systems).
|
||||
]
|
||||
[
|
||||
Conversion occurs, performed by the current path locale's `codecvt` facet.
|
||||
]
|
||||
[
|
||||
No conversion.
|
||||
]]
|
||||
]
|
||||
|
||||
When a class `path` function argument type matches the operating system's API argument type for paths, no conversion is performed
|
||||
rather than conversion to a specified encoding such as one of the Unicode encodings. This avoids unintended consequences, etc.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:other-changes Other changes]
|
||||
|
||||
* Uniform hybrid error handling: The hybrid error handling idiom has been consistently applied to all applicable functions.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
69
doc/v4.qbk
Normal file
69
doc/v4.qbk
Normal file
@@ -0,0 +1,69 @@
|
||||
[/
|
||||
/ Copyright Andrey Semashev 2024.
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0.
|
||||
/ (See accompanying file LICENSE_1_0.txt or copy at
|
||||
/ http://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:v4 Boost Filesystem Version 4]
|
||||
|
||||
Version 4 is a significant revision of the Boost Filesystem library that makes its interface and behavior closer to std::filesystem
|
||||
that was introduced in C++17 and updated in the later standards. It removes the features that were [link filesystem.deprecated
|
||||
deprecated] in Version 3 and makes a number of breaking changes. Eventually, Version 4 will become the default, and Version 3 will
|
||||
be removed.
|
||||
|
||||
Users can select Boost.Filesystem v4 version by defining `BOOST_FILESYSTEM_VERSION` macro to 4 when compiling their code. There
|
||||
is no need to separately compile Boost.Filesystem for each library version — a single binary supports both v3 and v4. Users
|
||||
should avoid using both v3 and v4 in the same application as this can lead to subtle bugs.
|
||||
|
||||
[section:breaking_changes Breaking changes]
|
||||
|
||||
[section:path Class `path` behavior]
|
||||
|
||||
* [member path::filename] no longer returns root name or root directory if the path contains no other elements. For example,
|
||||
on Windows `path("C:").filename()` used to return "C:" and `path("C:\\").filename()` used to return "\\" and both will return
|
||||
an empty path now. This also affects [member path::stem] and [member path::extension] methods, as those are based on
|
||||
`path::filename`.
|
||||
* [member path::stem] and [member path::extension] no longer treat a filename that starts with a dot and has no other dots
|
||||
as an extension. Filenames starting with a dot are commonly treated as filenames with an empty extension. The leading dot
|
||||
is used to indicate a hidden file on most UNIX-like systems.
|
||||
* [member path::filename] and `path::iterator` no longer return an implicit trailing dot (".") element if the path ends
|
||||
with a directory separator. Instead, an empty path is returned, similar to C++17 std::filesystem. This also affects other methods
|
||||
that are defined in terms of iterators or filename, such as [member path::stem], [member path::compare] or `lexicographical_compare`.
|
||||
For example, `path("a/b/") == path("a/b/.")` no longer holds true.
|
||||
* [member path::lexically_normal] no longer produces a trailing dot (".") element and omits a directory separator after a trailing
|
||||
dot-dot ("..") element in the normalized paths.
|
||||
* [member path::lexically_normal], [member path::make_preferred], [member path::generic_path] and similar methods no longer convert
|
||||
between forward and backward slashes in root names of the returned paths.
|
||||
* [member path::append] consider root name and root directory of the appended path. If the appended path is absolute, or root name
|
||||
is present and differs from the source path, the resulting path is equivalent to the appended path. If root directory is present,
|
||||
the result is the root directory and relative path rebased on top of the root name of the source path. Otherwise, the behavior
|
||||
is similar to v3. This behavior is similar to C++17 std::filesystem.
|
||||
* `path` no longer supports construction, assignment or appending from containers of characters. Use string types or iterators as
|
||||
the source for these opereations instead.
|
||||
* [member path::remove_filename] preserves the trailing directory separator, so that [member path::has_filename] returns `false`
|
||||
after a successful call to `path::remove_filename`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:directory Directory operations]
|
||||
|
||||
* [class directory_entry] constructors and modifiers that initialize or modify path of the directory entry automatically call
|
||||
[member directory_entry::refresh] instead of clearing cached file statuses. This means that the file identified by the new path needs
|
||||
to be accessible in the filesystem at the point of the call.
|
||||
* [class directory_entry] constructors and modifiers that accept [class file_status] arguments to initialize cached file statuses
|
||||
are removed. The amount of cached data is an implementation detail of `directory_entry`, and in the future it may not be limited
|
||||
to just file statuses. Users should rely on automatic refreshes of the cached data.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:operations Filesystem operations]
|
||||
|
||||
* [link filesystem.reference.equivalent `equivalent`] now fails if only one of the input paths exists.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
@@ -7,80 +7,81 @@
|
||||
|
||||
// Library home page: http://www.boost.org/libs/filesystem
|
||||
|
||||
//[example_path_info
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
const char* say_what(bool b)
|
||||
{
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
cout << "Usage: path_info path-element [path-element...]\n"
|
||||
std::cout << "Usage: path_info path-element [path-element...]\n"
|
||||
"Composes a path via operator/= from one or more path-element arguments\n"
|
||||
"Example: path_info foo/bar baz\n"
|
||||
" would report info about the composed path "
|
||||
#ifdef BOOST_FILESYSTEM_POSIX_API
|
||||
" would report info about the composed path foo/bar/baz\n";
|
||||
"foo/bar/baz"
|
||||
#else // BOOST_FILESYSTEM_WINDOWS_API
|
||||
" would report info about the composed path foo/bar\\baz\n";
|
||||
"foo/bar\\baz"
|
||||
#endif
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
path p;
|
||||
for (; argc > 1; --argc, ++argv)
|
||||
p /= argv[1]; // compose path p from the command line arguments
|
||||
for (int i = 1; i < argc; ++i)
|
||||
p /= argv[i]; // compose path p from the command line arguments
|
||||
|
||||
cout << "\ncomposed path:\n";
|
||||
cout << " operator<<()---------: " << p << "\n";
|
||||
cout << " make_preferred()-----: " << p.make_preferred() << "\n";
|
||||
std::cout << "\ncomposed path:" << std::endl;
|
||||
std::cout << " operator<<()---------: " << p << std::endl;
|
||||
std::cout << " make_preferred()-----: " << p.make_preferred() << std::endl;
|
||||
|
||||
cout << "\nelements:\n";
|
||||
std::cout << "\nelements:" << std::endl;
|
||||
for (auto element : p)
|
||||
cout << " " << element << '\n';
|
||||
std::cout << " " << element << std::endl;
|
||||
|
||||
cout << "\nobservers, native format:" << endl;
|
||||
std::cout << "\nobservers, native format:" << std::endl;
|
||||
#ifdef BOOST_FILESYSTEM_POSIX_API
|
||||
cout << " native()-------------: " << p.native() << endl;
|
||||
cout << " c_str()--------------: " << p.c_str() << endl;
|
||||
std::cout << " native()-------------: " << p.native() << std::endl;
|
||||
std::cout << " c_str()--------------: " << p.c_str() << std::endl;
|
||||
#else // BOOST_FILESYSTEM_WINDOWS_API
|
||||
wcout << L" native()-------------: " << p.native() << endl;
|
||||
wcout << L" c_str()--------------: " << p.c_str() << endl;
|
||||
std::wcout << L" native()-------------: " << p.native() << std::endl;
|
||||
std::wcout << L" c_str()--------------: " << p.c_str() << std::endl;
|
||||
#endif
|
||||
cout << " string()-------------: " << p.string() << endl;
|
||||
wcout << L" wstring()------------: " << p.wstring() << endl;
|
||||
std::cout << " string()-------------: " << p.string() << std::endl;
|
||||
std::wcout << L" wstring()------------: " << p.wstring() << std::endl;
|
||||
|
||||
cout << "\nobservers, generic format:\n";
|
||||
cout << " generic_string()-----: " << p.generic_string() << endl;
|
||||
wcout << L" generic_wstring()----: " << p.generic_wstring() << endl;
|
||||
std::cout << "\nobservers, generic format:" << std::endl;
|
||||
std::cout << " generic_string()-----: " << p.generic_string() << std::endl;
|
||||
std::wcout << L" generic_wstring()----: " << p.generic_wstring() << std::endl;
|
||||
|
||||
cout << "\ndecomposition:\n";
|
||||
cout << " root_name()----------: " << p.root_name() << '\n';
|
||||
cout << " root_directory()-----: " << p.root_directory() << '\n';
|
||||
cout << " root_path()----------: " << p.root_path() << '\n';
|
||||
cout << " relative_path()------: " << p.relative_path() << '\n';
|
||||
cout << " parent_path()--------: " << p.parent_path() << '\n';
|
||||
cout << " filename()-----------: " << p.filename() << '\n';
|
||||
cout << " stem()---------------: " << p.stem() << '\n';
|
||||
cout << " extension()----------: " << p.extension() << '\n';
|
||||
std::cout << "\ndecomposition:" << std::endl;
|
||||
std::cout << " root_name()----------: " << p.root_name() << std::endl;
|
||||
std::cout << " root_directory()-----: " << p.root_directory() << std::endl;
|
||||
std::cout << " root_path()----------: " << p.root_path() << std::endl;
|
||||
std::cout << " relative_path()------: " << p.relative_path() << std::endl;
|
||||
std::cout << " parent_path()--------: " << p.parent_path() << std::endl;
|
||||
std::cout << " filename()-----------: " << p.filename() << std::endl;
|
||||
std::cout << " stem()---------------: " << p.stem() << std::endl;
|
||||
std::cout << " extension()----------: " << p.extension() << std::endl;
|
||||
|
||||
cout << "\nquery:\n";
|
||||
cout << " empty()--------------: " << say_what(p.empty()) << '\n';
|
||||
cout << " is_absolute()--------: " << say_what(p.is_absolute()) << '\n';
|
||||
cout << " has_root_name()------: " << say_what(p.has_root_name()) << '\n';
|
||||
cout << " has_root_directory()-: " << say_what(p.has_root_directory()) << '\n';
|
||||
cout << " has_root_path()------: " << say_what(p.has_root_path()) << '\n';
|
||||
cout << " has_relative_path()--: " << say_what(p.has_relative_path()) << '\n';
|
||||
cout << " has_parent_path()----: " << say_what(p.has_parent_path()) << '\n';
|
||||
cout << " has_filename()-------: " << say_what(p.has_filename()) << '\n';
|
||||
cout << " has_stem()-----------: " << say_what(p.has_stem()) << '\n';
|
||||
cout << " has_extension()------: " << say_what(p.has_extension()) << '\n';
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
std::cout << "\nquery:" << std::endl;
|
||||
std::cout << " empty()--------------: " << p.empty() << std::endl;
|
||||
std::cout << " is_absolute()--------: " << p.is_absolute() << std::endl;
|
||||
std::cout << " has_root_name()------: " << p.has_root_name() << std::endl;
|
||||
std::cout << " has_root_directory()-: " << p.has_root_directory() << std::endl;
|
||||
std::cout << " has_root_path()------: " << p.has_root_path() << std::endl;
|
||||
std::cout << " has_relative_path()--: " << p.has_relative_path() << std::endl;
|
||||
std::cout << " has_parent_path()----: " << p.has_parent_path() << std::endl;
|
||||
std::cout << " has_filename()-------: " << p.has_filename() << std::endl;
|
||||
std::cout << " has_stem()-----------: " << p.has_stem() << std::endl;
|
||||
std::cout << " has_extension()------: " << p.has_extension() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
// Library home page: http://www.boost.org/libs/filesystem
|
||||
|
||||
//[example_tut0
|
||||
#include <iostream>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@@ -16,9 +17,10 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cout << "Usage: tut0 path\n";
|
||||
std::cout << "Usage: tut0 path" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << argv[1] << '\n';
|
||||
std::cout << argv[1] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
// Library home page: http://www.boost.org/libs/filesystem
|
||||
|
||||
//[example_tut1
|
||||
#include <iostream>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@@ -16,9 +17,10 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cout << "Usage: tut1 path\n";
|
||||
std::cout << "Usage: tut1 path" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << argv[1] << " " << file_size(argv[1]) << '\n';
|
||||
std::cout << argv[1] << " " << file_size(argv[1]) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -7,17 +7,17 @@
|
||||
|
||||
// Library home page: http://www.boost.org/libs/filesystem
|
||||
|
||||
//[example_tut2
|
||||
#include <iostream>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
cout << "Usage: tut2 path\n";
|
||||
std::cout << "Usage: tut2 path" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -26,14 +26,15 @@ int main(int argc, char* argv[])
|
||||
if (exists(p)) // does path p actually exist?
|
||||
{
|
||||
if (is_regular_file(p)) // is path p a regular file?
|
||||
cout << p << " size is " << file_size(p) << '\n';
|
||||
std::cout << p << " size is " << file_size(p) << std::endl;
|
||||
else if (is_directory(p)) // is path p a directory?
|
||||
cout << p << " is a directory\n";
|
||||
std::cout << p << " is a directory" << std::endl;
|
||||
else
|
||||
cout << p << " exists, but is not a regular file or directory\n";
|
||||
std::cout << p << " exists, but is not a regular file or directory" << std::endl;
|
||||
}
|
||||
else
|
||||
cout << p << " does not exist\n";
|
||||
std::cout << p << " does not exist" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -7,17 +7,17 @@
|
||||
|
||||
// Library home page: http://www.boost.org/libs/filesystem
|
||||
|
||||
//[example_tut3
|
||||
#include <iostream>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using std::cout;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
cout << "Usage: tut3 path\n";
|
||||
std::cout << "Usage: tut3 path" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -29,25 +29,26 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
if (is_regular_file(p))
|
||||
{
|
||||
cout << p << " size is " << file_size(p) << '\n';
|
||||
std::cout << p << " size is " << file_size(p) << std::endl;
|
||||
}
|
||||
else if (is_directory(p))
|
||||
{
|
||||
cout << p << " is a directory containing:\n";
|
||||
std::cout << p << " is a directory containing:" << std::endl;
|
||||
|
||||
for (directory_entry const& x : directory_iterator(p))
|
||||
cout << " " << x.path() << '\n';
|
||||
std::cout << " " << x.path() << std::endl;
|
||||
}
|
||||
else
|
||||
cout << p << " exists, but is not a regular file or directory\n";
|
||||
std::cout << p << " exists, but is not a regular file or directory" << std::endl;
|
||||
}
|
||||
else
|
||||
cout << p << " does not exist\n";
|
||||
std::cout << p << " does not exist" << std::endl;
|
||||
}
|
||||
catch (filesystem_error& ex)
|
||||
{
|
||||
cout << ex.what() << '\n';
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -7,19 +7,19 @@
|
||||
|
||||
// Library home page: http://www.boost.org/libs/filesystem
|
||||
|
||||
//[example_tut4
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using std::cout;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
cout << "Usage: tut4 path\n";
|
||||
std::cout << "Usage: tut4 path" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -31,13 +31,13 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
if (is_regular_file(p))
|
||||
{
|
||||
cout << p << " size is " << file_size(p) << '\n';
|
||||
std::cout << p << " size is " << file_size(p) << std::endl;
|
||||
}
|
||||
else if (is_directory(p))
|
||||
{
|
||||
cout << p << " is a directory containing:\n";
|
||||
std::cout << p << " is a directory containing:" << std::endl;
|
||||
|
||||
std::vector< path > v;
|
||||
std::vector<path> v;
|
||||
|
||||
for (auto&& x : directory_iterator(p))
|
||||
v.push_back(x.path());
|
||||
@@ -45,18 +45,19 @@ int main(int argc, char* argv[])
|
||||
std::sort(v.begin(), v.end());
|
||||
|
||||
for (auto&& x : v)
|
||||
cout << " " << x.filename() << '\n';
|
||||
std::cout << " " << x.filename() << std::endl;
|
||||
}
|
||||
else
|
||||
cout << p << " exists, but is not a regular file or directory\n";
|
||||
std::cout << p << " exists, but is not a regular file or directory" << std::endl;
|
||||
}
|
||||
else
|
||||
cout << p << " does not exist\n";
|
||||
std::cout << p << " does not exist" << std::endl;
|
||||
}
|
||||
catch (filesystem_error& ex)
|
||||
{
|
||||
cout << ex.what() << '\n';
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
// Library home page: http://www.boost.org/libs/filesystem
|
||||
|
||||
//[example_tut5
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <string>
|
||||
#include <list>
|
||||
@@ -67,3 +68,4 @@ int main()
|
||||
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -174,4 +174,24 @@ BOOST_PRAGMA_MESSAGE("Boost.Filesystem: Platform API mismatch between Boost.Syst
|
||||
#define BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_FILESYSTEM_DETAIL_DOC_ALT)
|
||||
#if !defined(BOOST_FILESYSTEM_DOXYGEN)
|
||||
#define BOOST_FILESYSTEM_DETAIL_DOC_ALT(alt, ...) __VA_ARGS__
|
||||
#else
|
||||
#define BOOST_FILESYSTEM_DETAIL_DOC_ALT(alt, ...) alt
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_FILESYSTEM_DETAIL_DOC_HIDDEN)
|
||||
#define BOOST_FILESYSTEM_DETAIL_DOC_HIDDEN(...) BOOST_FILESYSTEM_DETAIL_DOC_ALT(..., __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_FILESYSTEM_DETAIL_DOC)
|
||||
#if !defined(BOOST_FILESYSTEM_DOXYGEN)
|
||||
#define BOOST_FILESYSTEM_DETAIL_DOC(...)
|
||||
#else
|
||||
#define BOOST_FILESYSTEM_DETAIL_DOC(...) __VA_ARGS__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // BOOST_FILESYSTEM_CONFIG_HPP
|
||||
|
||||
@@ -56,16 +56,16 @@ namespace detail {
|
||||
namespace path_traits {
|
||||
|
||||
#if defined(BOOST_FILESYSTEM_WINDOWS_API)
|
||||
typedef wchar_t path_native_char_type;
|
||||
using path_native_char_type = wchar_t;
|
||||
#define BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE false
|
||||
#define BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE true
|
||||
#else
|
||||
typedef char path_native_char_type;
|
||||
using path_native_char_type = char;
|
||||
#define BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE true
|
||||
#define BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE false
|
||||
#endif
|
||||
|
||||
typedef std::codecvt< wchar_t, char, std::mbstate_t > codecvt_type;
|
||||
using codecvt_type = std::codecvt< wchar_t, char, std::mbstate_t >;
|
||||
|
||||
struct unknown_type_tag {};
|
||||
struct ntcts_type_tag {};
|
||||
@@ -84,9 +84,9 @@ template< typename T >
|
||||
struct path_source_traits
|
||||
{
|
||||
//! The kind of the path source. Useful for dispatching.
|
||||
typedef unknown_type_tag tag_type;
|
||||
using tag_type = unknown_type_tag;
|
||||
//! Character type that the source contains
|
||||
typedef void char_type;
|
||||
using char_type = void;
|
||||
//! Indicates whether the source is natively supported by \c path::string_type as arguments for constructors/assignment/appending
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
@@ -94,128 +94,128 @@ struct path_source_traits
|
||||
template< >
|
||||
struct path_source_traits< char* >
|
||||
{
|
||||
typedef char_ptr_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = char_ptr_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< const char* >
|
||||
{
|
||||
typedef char_ptr_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = char_ptr_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< wchar_t* >
|
||||
{
|
||||
typedef char_ptr_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = char_ptr_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< const wchar_t* >
|
||||
{
|
||||
typedef char_ptr_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = char_ptr_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< char[] >
|
||||
{
|
||||
typedef char_array_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = char_array_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< const char[] >
|
||||
{
|
||||
typedef char_array_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = char_array_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< wchar_t[] >
|
||||
{
|
||||
typedef char_array_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = char_array_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< const wchar_t[] >
|
||||
{
|
||||
typedef char_array_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = char_array_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
|
||||
};
|
||||
|
||||
template< std::size_t N >
|
||||
struct path_source_traits< char[N] >
|
||||
{
|
||||
typedef char_array_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = char_array_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
|
||||
};
|
||||
|
||||
template< std::size_t N >
|
||||
struct path_source_traits< const char[N] >
|
||||
{
|
||||
typedef char_array_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = char_array_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
|
||||
};
|
||||
|
||||
template< std::size_t N >
|
||||
struct path_source_traits< wchar_t[N] >
|
||||
{
|
||||
typedef char_array_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = char_array_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
|
||||
};
|
||||
|
||||
template< std::size_t N >
|
||||
struct path_source_traits< const wchar_t[N] >
|
||||
{
|
||||
typedef char_array_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = char_array_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< std::string >
|
||||
{
|
||||
typedef std_string_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = std_string_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< std::wstring >
|
||||
{
|
||||
typedef std_string_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = std_string_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< boost::container::basic_string< char, std::char_traits< char >, void > >
|
||||
{
|
||||
typedef boost_container_string_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = boost_container_string_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > >
|
||||
{
|
||||
typedef boost_container_string_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = boost_container_string_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
|
||||
@@ -224,16 +224,16 @@ struct path_source_traits< boost::container::basic_string< wchar_t, std::char_tr
|
||||
template< >
|
||||
struct path_source_traits< std::string_view >
|
||||
{
|
||||
typedef std_string_view_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = std_string_view_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< std::wstring_view >
|
||||
{
|
||||
typedef std_string_view_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = std_string_view_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
|
||||
};
|
||||
|
||||
@@ -242,16 +242,16 @@ struct path_source_traits< std::wstring_view >
|
||||
template< >
|
||||
struct path_source_traits< boost::basic_string_view< char, std::char_traits< char > > >
|
||||
{
|
||||
typedef boost_string_view_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = boost_string_view_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct path_source_traits< boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > >
|
||||
{
|
||||
typedef boost_string_view_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = boost_string_view_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
|
||||
@@ -262,8 +262,8 @@ BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignmen
|
||||
path_source_traits< std::vector< char > >
|
||||
{
|
||||
// Since C++11 this could be string_class_tag as std::vector gained data() member
|
||||
typedef range_type_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = range_type_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
|
||||
@@ -273,8 +273,8 @@ BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignmen
|
||||
path_source_traits< std::vector< wchar_t > >
|
||||
{
|
||||
// Since C++11 this could be string_class_tag as std::vector gained data() member
|
||||
typedef range_type_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = range_type_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
|
||||
@@ -283,8 +283,8 @@ struct
|
||||
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
|
||||
path_source_traits< std::list< char > >
|
||||
{
|
||||
typedef range_type_tag tag_type;
|
||||
typedef char char_type;
|
||||
using tag_type = range_type_tag;
|
||||
using char_type = char;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
|
||||
@@ -293,8 +293,8 @@ struct
|
||||
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
|
||||
path_source_traits< std::list< wchar_t > >
|
||||
{
|
||||
typedef range_type_tag tag_type;
|
||||
typedef wchar_t char_type;
|
||||
using tag_type = range_type_tag;
|
||||
using char_type = wchar_t;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
#endif // defined(BOOST_FILESYSTEM_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4
|
||||
@@ -302,8 +302,8 @@ path_source_traits< std::list< wchar_t > >
|
||||
template< >
|
||||
struct path_source_traits< directory_entry >
|
||||
{
|
||||
typedef directory_entry_tag tag_type;
|
||||
typedef path_native_char_type char_type;
|
||||
using tag_type = directory_entry_tag;
|
||||
using char_type = path_native_char_type;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
|
||||
};
|
||||
|
||||
@@ -479,7 +479,7 @@ BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source,
|
||||
}
|
||||
|
||||
|
||||
typedef char yes_type;
|
||||
using yes_type = char;
|
||||
struct no_type { char buf[2]; };
|
||||
|
||||
#if !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
|
||||
@@ -609,34 +609,34 @@ struct is_convertible_to_path_source :
|
||||
template< typename T, typename >
|
||||
struct make_dependent
|
||||
{
|
||||
typedef T type;
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template< typename Source, typename Callback >
|
||||
BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(const char* source, Callback cb, const codecvt_type* cvt)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< const char*, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< const char*, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t >(source), cb, cvt);
|
||||
}
|
||||
|
||||
template< typename Source, typename Callback >
|
||||
BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(const wchar_t* source, Callback cb, const codecvt_type* cvt)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< const wchar_t*, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< const wchar_t*, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t >(source), cb, cvt);
|
||||
}
|
||||
|
||||
template< typename Source, typename Callback >
|
||||
BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::string const& source, Callback cb, const codecvt_type* cvt)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< std::string, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< std::string, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
template< typename Source, typename Callback >
|
||||
BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::wstring const& source, Callback cb, const codecvt_type* cvt)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< std::wstring, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< std::wstring, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
@@ -648,7 +648,7 @@ BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
|
||||
const codecvt_type* cvt
|
||||
)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< boost::container::basic_string< char, std::char_traits< char >, void >, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< boost::container::basic_string< char, std::char_traits< char >, void >, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
@@ -660,7 +660,7 @@ BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
|
||||
const codecvt_type* cvt
|
||||
)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void >, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void >, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
@@ -672,7 +672,7 @@ BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
|
||||
const codecvt_type* cvt
|
||||
)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< boost::basic_string_view< char, std::char_traits< char > >, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< boost::basic_string_view< char, std::char_traits< char > >, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
@@ -684,7 +684,7 @@ BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
|
||||
const codecvt_type* cvt
|
||||
)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< boost::basic_string_view< wchar_t, std::char_traits< wchar_t > >, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< boost::basic_string_view< wchar_t, std::char_traits< wchar_t > >, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
@@ -695,14 +695,14 @@ BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
|
||||
template< typename Source, typename Callback >
|
||||
BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< std::string_view, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< std::string_view, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
template< typename Source, typename Callback >
|
||||
BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< std::wstring_view, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< std::wstring_view, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
@@ -711,7 +711,7 @@ BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::
|
||||
template< typename Source, typename Callback >
|
||||
BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = nullptr)
|
||||
{
|
||||
typedef typename std::remove_cv< Source >::type source_t;
|
||||
using source_t = typename std::remove_cv< Source >::type;
|
||||
return path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt);
|
||||
}
|
||||
|
||||
@@ -720,14 +720,14 @@ BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible(Source con
|
||||
template< typename Source, typename Callback >
|
||||
BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_sv_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< std::string_view, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< std::string_view, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
template< typename Source, typename Callback >
|
||||
BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_sv_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt)
|
||||
{
|
||||
typedef typename path_traits::make_dependent< std::wstring_view, Source >::type source_t;
|
||||
using source_t = typename path_traits::make_dependent< std::wstring_view, Source >::type;
|
||||
return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
|
||||
}
|
||||
|
||||
@@ -737,7 +737,7 @@ BOOST_FORCEINLINE typename std::enable_if<
|
||||
typename Callback::result_type
|
||||
>::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = nullptr)
|
||||
{
|
||||
typedef typename std::remove_cv< Source >::type source_t;
|
||||
using source_t = typename std::remove_cv< Source >::type;
|
||||
return path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt);
|
||||
}
|
||||
|
||||
@@ -747,7 +747,7 @@ BOOST_FORCEINLINE typename std::enable_if<
|
||||
typename Callback::result_type
|
||||
>::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = nullptr)
|
||||
{
|
||||
typedef typename std::remove_cv< Source >::type source_t;
|
||||
using source_t = typename std::remove_cv< Source >::type;
|
||||
return path_traits::dispatch_convertible_sv_impl< source_t >(source, cb, cvt);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,16 +47,19 @@
|
||||
namespace boost {
|
||||
namespace filesystem {
|
||||
|
||||
//! \hideinitializer
|
||||
enum class directory_options : unsigned int
|
||||
{
|
||||
none = 0u,
|
||||
skip_permission_denied = 1u, // if a directory cannot be opened because of insufficient permissions, pretend that the directory is empty
|
||||
follow_directory_symlink = 1u << 1u, // recursive_directory_iterator: follow directory symlinks
|
||||
skip_dangling_symlinks = 1u << 2u, // non-standard extension for recursive_directory_iterator: don't follow dangling directory symlinks,
|
||||
pop_on_error = 1u << 3u, // non-standard extension for recursive_directory_iterator: instead of producing an end iterator on errors,
|
||||
// repeatedly invoke pop() until it succeeds or the iterator becomes equal to end iterator
|
||||
skip_permission_denied = 1u, //!< If a directory cannot be opened because of insufficient permissions, pretend that the directory is empty
|
||||
follow_directory_symlink = 1u << 1u, //!< `recursive_directory_iterator`: follow directory symlinks
|
||||
skip_dangling_symlinks = 1u << 2u, //!< Non-standard extension for `recursive_directory_iterator`: don't follow dangling directory symlinks,
|
||||
pop_on_error = 1u << 3u, /*!< non-standard extension for `recursive_directory_iterator`: instead of producing an end iterator on errors,
|
||||
* repeatedly invoke `pop()` until it succeeds or the iterator becomes equal to end iterator */
|
||||
#if !defined(BOOST_FILESYSTEM_DOXYGEN)
|
||||
_detail_no_follow = 1u << 4u, // internal use only
|
||||
_detail_no_push = 1u << 5u // internal use only
|
||||
#endif
|
||||
};
|
||||
|
||||
BOOST_BITMASK(directory_options)
|
||||
|
||||
@@ -41,26 +41,29 @@ struct space_info
|
||||
boost::uintmax_t available; // <= free
|
||||
};
|
||||
|
||||
//! \hideinitializer
|
||||
enum class copy_options : unsigned int
|
||||
{
|
||||
none = 0u, // Default. For copy_file: error if the target file exists. For copy: do not recurse, follow symlinks, copy file contents.
|
||||
none = 0u, //!< Default. For copy_file: error if the target file exists. For copy: do not recurse, follow symlinks, copy file contents.
|
||||
|
||||
// copy_file options:
|
||||
skip_existing = 1u, // Don't overwrite the existing target file, don't report an error
|
||||
overwrite_existing = 1u << 1u, // Overwrite existing file
|
||||
update_existing = 1u << 2u, // Overwrite existing file if its last write time is older than the replacement file
|
||||
synchronize_data = 1u << 3u, // Flush all buffered data written to the target file to permanent storage
|
||||
synchronize = 1u << 4u, // Flush all buffered data and attributes written to the target file to permanent storage
|
||||
ignore_attribute_errors = 1u << 5u, // Ignore errors of copying file attributes
|
||||
skip_existing = 1u, //!< Don't overwrite the existing target file, don't report an error
|
||||
overwrite_existing = 1u << 1u, //!< Overwrite existing file
|
||||
update_existing = 1u << 2u, //!< Overwrite existing file if its last write time is older than the replacement file
|
||||
synchronize_data = 1u << 3u, //!< Flush all buffered data written to the target file to permanent storage
|
||||
synchronize = 1u << 4u, //!< Flush all buffered data and attributes written to the target file to permanent storage
|
||||
ignore_attribute_errors = 1u << 5u, //!< Ignore errors of copying file attributes
|
||||
|
||||
// copy options:
|
||||
recursive = 1u << 8u, // Recurse into sub-directories
|
||||
copy_symlinks = 1u << 9u, // Copy symlinks as symlinks instead of copying the referenced file
|
||||
skip_symlinks = 1u << 10u, // Don't copy symlinks
|
||||
directories_only = 1u << 11u, // Only copy directory structure, do not copy non-directory files
|
||||
create_symlinks = 1u << 12u, // Create symlinks instead of copying files
|
||||
create_hard_links = 1u << 13u, // Create hard links instead of copying files
|
||||
recursive = 1u << 8u, //!< Recurse into sub-directories
|
||||
copy_symlinks = 1u << 9u, //!< Copy symlinks as symlinks instead of copying the referenced file
|
||||
skip_symlinks = 1u << 10u, //!< Don't copy symlinks
|
||||
directories_only = 1u << 11u, //!< Only copy directory structure, do not copy non-directory files
|
||||
create_symlinks = 1u << 12u, //!< Create symlinks instead of copying files
|
||||
create_hard_links = 1u << 13u, //!< Create hard links instead of copying files
|
||||
#if !defined(BOOST_FILESYSTEM_DOXYGEN)
|
||||
_detail_recursing = 1u << 14u // Internal use only, do not use
|
||||
#endif
|
||||
};
|
||||
|
||||
BOOST_BITMASK(copy_options)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=doc/index.htm"/>
|
||||
<meta http-equiv="refresh" content="0; URL=doc/html/index.html"/>
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="doc/index.htm">doc/index.htm</a>.
|
||||
<a href="doc/html/index.html">doc/html/index.html</a>.
|
||||
<hr/>
|
||||
<p>© Copyright Beman Dawes, 2003</p>
|
||||
<p> Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
16
src/path.cpp
16
src/path.cpp
@@ -596,8 +596,8 @@ BOOST_FILESYSTEM_DECL void path_algorithms::append_v4(path& p, const value_type*
|
||||
|
||||
BOOST_FILESYSTEM_DECL int path_algorithms::lex_compare_v3
|
||||
(
|
||||
path_detail::path_iterator first1, path_detail::path_iterator const& last1,
|
||||
path_detail::path_iterator first2, path_detail::path_iterator const& last2
|
||||
path_impl::path_iterator first1, path_impl::path_iterator const& last1,
|
||||
path_impl::path_iterator first2, path_impl::path_iterator const& last2
|
||||
)
|
||||
{
|
||||
for (; first1 != last1 && first2 != last2;)
|
||||
@@ -617,8 +617,8 @@ BOOST_FILESYSTEM_DECL int path_algorithms::lex_compare_v3
|
||||
|
||||
BOOST_FILESYSTEM_DECL int path_algorithms::lex_compare_v4
|
||||
(
|
||||
path_detail::path_iterator first1, path_detail::path_iterator const& last1,
|
||||
path_detail::path_iterator first2, path_detail::path_iterator const& last2
|
||||
path_impl::path_iterator first1, path_impl::path_iterator const& last1,
|
||||
path_impl::path_iterator first2, path_impl::path_iterator const& last2
|
||||
)
|
||||
{
|
||||
for (; first1 != last1 && first2 != last2;)
|
||||
@@ -1161,7 +1161,7 @@ namespace boost {
|
||||
namespace filesystem {
|
||||
namespace detail {
|
||||
|
||||
BOOST_FILESYSTEM_DECL void path_algorithms::increment_v3(path_detail::path_iterator& it)
|
||||
BOOST_FILESYSTEM_DECL void path_algorithms::increment_v3(path_impl::path_iterator& it)
|
||||
{
|
||||
const size_type size = it.m_path_ptr->m_pathname.size();
|
||||
BOOST_ASSERT_MSG(it.m_pos < size, "path::iterator increment past end()");
|
||||
@@ -1215,7 +1215,7 @@ BOOST_FILESYSTEM_DECL void path_algorithms::increment_v3(path_detail::path_itera
|
||||
it.m_element.m_pathname.assign(p + it.m_pos, p + end_pos);
|
||||
}
|
||||
|
||||
BOOST_FILESYSTEM_DECL void path_algorithms::increment_v4(path_detail::path_iterator& it)
|
||||
BOOST_FILESYSTEM_DECL void path_algorithms::increment_v4(path_impl::path_iterator& it)
|
||||
{
|
||||
const size_type size = it.m_path_ptr->m_pathname.size();
|
||||
BOOST_ASSERT_MSG(it.m_pos <= size, "path::iterator increment past end()");
|
||||
@@ -1276,7 +1276,7 @@ BOOST_FILESYSTEM_DECL void path_algorithms::increment_v4(path_detail::path_itera
|
||||
it.m_element.m_pathname.assign(p + it.m_pos, p + end_pos);
|
||||
}
|
||||
|
||||
BOOST_FILESYSTEM_DECL void path_algorithms::decrement_v3(path_detail::path_iterator& it)
|
||||
BOOST_FILESYSTEM_DECL void path_algorithms::decrement_v3(path_impl::path_iterator& it)
|
||||
{
|
||||
const size_type size = it.m_path_ptr->m_pathname.size();
|
||||
BOOST_ASSERT_MSG(it.m_pos > 0, "path::iterator decrement past begin()");
|
||||
@@ -1336,7 +1336,7 @@ BOOST_FILESYSTEM_DECL void path_algorithms::decrement_v3(path_detail::path_itera
|
||||
it.m_element.m_pathname.assign(p + it.m_pos, p + end_pos);
|
||||
}
|
||||
|
||||
BOOST_FILESYSTEM_DECL void path_algorithms::decrement_v4(path_detail::path_iterator& it)
|
||||
BOOST_FILESYSTEM_DECL void path_algorithms::decrement_v4(path_impl::path_iterator& it)
|
||||
{
|
||||
const size_type size = it.m_path_ptr->m_pathname.size();
|
||||
BOOST_ASSERT_MSG(it.m_pos > 0, "path::iterator decrement past begin()");
|
||||
|
||||
Reference in New Issue
Block a user