New Page 1

$id frontmatter=

Document number: | N3335=12-0025
Date: | 2012-01-13
Project: | Programming Language C++, Library Working Group
Reply-to: | Beman Dawes <bdawes at acm dot org>

# Filesystem Library for C++11/TR2 (Revision 1)

This paper proposes that the filesystem library component of C++ Standard Library Technical Report 2 be based on Version 3 of the Boost Filesystem Library (see www.boost.org/libs/filesystem). Preliminary wording is provided. A TODO list identifies remaining work to be done.

## Revision history

N3335=12-0025, Filesystem Library for C++11/TR2 (Revision 1). Changes include:

- Regenerated the proposed wording from the Boost Filesystem library reference documentation, using an automated process. This process reduces the likelihood of inadvertent discrepancies between descriptions.
- An Issues list was added, seeded with issues raised by the LWG review of N3239 at the Bloomington meeting, and private communications from LWG members.
- Namespace changed to `files` as an experiment. Made this issue number 1 so the LWG can pass judgement.
- New functions were added, suggested by David Svoboda, to generate canonical paths and manage permissions.
- More C++11 functionality was applied. This process is still incomplete, however.
- Added proposed changes to header <fstream>. The previous paper had inadvertently supplied the wrong wording.
- Continued the general cleanup of wording.

N3239 = 11-0009, Filesystem Library Update for TR2 (Preliminary), reflected changes made to the Boost library version 3 since the previously accepted committee paper:

- A single class `path` handles all aspects of internationalization, replacing the previous template and its `path` and `wpath` instantiations. Character types `char`, `wchar_t`, `char16_t`, and `char32_t` are supported. This is a major simplification of the path abstraction, particularly for functions that take path arguments. This change was based on a suggestion by Peter Dimov.
- Several operational functions have been added, including much better symlink support, the ability to resize a file, and the ability to generate a unique path.
- Support for error reporting via `error_code` is now uniform throughout the operations functions.
- Several functions have been renamed, based on feedback from users.

N1975 = 06-0045, Filesystem Library Proposal for TR2 (Revision 3), was adopted by the committee in April, 2006, at the Berlin meeting. Shortly afterward the Library Working Group set aside work on TR2 to concentrate on C++0x.

## Motivation and Scope

The motivation and scope for a filesystem library were described in N1975, and are not repeated here. A minor scope reduction is that an addition to the current C++ runtime library is no longer needed.

Boost Filesystem Version 3 introduced a single path type that interoperates well with both `basic_string` and user defined string types. Thus the following Design alternatives paragraph is no long applicable:

> Single path type which can at runtime accept narrow or wide character pathnames. Although certainly interesting, and possibly superior, such a design would not interoperate well with the current Standard Library's compile-time typed `basic_string`. A new runtime polymorphic string class would be the best place to experiment with this concept, not a path class.

## TODO

- Apply more C++0X features. Boost.Filesystem needs to implement these to verify their application is correct.
- Boost.Filesystem needs to implement `char16_t` and `char32_t` support to verify the specification for these is correct.
- Replace path inserter and extractor Effects with prose, since the current wording relies on `boost::io::quoted`.
- The Boost implementation has more class path non-member relational functions that shown in the docs, and the specific set of relational functions varies between Windows and POSIX. Figure out what's happening and document it.
- `Source` is not specified as actually implemented. Expose `path_traits`?
- Effects for `copy` and `copy_directory` need to be reviewed, revised, tested, peer reviewed.
- Review changes to header <fstream>. Add semantics. Add section names. Verify still in sync with WP.

$endid $id wording_prefix=

## Proposed Wording

Gray-shaded italic text is commentary on the proposal. It is not to be added to the TR.

Add the following to the Technical Report's front matter:

The following standard contains provisions which, through reference in this text, constitute provisions of this Technical Report. At the time of publication, the editions indicated were valid. All standards are subject to revision, and parties to agreements based on this Technical Report are encouraged to investigate the possibility of applying the most recent editions of the standard indicated below. Members of IEC and ISO maintain registers of currently valid International Standards.

- ISO/IEC 9945:2003, Portable Operating System Interface (POSIX1), part 1 (Base Definitions) and part 2 (System Interfaces), both as corrected by their respective 2004 Correction 1 documents.

  [Note: ISO/IEC 9945:2003 is also IEEE Std 1003.1-2001, and The Open Group Base Specifications, Issue 6, and is also known as The Single Unix2 Specification, Version 3. It is available from each of those organizations, and may be read online or downloaded from www.unix.org/single_unix_specification/ -- end note]

