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
fandt:
- 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::nonefromresolves to the filetoresolves to.
Change 15.26 Permissions [fs.op.permissions]:
Requires:
!((prms & perms::add_perms) != perms::none && (prms & perms::remove_perms) != perms::none).