Section: 10 [filesys.ts::fs.enum] Status: NAD Editorial Submitter: Daniel Krügler Opened: 2014-03-01 Last modified: 2016-08-11
Priority: Not Prioritized
View all issues with NAD Editorial status.
Discussion:
Addresses: filesys.ts
copy_options
is declared as enum class
type that is a bismask type, but the
specification repeatedly uses expressions that are invalid for scoped
enums, such as:
!(options)
because there is no contextual conversion to bool, not even the || operator in:
((options & copy_options::recursive) || !(options))
Affected are basically all formulations in the form:
"if options & copy_options::create_symlinks
[..]"
because all rely on contextual conversion to bool. The only other specifically
mention scoped enumeration in the standard that is also a bit mask type is the
launch
enum and
the wording there always uses forms such as:
"if policy & launch::deferred
is non-zero"
which better acknowledges the fact that the obtained values does not necessarily
undergo an implicit conversion.
I think the current wording in the file system spec. must be changed, especially for
invalid expressions of the form:
((options & copy_options::recursive) || !(options))
A similar problem arises in the usage of the bitmask type perms
for the
expression:
((prms & add_perms) && (prms & remove_perms))
The only way how to describe this with a scoped enum is the lengthier form
((prms & perms::add_perms) != perms::none && (prms & perms::remove_perms) !=
perms::none)
thus fixing several problems:
add_perms
and remove_perms
is incorrect[20 May 2014 Beman Dawes provides proposed wording. Fixing invalid C++ is editorial, but treating this as an issue ensures more people review the proposed changes.]
[17 Jun 2014 Rapperswil LWG requests issue be handled as editorial.]
Proposed resolution:
Change 15.3 Copy [fs.op.copy]:
Before the first use of
f
andt
:
- If
(options & copy_options::create_symlinks) != copy_options::none || (options & copy_options::skip_symlinks) != copy_options::none
, thenauto f = symlink_status(from)
and if neededauto t = symlink_status(to)
.- Otherwise,
auto f = status(from)
and if neededauto t = status(to)
.Report an error as specified in Error reporting (7) if:
!exists(f)
, orequivalent(from, to)
, oris_other(f) || is_other(t)
, oris_directory(f) && is_regular_file(t)
.If
is_symlink(f)
, then:
- If
(options & copy_options::skip_symlinks) != copy_options::none
, then return.- Otherwise if
!exists(t)
, thencopy_symlink(from, to, options)
.- Otherwise report an error as specified in Error reporting (7).
Otherwise if
is_regular_file(f)
, then:
- If
(options & copy_options::directories_only) != copy_options::none
, then return.- Otherwise if
(options & copy_options::create_symlinks ) != copy_options::none
, then create a symbolic link to the source file.- Otherwise if
(options & copy_options::create_hard_links) != copy_options::none
, then create a hard link to the source file.- Otherwise if
is_directory(t)
, thencopy_file(from, to/from.filename(), options)
.- Otherwise,
copy_file(from, to, options)
.
Otherwise if
is_directory(f) && ((options & copy_options::recursive) != copy_options::none ||
then:!(options == copy_options::none))
- If
!exists(t)
, thencreate_directory(to, from)
.- Then, iterate over the files in
from
, as if byfor (directory_entry& x : directory_iterator(from))
, and for each iterationcopy(x.path(), to/x.path().filename(), options | copy_options::unspecified)
.
Change 15.4 Copy file [fs.op.copy_file]:
If
exists(to) &&
report a file already exists error as specified in Error reporting (7).
!(options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::noneIf
!exists(to) || (options & copy_options::overwrite_existing) != copy_options::none || ((options & copy_options::update_existing) != copy_options::none && last_write_time(from) > last_write_time(to)) ||
copy the contents and attributes of the file!(options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::nonefrom
resolves to the fileto
resolves to.
Change 15.26 Permissions [fs.op.permissions]:
Requires:
!((prms & perms::add_perms) != perms::none && (prms & perms::remove_perms) != perms::none)
.