ISO/IEC 9945:2003, with the indicated corrections, is hereinafter called POSIX.

Footnote 1: POSIX® is a registered trademark of The IEEE.

Footnote 2: UNIX® is a registered trademark of The Open Group.

Add the following to the Technical Report as a new Clause:

## Filesystem Library

$endid $id wording_suffix=

End of new Clause.

Modify File streams [fstreams] as follows:

To class basic_filebuf public members add:

>     basic_filebuf<charT,traits>* open(const path& p, std::ios_base::openmode mode);

To class basic_ifstream public members add:

>     explicit basic_ifstream(const path& p, std::ios_base::openmode mode=std::ios_base::in)

>     void open(const path& p, std::ios_base::openmode mode=std::ios_base::in);

To class basic_ofstream public members add:

>     explicit basic_ofstream(const path& p, std::ios_base::openmode mode=std::ios_base::out);

>     void open(const path& p, std::ios_base::openmode mode=std::ios_base::out);

To class basic_fstream public members add:

>     explicit basic_fstream(const path& p,
>       std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out);

>     void open(const path& p,
>       std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out);

End of proposed wording.

## Issues List

### Issue 1: What is the appropriate namespace?

#### Discussion

The proposal places the library in `namespace std::tr2::$SUBNAMESPACE;`. Rationale for a sub-namespace is that the library uses several names that don't seem appropriate for namespace `tr2` since full standardization would then put the names into `std`. The function names `remove` and `rename` are of particular concern because these functions differ in behavior from current standard library functions with those names. It also doesn't seem desirable to preempt names like `equivalent` and `status`.

The Boost Filesystem library used `namespace boost::filesystem`, but that always seemed a bit too long.

#### Proposed resolution

Status quo. Leave in `namespace std::tr2::$SUBNAMESPACE;`.

### Issue 2: Excessive use of `const codecvt_type&` arguments

#### Discussion

Users sometimes need to do path conversions that use something other than the imbued codecvt facet. The need is particularly acute in multi-threaded applications where changing the imbued facet would introduce a data race. That said, providing an optional `const codecvt_type&` argument for every function where the need might possibly arise is excessive because its use is so rare and it adds considerable interface clutter.

#### Proposed resolution

Remove all existing class path `const codecvt_type&` arguments.

Add an additional non-member function:

>     unspecified-iterator-type convert(const path& p, const codecvt_type& codecvt);

> Returns: An unspecified iterator type whose value type is `path::value_type`. The returned iterator points to the beginning of a sequence equivalent to `p.native()` with encoding as specified by `codecvt`.

### Issue 3: Possible "implicit cast to native type"?

#### Discussion

In Bloomington there was discussion of "implicit cast to implicit cast to native OS type to inter operate with existing iostream library and native functions instead of modifying fstream".

Beman comments: I wasn't in Bloomington and am not sure of the context of the above. N3239 inadvertently included the Boost docs for <fstream> rather than suggested <fstream> changes for TR2, and that may have caused some confusion. Or maybe I'm just missing something from the wiki notes. Some further discussions are needed to better define the issue.

#### Proposed resolution

### Issue 4: Given move semantics, it is best not to return const strings.

#### Discussion

The issue title pretty much says it all.

#### Proposed resolution

As part of the C++11 refinements to the interface, review returns of const strings and change to plain strings where appropriate.

### Issue 5: Is there a way to handle characters that are illegal for particular OS?

#### Discussion

Question raised by Pablo in Bloomington.

#### Proposed resolution

Beman suggests NAD, Future. I've done some work on this, including looking at systems like OpenVMS that have an escape mechanism to handle otherwise unrepresentable characters. There was a comment to that effect in N3239. I believe it should be deferred to some future release since (1) it is complex enough that I'd like to see actual implementation and use experience (presumably via Boost), and (2) I can't recall a user ever requesting such a feature.

### Issue 6: Could allocator support be class path?

#### Discussion

Question raised by a committee member in private email.

Comment from Beman: How would allocator support work, given that class path is not a template?

#### Proposed resolution

$endid $id backmatter= $endid