29 Input/output library [input.output]

29.11 File systems [filesystems]

29.11.13 Filesystem operation functions [fs.op.funcs]

29.11.13.4 Copy [fs.op.copy]

void copy(const path& from, const path& to);
Effects: Equivalent to copy(from, to, copy_­options​::​none).
void copy(const path& from, const path& to, error_code& ec);
Effects: Equivalent to copy(from, to, copy_­options​::​none, ec).
void copy(const path& from, const path& to, copy_options options); void copy(const path& from, const path& to, copy_options options, error_code& ec);
Preconditions: At most one element from each option group ([fs.enum.copy.opts]) is set in options.
Effects: Before the first use of f and t:
  • If (options & copy_options::create_symlinks) != copy_options::none || (options & copy_options::skip_symlinks) != copy_options::none then auto f = symlink_­status(from) and if needed auto t = symlink_­status(to).
  • Otherwise, if (options & copy_options::copy_symlinks) != copy_options::none then auto f = symlink_­status(from) and if needed auto t = status(to).
  • Otherwise, auto f = status(from) and if needed auto t = status(to).
Effects are then as follows:
  • If f.type() or t.type() is an implementation-defined file type ([fs.enum.file.type]), then the effects are implementation-defined.
  • Otherwise, an error is reported as specified in [fs.err.report] if:
    • exists(f) is false, or
    • equivalent(from, to) is true, or
    • is_­other(f) || is_­other(t) is true, or
    • is_­directory(f) && is_­regular_­file(t) is true.
  • Otherwise, if is_­symlink(f), then:
    • If (options & copy_­options​::​skip_­symlinks) != copy_­options​::​none then return.
    • Otherwise if !exists(t) && (options & copy_options::copy_symlinks) != copy_options::none then copy_­symlink(from, to).
    • Otherwise report an error as specified in [fs.err.report].
  • 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), then copy_­file(from, to/from.filename(), options).
    • Otherwise, copy_­file(from, to, options).
  • Otherwise, if is_directory(f) && (options & copy_options::create_symlinks) != copy_options::none then report an error with an error_­code argument equal to make_­error_­code(errc​::​is_­a_­directory).
  • Otherwise, if is_directory(f) && ((options & copy_options::recursive) != copy_options::none || options == copy_options::none) then:
    • If exists(t) is false, then create_­directory(to, from).
    • Then, iterate over the files in from, as if by for (const directory_entry& x : directory_iterator(from)) copy(x.path(), to/x.path().filename(), options | copy_options::in-recursive-copy); where in-recursive-copy is a bitmask element of copy_­options that is not one of the elements in [fs.enum.copy.opts].
  • Otherwise, for the signature with argument ec, ec.clear().
  • Otherwise, no effects.
Throws: As specified in [fs.err.report].
Remarks: For the signature with argument ec, any library functions called by the implementation shall have an error_­code argument if applicable.
[Example 1:
Given this directory structure:
/dir1
  file1
  file2
  dir2
    file3
Calling copy("/dir1", "/dir3") would result in:
/dir1
  file1
  file2
  dir2
    file3
/dir3
  file1
  file2
Alternatively, calling copy("/dir1", "/dir3", copy_­options​::​recursive) would result in:
/dir1
  file1
  file2
  dir2
    file3
/dir3
  file1
  file2
  dir2
    file3
— end example]