From Jason Turner

[filesystems]

Large diff (139.5 KB) - rendering may be slow on some devices

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpqa2xlps2/{from.md → to.md} +4040 -0
tmp/tmpqa2xlps2/{from.md → to.md} RENAMED
@@ -0,0 +1,4040 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## File systems <a id="filesystems">[[filesystems]]</a>
2
+
3
+ ### General <a id="fs.general">[[fs.general]]</a>
4
+
5
+ This subclause describes operations on file systems and their
6
+ components, such as paths, regular files, and directories.
7
+
8
+ ### Conformance <a id="fs.conformance">[[fs.conformance]]</a>
9
+
10
+ Conformance is specified in terms of behavior. Ideal behavior is not
11
+ always implementable, so the conformance subclauses take that into
12
+ account.
13
+
14
+ #### POSIX conformance <a id="fs.conform.9945">[[fs.conform.9945]]</a>
15
+
16
+ Some behavior is specified by reference to POSIX ([[fs.norm.ref]]). How
17
+ such behavior is actually implemented is unspecified.
18
+
19
+ [*Note 1*: This constitutes an “as if” rule allowing implementations to
20
+ call native operating system or other APIs. — *end note*]
21
+
22
+ Implementations are encouraged to provide such behavior as it is defined
23
+ by POSIX. Implementations shall document any behavior that differs from
24
+ the behavior defined by POSIX. Implementations that do not support exact
25
+ POSIX behavior are encouraged to provide behavior as close to POSIX
26
+ behavior as is reasonable given the limitations of actual operating
27
+ systems and file systems. If an implementation cannot provide any
28
+ reasonable behavior, the implementation shall report an error as
29
+ specified in  [[fs.err.report]].
30
+
31
+ [*Note 2*: This allows users to rely on an exception being thrown or an
32
+ error code being set when an implementation cannot provide any
33
+ reasonable behavior. — *end note*]
34
+
35
+ Implementations are not required to provide behavior that is not
36
+ supported by a particular file system.
37
+
38
+ [*Example 1*: The FAT file system used by some memory cards, camera
39
+ memory, and floppy disks does not support hard links, symlinks, and many
40
+ other features of more capable file systems, so implementations are not
41
+ required to support those features on the FAT file system but instead
42
+ are required to report an error as described above. — *end example*]
43
+
44
+ #### Operating system dependent behavior conformance <a id="fs.conform.os">[[fs.conform.os]]</a>
45
+
46
+ Some behavior is specified as being operating system dependent (
47
+ [[fs.def.osdep]]). The operating system an implementation is dependent
48
+ upon is *implementation-defined*.
49
+
50
+ It is permissible for an implementation to be dependent upon an
51
+ operating system emulator rather than the actual underlying operating
52
+ system.
53
+
54
+ #### File system race behavior <a id="fs.race.behavior">[[fs.race.behavior]]</a>
55
+
56
+ Behavior is undefined if calls to functions provided by this subclause
57
+ introduce a file system race ([[fs.def.race]]).
58
+
59
+ If the possibility of a file system race would make it unreliable for a
60
+ program to test for a precondition before calling a function described
61
+ herein, *Requires:* is not specified for the function.
62
+
63
+ [*Note 1*: As a design practice, preconditions are not specified when
64
+ it is unreasonable for a program to detect them prior to calling the
65
+ function. — *end note*]
66
+
67
+ ### Normative references <a id="fs.norm.ref">[[fs.norm.ref]]</a>
68
+
69
+ This subclause mentions commercially available operating systems for
70
+ purposes of exposition.[^41]
71
+
72
+ ### Terms and definitions <a id="fs.definitions">[[fs.definitions]]</a>
73
+
74
+ A path that unambiguously identifies the location of a file without
75
+ reference to an additional starting location. The elements of a path
76
+ that determine if it is absolute are operating system dependent.
77
+
78
+ A file within a file system that acts as a container of directory
79
+ entries that contain information about other files, possibly including
80
+ other directory files.
81
+
82
+ An object within a file system that holds user or system data. Files can
83
+ be written to, or read from, or both. A file has certain attributes,
84
+ including type. File types include regular files and directories. Other
85
+ types of files, such as symbolic links ([[fs.def.symlink]]), may be
86
+ supported by the implementation.
87
+
88
+ A collection of files and their attributes.
89
+
90
+ The condition that occurs when multiple threads, processes, or computers
91
+ interleave access and modification of the same object within a file
92
+ system.
93
+
94
+ The name of a file. Filenames *dot* and *dot-dot*, consisting solely of
95
+ one and two period characters respectively, have special meaning. The
96
+ following characteristics of filenames are operating system dependent:
97
+
98
+ - The permitted characters. \[*Example 1*: Some operating systems
99
+ prohibit the ASCII control characters (0x00 – 0x1F) in
100
+ filenames. — *end example*]
101
+ - The maximum permitted length.
102
+ - Filenames that are not permitted.
103
+ - Filenames that have special meaning.
104
+ - Case awareness and sensitivity during path resolution.
105
+ - Special rules that may apply to file types other than regular files,
106
+ such as directories.
107
+
108
+ A link ([[fs.def.link]]) to an existing file. Some file systems support
109
+ multiple hard links to a file. If the last hard link to a file is
110
+ removed, the file itself is removed.
111
+
112
+ [*Note 1*: A hard link can be thought of as a shared-ownership smart
113
+ pointer to a file. — *end note*]
114
+
115
+ An object that associates a filename with a file. Several links can
116
+ associate names with the same file.
117
+
118
+ For narrow character strings, the operating system dependent current
119
+ encoding for pathnames ([[fs.def.pathname]]). For wide character
120
+ strings, the implementation-defined execution wide-character set
121
+ encoding ([[lex.charset]]).
122
+
123
+ The operating system dependent pathname format accepted by the host
124
+ operating system.
125
+
126
+ A path in normal form is said to be *normalized*. The process of
127
+ obtaining a normalized path from a path that is not in normal form is
128
+ called *normalization*.
129
+
130
+ Normalization of a generic format pathname means:
131
+
132
+ 1. If the path is empty, stop.
133
+ 2. Replace each slash character in the *root-name* with a
134
+ *preferred-separator*.
135
+ 3. Replace each *directory-separator* with a *preferred-separator*.
136
+ \[*Note 2*: The generic pathname grammar ([[fs.path.generic]])
137
+ defines *directory-separator* as one or more slashes and
138
+ *preferred-separator*s. — *end note*]
139
+ 4. Remove each *dot* filename and any immediately following
140
+ *directory-separator*.
141
+ 5. As long as any appear, remove a non-*dot-dot* filename immediately
142
+ followed by a *directory-separator* and a *dot-dot* filename, along
143
+ with any immediately following *directory-separator*.
144
+ 6. If there is a *root-directory*, remove all *dot-dot* filenames and
145
+ any *directory-separator*s immediately following them.
146
+ \[*Note 3*: These *dot-dot* filenames attempt to refer to
147
+ nonexistent parent directories. — *end note*]
148
+ 7. If the last filename is *dot-dot*, remove any trailing
149
+ *directory-separator*.
150
+ 8. If the path is empty, add a *dot*.
151
+
152
+ Behavior that is dependent upon the behavior and characteristics of an
153
+ operating system. See  [[fs.conform.os]].
154
+
155
+ the directory that both contains a directory entry for the given
156
+ directory and is represented by the filename *dot-dot* in the given
157
+ directory.
158
+
159
+ a directory containing a directory entry for the file under discussion.
160
+
161
+ A sequence of elements that identify the location of a file within a
162
+ filesystem. The elements are the *root-name*ₒₚₜ , *root-directory*ₒₚₜ ,
163
+ and an optional sequence of filenames. The maximum number of elements in
164
+ the sequence is operating system dependent.
165
+
166
+ A character string that represents the name of a path. Pathnames are
167
+ formatted according to the generic pathname format grammar (
168
+ [[fs.path.generic]]) or an operating system dependent native pathname
169
+ format.
170
+
171
+ Pathname resolution is the operating system dependent mechanism for
172
+ resolving a pathname to a particular file in a file hierarchy. There may
173
+ be multiple pathnames that resolve to the same file.
174
+
175
+ [*Example 2*: POSIX specifies the mechanism in section 4.11, Pathname
176
+ resolution. — *end example*]
177
+
178
+ A path that is not absolute, and as such, only unambiguously identifies
179
+ the location of a file when resolved ([[fs.def.pathres]]) relative to
180
+ an implied starting location. The elements of a path that determine if
181
+ it is relative are operating system dependent.
182
+
183
+ [*Note 4*: Pathnames “.” and “..” are relative paths. — *end note*]
184
+
185
+ A type of file with the property that when the file is encountered
186
+ during pathname resolution, a string stored by the file is used to
187
+ modify the pathname resolution.
188
+
189
+ [*Note 5*: Symbolic links are often called symlinks. A symbolic link
190
+ can be thought of as a raw pointer to a file. If the file pointed to
191
+ does not exist, the symbolic link is said to be a “dangling” symbolic
192
+ link. — *end note*]
193
+
194
+ ### Requirements <a id="fs.req">[[fs.req]]</a>
195
+
196
+ Throughout this subclause, `char`, `wchar_t`, `char16_t`, and `char32_t`
197
+ are collectively called *encoded character types*.
198
+
199
+ Functions with template parameters named `EcharT` shall not participate
200
+ in overload resolution unless `EcharT` is one of the encoded character
201
+ types.
202
+
203
+ Template parameters named `InputIterator` shall meet the input iterator
204
+ requirements ([[input.iterators]]) and shall have a value type that is
205
+ one of the encoded character types.
206
+
207
+ [*Note 1*: Use of an encoded character type implies an associated
208
+ character set and encoding. Since `signed char` and `unsigned char` have
209
+ no implied character set and encoding, they are not included as
210
+ permitted types. — *end note*]
211
+
212
+ Template parameters named `Allocator` shall meet the Allocator
213
+ requirements ([[allocator.requirements]]).
214
+
215
+ #### Namespaces and headers <a id="fs.req.namespace">[[fs.req.namespace]]</a>
216
+
217
+ Unless otherwise specified, references to entities described in this
218
+ subclause are assumed to be qualified with `::std::filesystem::`.
219
+
220
+ ### Header `<filesystem>` synopsis <a id="fs.filesystem.syn">[[fs.filesystem.syn]]</a>
221
+
222
+ ``` cpp
223
+ namespace std::filesystem {
224
+ // [fs.class.path], paths
225
+ class path;
226
+
227
+ // [fs.path.nonmember], path non-member functions
228
+ void swap(path& lhs, path& rhs) noexcept;
229
+ size_t hash_value(const path& p) noexcept;
230
+
231
+ bool operator==(const path& lhs, const path& rhs) noexcept;
232
+ bool operator!=(const path& lhs, const path& rhs) noexcept;
233
+ bool operator< (const path& lhs, const path& rhs) noexcept;
234
+ bool operator<=(const path& lhs, const path& rhs) noexcept;
235
+ bool operator> (const path& lhs, const path& rhs) noexcept;
236
+ bool operator>=(const path& lhs, const path& rhs) noexcept;
237
+
238
+ path operator/ (const path& lhs, const path& rhs);
239
+
240
+ // [fs.path.io], path inserter and extractor
241
+ template <class charT, class traits>
242
+ basic_ostream<charT, traits>&
243
+ operator<<(basic_ostream<charT, traits>& os, const path& p);
244
+ template <class charT, class traits>
245
+ basic_istream<charT, traits>&
246
+ operator>>(basic_istream<charT, traits>& is, path& p);
247
+
248
+ // [fs.path.factory], path factory functions
249
+ template <class Source>
250
+ path u8path(const Source& source);
251
+ template <class InputIterator>
252
+ path u8path(InputIterator first, InputIterator last);
253
+
254
+ // [fs.class.filesystem_error], filesystem errors
255
+ class filesystem_error;
256
+
257
+ // [fs.class.directory_entry], directory entries
258
+ class directory_entry;
259
+
260
+ // [fs.class.directory_iterator], directory iterators
261
+ class directory_iterator;
262
+
263
+ // [fs.dir.itr.nonmembers], range access for directory iterators
264
+ directory_iterator begin(directory_iterator iter) noexcept;
265
+ directory_iterator end(const directory_iterator&) noexcept;
266
+
267
+ // [fs.class.rec.dir.itr], recursive directory iterators
268
+ class recursive_directory_iterator;
269
+
270
+ // [fs.rec.dir.itr.nonmembers], range access for recursive directory iterators
271
+ recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
272
+ recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
273
+
274
+ // [fs.class.file_status], file status
275
+ class file_status;
276
+
277
+ struct space_info {
278
+ uintmax_t capacity;
279
+ uintmax_t free;
280
+ uintmax_t available;
281
+ };
282
+
283
+ // [fs.enum], enumerations
284
+ enum class file_type;
285
+ enum class perms;
286
+ enum class perm_options;
287
+ enum class copy_options;
288
+ enum class directory_options;
289
+
290
+ using file_time_type = chrono::time_point<trivial-clock>;
291
+
292
+ // [fs.op.funcs], filesystem operations
293
+ path absolute(const path& p, const path& base = current_path());
294
+
295
+ path canonical(const path& p, const path& base = current_path());
296
+ path canonical(const path& p, error_code& ec);
297
+ path canonical(const path& p, const path& base, error_code& ec);
298
+
299
+ void copy(const path& from, const path& to);
300
+ void copy(const path& from, const path& to, error_code& ec) noexcept;
301
+ void copy(const path& from, const path& to, copy_options options);
302
+ void copy(const path& from, const path& to, copy_options options,
303
+ error_code& ec) noexcept;
304
+
305
+ bool copy_file(const path& from, const path& to);
306
+ bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
307
+ bool copy_file(const path& from, const path& to, copy_options option);
308
+ bool copy_file(const path& from, const path& to, copy_options option,
309
+ error_code& ec) noexcept;
310
+
311
+ void copy_symlink(const path& existing_symlink, const path& new_symlink);
312
+ void copy_symlink(const path& existing_symlink, const path& new_symlink,
313
+ error_code& ec) noexcept;
314
+
315
+ bool create_directories(const path& p);
316
+ bool create_directories(const path& p, error_code& ec) noexcept;
317
+
318
+ bool create_directory(const path& p);
319
+ bool create_directory(const path& p, error_code& ec) noexcept;
320
+
321
+ bool create_directory(const path& p, const path& attributes);
322
+ bool create_directory(const path& p, const path& attributes,
323
+ error_code& ec) noexcept;
324
+
325
+ void create_directory_symlink(const path& to, const path& new_symlink);
326
+ void create_directory_symlink(const path& to, const path& new_symlink,
327
+ error_code& ec) noexcept;
328
+
329
+ void create_hard_link(const path& to, const path& new_hard_link);
330
+ void create_hard_link(const path& to, const path& new_hard_link,
331
+ error_code& ec) noexcept;
332
+
333
+ void create_symlink(const path& to, const path& new_symlink);
334
+ void create_symlink(const path& to, const path& new_symlink,
335
+ error_code& ec) noexcept;
336
+
337
+ path current_path();
338
+ path current_path(error_code& ec);
339
+ void current_path(const path& p);
340
+ void current_path(const path& p, error_code& ec) noexcept;
341
+
342
+ bool exists(file_status s) noexcept;
343
+ bool exists(const path& p);
344
+ bool exists(const path& p, error_code& ec) noexcept;
345
+
346
+ bool equivalent(const path& p1, const path& p2);
347
+ bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
348
+
349
+ uintmax_t file_size(const path& p);
350
+ uintmax_t file_size(const path& p, error_code& ec) noexcept;
351
+
352
+ uintmax_t hard_link_count(const path& p);
353
+ uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
354
+
355
+ bool is_block_file(file_status s) noexcept;
356
+ bool is_block_file(const path& p);
357
+ bool is_block_file(const path& p, error_code& ec) noexcept;
358
+
359
+ bool is_character_file(file_status s) noexcept;
360
+ bool is_character_file(const path& p);
361
+ bool is_character_file(const path& p, error_code& ec) noexcept;
362
+
363
+ bool is_directory(file_status s) noexcept;
364
+ bool is_directory(const path& p);
365
+ bool is_directory(const path& p, error_code& ec) noexcept;
366
+
367
+ bool is_empty(const path& p);
368
+ bool is_empty(const path& p, error_code& ec) noexcept;
369
+
370
+ bool is_fifo(file_status s) noexcept;
371
+ bool is_fifo(const path& p);
372
+ bool is_fifo(const path& p, error_code& ec) noexcept;
373
+
374
+ bool is_other(file_status s) noexcept;
375
+ bool is_other(const path& p);
376
+ bool is_other(const path& p, error_code& ec) noexcept;
377
+
378
+ bool is_regular_file(file_status s) noexcept;
379
+ bool is_regular_file(const path& p);
380
+ bool is_regular_file(const path& p, error_code& ec) noexcept;
381
+
382
+ bool is_socket(file_status s) noexcept;
383
+ bool is_socket(const path& p);
384
+ bool is_socket(const path& p, error_code& ec) noexcept;
385
+
386
+ bool is_symlink(file_status s) noexcept;
387
+ bool is_symlink(const path& p);
388
+ bool is_symlink(const path& p, error_code& ec) noexcept;
389
+
390
+ file_time_type last_write_time(const path& p);
391
+ file_time_type last_write_time(const path& p, error_code& ec) noexcept;
392
+ void last_write_time(const path& p, file_time_type new_time);
393
+ void last_write_time(const path& p, file_time_type new_time,
394
+ error_code& ec) noexcept;
395
+
396
+ void permissions(const path& p, perms prms, perm_options opts=perm_options::replace);
397
+ void permissions(const path& p, perms prms, error_code& ec) noexcept;
398
+ void permissions(const path& p, perms prms, perm_options opts, error_code& ec);
399
+
400
+ path proximate(const path& p, error_code& ec);
401
+ path proximate(const path& p, const path& base = current_path());
402
+ path proximate(const path& p, const path& base, error_code& ec);
403
+
404
+ path read_symlink(const path& p);
405
+ path read_symlink(const path& p, error_code& ec);
406
+
407
+ path relative(const path& p, error_code& ec);
408
+ path relative(const path& p, const path& base = current_path());
409
+ path relative(const path& p, const path& base, error_code& ec);
410
+
411
+ bool remove(const path& p);
412
+ bool remove(const path& p, error_code& ec) noexcept;
413
+
414
+ uintmax_t remove_all(const path& p);
415
+ uintmax_t remove_all(const path& p, error_code& ec) noexcept;
416
+
417
+ void rename(const path& from, const path& to);
418
+ void rename(const path& from, const path& to, error_code& ec) noexcept;
419
+
420
+ void resize_file(const path& p, uintmax_t size);
421
+ void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
422
+
423
+ space_info space(const path& p);
424
+ space_info space(const path& p, error_code& ec) noexcept;
425
+
426
+ file_status status(const path& p);
427
+ file_status status(const path& p, error_code& ec) noexcept;
428
+
429
+ bool status_known(file_status s) noexcept;
430
+
431
+ file_status symlink_status(const path& p);
432
+ file_status symlink_status(const path& p, error_code& ec) noexcept;
433
+
434
+ path temp_directory_path();
435
+ path temp_directory_path(error_code& ec);
436
+
437
+ path weakly_canonical(const path& p);
438
+ path weakly_canonical(const path& p, error_code& ec);
439
+ }
440
+ ```
441
+
442
+ `trivial-clock` is an *implementation-defined* type that satisfies the
443
+ `TrivialClock` requirements ([[time.clock.req]]) and that is capable of
444
+ representing and measuring file time values. Implementations should
445
+ ensure that the resolution and range of `file_time_type` reflect the
446
+ operating system dependent resolution and range of file time values.
447
+
448
+ ### Error reporting <a id="fs.err.report">[[fs.err.report]]</a>
449
+
450
+ Filesystem library functions often provide two overloads, one that
451
+ throws an exception to report file system errors, and another that sets
452
+ an `error_code`.
453
+
454
+ [*Note 1*:
455
+
456
+ This supports two common use cases:
457
+
458
+ - Uses where file system errors are truly exceptional and indicate a
459
+ serious failure. Throwing an exception is an appropriate response.
460
+ - Uses where file system errors are routine and do not necessarily
461
+ represent failure. Returning an error code is the most appropriate
462
+ response. This allows application specific error handling, including
463
+ simply ignoring the error.
464
+
465
+ — *end note*]
466
+
467
+ Functions not having an argument of type `error_code&` handle errors as
468
+ follows, unless otherwise specified:
469
+
470
+ - When a call by the implementation to an operating system or other
471
+ underlying API results in an error that prevents the function from
472
+ meeting its specifications, an exception of type `filesystem_error`
473
+ shall be thrown. For functions with a single path argument, that
474
+ argument shall be passed to the `filesystem_error` constructor with a
475
+ single path argument. For functions with two path arguments, the first
476
+ of these arguments shall be passed to the `filesystem_error`
477
+ constructor as the `path1` argument, and the second shall be passed as
478
+ the `path2` argument. The `filesystem_error` constructor’s
479
+ `error_code` argument is set as appropriate for the specific operating
480
+ system dependent error.
481
+ - Failure to allocate storage is reported by throwing an exception as
482
+ described in  [[res.on.exception.handling]].
483
+ - Destructors throw nothing.
484
+
485
+ Functions having an argument of type `error_code&` handle errors as
486
+ follows, unless otherwise specified:
487
+
488
+ - If a call by the implementation to an operating system or other
489
+ underlying API results in an error that prevents the function from
490
+ meeting its specifications, the `error_code&` argument is set as
491
+ appropriate for the specific operating system dependent error.
492
+ Otherwise, `clear()` is called on the `error_code&` argument.
493
+
494
+ ### Class `path` <a id="fs.class.path">[[fs.class.path]]</a>
495
+
496
+ An object of class `path` represents a path ([[fs.def.path]]) and
497
+ contains a pathname ([[fs.def.pathname]]). Such an object is concerned
498
+ only with the lexical and syntactic aspects of a path. The path does not
499
+ necessarily exist in external storage, and the pathname is not
500
+ necessarily valid for the current operating system or for a particular
501
+ file system.
502
+
503
+ [*Note 1*: Class `path` is used to support the differences between the
504
+ string types used by different operating systems to represent pathnames,
505
+ and to perform conversions between encodings when
506
+ necessary. — *end note*]
507
+
508
+ ``` cpp
509
+ namespace std::filesystem {
510
+ class path {
511
+ public:
512
+ using value_type = see below;
513
+ using string_type = basic_string<value_type>;
514
+ static constexpr value_type preferred_separator = see below;
515
+
516
+ // [fs.enum.path.format], enumeration format
517
+ enum format;
518
+
519
+ // [fs.path.construct], constructors and destructor
520
+ path() noexcept;
521
+ path(const path& p);
522
+ path(path&& p) noexcept;
523
+ path(string_type&& source, format fmt = auto_format);
524
+ template <class Source>
525
+ path(const Source& source, format fmt = auto_format);
526
+ template <class InputIterator>
527
+ path(InputIterator first, InputIterator last, format fmt = auto_format);
528
+ template <class Source>
529
+ path(const Source& source, const locale& loc, format fmt = auto_format);
530
+ template <class InputIterator>
531
+ path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format);
532
+ ~path();
533
+
534
+ // [fs.path.assign], assignments
535
+ path& operator=(const path& p);
536
+ path& operator=(path&& p) noexcept;
537
+ path& operator=(string_type&& source);
538
+ path& assign(string_type&& source);
539
+ template <class Source>
540
+ path& operator=(const Source& source);
541
+ template <class Source>
542
+ path& assign(const Source& source)
543
+ template <class InputIterator>
544
+ path& assign(InputIterator first, InputIterator last);
545
+
546
+ // [fs.path.append], appends
547
+ path& operator/=(const path& p);
548
+ template <class Source>
549
+ path& operator/=(const Source& source);
550
+ template <class Source>
551
+ path& append(const Source& source);
552
+ template <class InputIterator>
553
+ path& append(InputIterator first, InputIterator last);
554
+
555
+ // [fs.path.concat], concatenation
556
+ path& operator+=(const path& x);
557
+ path& operator+=(const string_type& x);
558
+ path& operator+=(basic_string_view<value_type> x);
559
+ path& operator+=(const value_type* x);
560
+ path& operator+=(value_type x);
561
+ template <class Source>
562
+ path& operator+=(const Source& x);
563
+ template <class EcharT>
564
+ path& operator+=(EcharT x);
565
+ template <class Source>
566
+ path& concat(const Source& x);
567
+ template <class InputIterator>
568
+ path& concat(InputIterator first, InputIterator last);
569
+
570
+ // [fs.path.modifiers], modifiers
571
+ void clear() noexcept;
572
+ path& make_preferred();
573
+ path& remove_filename();
574
+ path& replace_filename(const path& replacement);
575
+ path& replace_extension(const path& replacement = path());
576
+ void swap(path& rhs) noexcept;
577
+
578
+ // [fs.path.native.obs], native format observers
579
+ const string_type& native() const noexcept;
580
+ const value_type* c_str() const noexcept;
581
+ operator string_type() const;
582
+
583
+ template <class EcharT, class traits = char_traits<EcharT>,
584
+ class Allocator = allocator<EcharT>>
585
+ basic_string<EcharT, traits, Allocator>
586
+ string(const Allocator& a = Allocator()) const;
587
+ std::string string() const;
588
+ std::wstring wstring() const;
589
+ std::string u8string() const;
590
+ std::u16string u16string() const;
591
+ std::u32string u32string() const;
592
+
593
+ // [fs.path.generic.obs], generic format observers
594
+ template <class EcharT, class traits = char_traits<EcharT>,
595
+ class Allocator = allocator<EcharT>>
596
+ basic_string<EcharT, traits, Allocator>
597
+ generic_string(const Allocator& a = Allocator()) const;
598
+ std::string generic_string() const;
599
+ std::wstring generic_wstring() const;
600
+ std::string generic_u8string() const;
601
+ std::u16string generic_u16string() const;
602
+ std::u32string generic_u32string() const;
603
+
604
+ // [fs.path.compare], compare
605
+ int compare(const path& p) const noexcept;
606
+ int compare(const string_type& s) const;
607
+ int compare(basic_string_view<value_type> s) const;
608
+ int compare(const value_type* s) const;
609
+
610
+ // [fs.path.decompose], decomposition
611
+ path root_name() const;
612
+ path root_directory() const;
613
+ path root_path() const;
614
+ path relative_path() const;
615
+ path parent_path() const;
616
+ path filename() const;
617
+ path stem() const;
618
+ path extension() const;
619
+
620
+ // [fs.path.query], query
621
+ bool empty() const noexcept;
622
+ bool has_root_name() const;
623
+ bool has_root_directory() const;
624
+ bool has_root_path() const;
625
+ bool has_relative_path() const;
626
+ bool has_parent_path() const;
627
+ bool has_filename() const;
628
+ bool has_stem() const;
629
+ bool has_extension() const;
630
+ bool is_absolute() const;
631
+ bool is_relative() const;
632
+
633
+ // [fs.path.gen], generation
634
+ path lexically_normal() const;
635
+ path lexically_relative(const path& base) const;
636
+ path lexically_proximate(const path& base) const;
637
+
638
+ // [fs.path.itr], iterators
639
+ class iterator;
640
+ using const_iterator = iterator;
641
+
642
+ iterator begin() const;
643
+ iterator end() const;
644
+ };
645
+ }
646
+ ```
647
+
648
+ `value_type` is a `typedef` for the operating system dependent encoded
649
+ character type used to represent pathnames.
650
+
651
+ The value of the `preferred_separator` member is the operating system
652
+ dependent *preferred-separator* character ([[fs.path.generic]]).
653
+
654
+ [*Example 1*: For POSIX-based operating systems, `value_type` is `char`
655
+ and `preferred_separator` is the slash character (`'/'`). For
656
+ Windows-based operating systems, `value_type` is `wchar_t` and
657
+ `preferred_separator` is the backslash character
658
+ (`L'\\'`). — *end example*]
659
+
660
+ #### Generic pathname format <a id="fs.path.generic">[[fs.path.generic]]</a>
661
+
662
+ ``` bnf
663
+ pathname:
664
+ root-nameₒₚₜ root-directoryₒₚₜ relative-path
665
+ ```
666
+
667
+ ``` bnf
668
+ root-name:
669
+ operating system dependent sequences of characters
670
+ implementation-defined sequences of characters
671
+ ```
672
+
673
+ ``` bnf
674
+ root-directory:
675
+ directory-separator
676
+ ```
677
+
678
+ ``` bnf
679
+ relative-path:
680
+ filename
681
+ filename directory-separator relative-path
682
+ an empty path
683
+ ```
684
+
685
+ ``` bnf
686
+ filename:
687
+ non-empty sequence of characters other than *directory-separator* characters
688
+ ```
689
+
690
+ ``` bnf
691
+ directory-separator:
692
+ preferred-separator directory-separatorₒₚₜ
693
+ fallback-separator directory-separatorₒₚₜ
694
+ ```
695
+
696
+ ``` bnf
697
+ preferred-separator:
698
+ operating system dependent directory separator character
699
+ ```
700
+
701
+ ``` bnf
702
+ fallback-separator:
703
+ /, if *preferred-separator* is not /
704
+ ```
705
+
706
+ [*Note 1*: Operating systems often place restrictions on the characters
707
+ that may be used in a *filename*. For wide portability, users may wish
708
+ to limit *filename* characters to the POSIX Portable Filename Character
709
+ Set:
710
+ `A B C D E F G H I J K L M N O P Q R S T U V W X Y Z`
711
+ `a b c d e f g h i j k l m n o p q r s t u v w x y z`
712
+ `0 1 2 3 4 5 6 7 8 9 . _ -` — *end note*]
713
+
714
+ Except in a *root-name*, multiple successive *directory-separator*
715
+ characters are considered to be the same as one *directory-separator*
716
+ character.
717
+
718
+ The filename *dot* ([[fs.def.filename]]) is treated as a reference to
719
+ the current directory. The filename *dot-dot* ([[fs.def.filename]]) is
720
+ treated as a reference to the parent directory. What the filename
721
+ *dot-dot* refers to relative to *root-directory* is
722
+ *implementation-defined*. Specific filenames may have special meanings
723
+ for a particular operating system.
724
+
725
+ A *root-name* identifies the starting location for pathname resolution (
726
+ [[fs.def.pathres]]). If there are no operating system dependent
727
+ *root-name*s, at least one *implementation-defined* *root-name* is
728
+ required.
729
+
730
+ [*Note 2*: Many operating systems define a name beginning with two
731
+ *directory-separator* characters as a *root-name* that identifies
732
+ network or other resource locations. Some operating systems define a
733
+ single letter followed by a colon as a drive specifier – a *root-name*
734
+ identifying a specific device such as a disk drive. — *end note*]
735
+
736
+ If a *root-name* is otherwise ambiguous, the possibility with the
737
+ longest sequence of characters is chosen.
738
+
739
+ [*Note 3*: On a POSIX-like operating system, it is impossible to have a
740
+ *root-name* and a *relative-path* without an intervening
741
+ *root-directory* element. — *end note*]
742
+
743
+ #### `path` conversions <a id="fs.path.cvt">[[fs.path.cvt]]</a>
744
+
745
+ ##### `path` argument format conversions <a id="fs.path.fmt.cvt">[[fs.path.fmt.cvt]]</a>
746
+
747
+ [*Note 1*:
748
+
749
+ The format conversions described in this section are not applied on
750
+ POSIX-based operating systems because on these systems:
751
+
752
+ - The generic format is acceptable as a native path.
753
+ - There is no need to distinguish between native format and generic
754
+ format in function arguments.
755
+ - Paths for regular files and paths for directories share the same
756
+ syntax.
757
+
758
+ — *end note*]
759
+
760
+ Several functions are defined to accept *detected-format* arguments,
761
+ which are character sequences. A detected-format argument represents a
762
+ path using either a pathname in the generic format (
763
+ [[fs.path.generic]]) or a pathname in the native format (
764
+ [[fs.def.native]]). Such an argument is taken to be in the generic
765
+ format if and only if it matches the generic format and is not
766
+ acceptable to the operating system as a native path.
767
+
768
+ [*Note 2*: Some operating systems may have no unambiguous way to
769
+ distinguish between native format and generic format arguments. This is
770
+ by design as it simplifies use for operating systems that do not require
771
+ disambiguation. An implementation for an operating system where
772
+ disambiguation is required is permitted to distinguish between the
773
+ formats. — *end note*]
774
+
775
+ Pathnames are converted as needed between the generic and native formats
776
+ in an operating-system-dependent manner. Let *G(n)* and *N(g)* in a
777
+ mathematical sense be the implementation’s functions that convert
778
+ native-to-generic and generic-to-native formats respectively. If
779
+ *g=G(n)* for some *n*, then *G(N(g))=g*; if *n=N(g)* for some *g*, then
780
+ *N(G(n))=n*.
781
+
782
+ [*Note 3*: Neither *G* nor *N* need be invertible. — *end note*]
783
+
784
+ If the native format requires paths for regular files to be formatted
785
+ differently from paths for directories, the path shall be treated as a
786
+ directory path if its last element is a *directory-separator*, otherwise
787
+ it shall be treated as a path to a regular file.
788
+
789
+ [*Note 4*: A path stores a native format pathname (
790
+ [[fs.path.native.obs]]) and acts as if it also stores a generic format
791
+ pathname, related as given below. The implementation may generate the
792
+ generic format pathname based on the native format pathname (and
793
+ possibly other information) when requested. — *end note*]
794
+
795
+ When a path is constructed from or is assigned a single representation
796
+ separate from any path, the other representation is selected by the
797
+ appropriate conversion function (*G* or *N*).
798
+
799
+ When the (new) value *p* of one representation of a path is derived from
800
+ the representation of that or another path, a value *q* is chosen for
801
+ the other representation. The value *q* converts to *p* (by *G* or *N*
802
+ as appropriate) if any such value does so; *q* is otherwise unspecified.
803
+
804
+ [*Note 5*: If *q* is the result of converting any path at all, it is
805
+ the result of converting *p*. — *end note*]
806
+
807
+ ##### `path` type and encoding conversions <a id="fs.path.type.cvt">[[fs.path.type.cvt]]</a>
808
+
809
+ For member function arguments that take character sequences representing
810
+ paths and for member functions returning strings, value type and
811
+ encoding conversion is performed if the value type of the argument or
812
+ return value differs from `path::value_type`. For the argument or return
813
+ value, the method of conversion and the encoding to be converted to is
814
+ determined by its value type:
815
+
816
+ - `char`: The encoding is the native narrow encoding (
817
+ [[fs.def.native.encode]]). The method of conversion, if any, is
818
+ operating system dependent. \[*Note 6*: For POSIX-based operating
819
+ systems `path::value_type` is `char` so no conversion from `char`
820
+ value type arguments or to `char` value type return values is
821
+ performed. For Windows-based operating systems, the native narrow
822
+ encoding is determined by calling a Windows API
823
+ function. — *end note*] \[*Note 7*: This results in behavior
824
+ identical to other C and C++ standard library functions that perform
825
+ file operations using narrow character strings to identify paths.
826
+ Changing this behavior would be surprising and error
827
+ prone. — *end note*]
828
+ - `wchar_t`: The encoding is the native wide encoding (
829
+ [[fs.def.native.encode]]). The method of conversion is unspecified.
830
+ \[*Note 8*: For Windows-based operating systems `path::value_type` is
831
+ `wchar_t` so no conversion from `wchar_t` value type arguments or to
832
+ `wchar_t` value type return values is performed. — *end note*]
833
+ - `char16_t`: The encoding is UTF-16. The method of conversion is
834
+ unspecified.
835
+ - `char32_t`: The encoding is UTF-32. The method of conversion is
836
+ unspecified.
837
+
838
+ If the encoding being converted to has no representation for source
839
+ characters, the resulting converted characters, if any, are unspecified.
840
+ Implementations should not modify member function arguments if already
841
+ of type `path::value_type`.
842
+
843
+ #### `path` requirements <a id="fs.path.req">[[fs.path.req]]</a>
844
+
845
+ In addition to the requirements ([[fs.req]]), function template
846
+ parameters named `Source` shall be one of:
847
+
848
+ - `basic_string<EcharT, traits, Allocator>`. A function argument
849
+ `const Source&` `source` shall have an effective range
850
+ \[`source.begin()`, `source.end()`).
851
+ - `basic_string_view<EcharT, traits>`. A function argument
852
+ `const Source&` `source` shall have an effective range
853
+ \[`source.begin()`, `source.end()`).
854
+ - A type meeting the input iterator requirements that iterates over a
855
+ NTCTS. The value type shall be an encoded character type. A function
856
+ argument `const Source&` `source` shall have an effective range
857
+ \[`source`, `end`) where `end` is the first iterator value with an
858
+ element value equal to `iterator_traits<Source>::value_type()`.
859
+ - A character array that after array-to-pointer decay results in a
860
+ pointer to the start of a NTCTS. The value type shall be an encoded
861
+ character type. A function argument `const Source&` `source` shall
862
+ have an effective range \[`source`, `end`) where `end` is the first
863
+ iterator value with an element value equal to
864
+ `iterator_traits<decay_t<Source>>::value_type()`.
865
+
866
+ Functions taking template parameters named `Source` shall not
867
+ participate in overload resolution unless either
868
+
869
+ - `Source` is a specialization of `basic_string` or `basic_string_view`,
870
+ or
871
+ - the *qualified-id* `iterator_traits<decay_t<Source>>::value_type` is
872
+ valid and denotes a possibly `const` encoded character type (
873
+ [[temp.deduct]]).
874
+
875
+ [*Note 1*: See path conversions ([[fs.path.cvt]]) for how the value
876
+ types above and their encodings convert to `path::value_type` and its
877
+ encoding. — *end note*]
878
+
879
+ Arguments of type `Source` shall not be null pointers.
880
+
881
+ #### `path` members <a id="fs.path.member">[[fs.path.member]]</a>
882
+
883
+ ##### `path` constructors <a id="fs.path.construct">[[fs.path.construct]]</a>
884
+
885
+ ``` cpp
886
+ path() noexcept;
887
+ ```
888
+
889
+ *Effects:* Constructs an object of class `path`.
890
+
891
+ *Postconditions:* `empty() == true`.
892
+
893
+ ``` cpp
894
+ path(const path& p);
895
+ path(path&& p) noexcept;
896
+ ```
897
+
898
+ *Effects:* Constructs an object of class `path` having the same pathname
899
+ in the native and generic formats, respectively, as the original value
900
+ of `p`. In the second form, `p` is left in a valid but unspecified
901
+ state.
902
+
903
+ ``` cpp
904
+ path(string_type&& source, format fmt = auto_format);
905
+ ```
906
+
907
+ *Effects:* Constructs an object of class `path` for which the pathname
908
+ in the detected-format of `source` has the original value of
909
+ `source` ([[fs.path.fmt.cvt]]), converting format if
910
+ required ([[fs.path.fmt.cvt]]). `source` is left in a valid but
911
+ unspecified state.
912
+
913
+ ``` cpp
914
+ template <class Source>
915
+ path(const Source& source, format fmt = auto_format);
916
+ template <class InputIterator>
917
+ path(InputIterator first, InputIterator last, format fmt = auto_format);
918
+ ```
919
+
920
+ *Effects:* Let `s` be the effective range of `source` ([[fs.path.req]])
921
+ or the range \[`first`, `last`), with the encoding converted if
922
+ required ([[fs.path.cvt]]). Finds the detected-format of
923
+ `s` ([[fs.path.fmt.cvt]]) and constructs an object of class `path` for
924
+ which the pathname in that format is `s`.
925
+
926
+ ``` cpp
927
+ template <class Source>
928
+ path(const Source& source, const locale& loc, format fmt = auto_format);
929
+ template <class InputIterator>
930
+ path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format);
931
+ ```
932
+
933
+ *Requires:* The value type of `Source` and `InputIterator` is `char`.
934
+
935
+ *Effects:* Let `s` be the effective range of `source` or the range
936
+ \[`first`, `last`), after converting the encoding as follows:
937
+
938
+ - If `value_type` is `wchar_t`, converts to the native wide
939
+ encoding ([[fs.def.native.encode]]) using the
940
+ `codecvt<wchar_t, char, mbstate_t>` facet of `loc`.
941
+ - Otherwise a conversion is performed using the
942
+ `codecvt<wchar_t, char, mbstate_t>` facet of `loc`, and then a second
943
+ conversion to the current narrow encoding.
944
+
945
+ Finds the detected-format of `s` ([[fs.path.fmt.cvt]]) and constructs
946
+ an object of class `path` for which the pathname in that format is `s`.
947
+
948
+ [*Example 1*:
949
+
950
+ A string is to be read from a database that is encoded in ISO/IEC
951
+ 8859-1, and used to create a directory:
952
+
953
+ ``` cpp
954
+ namespace fs = std::filesystem;
955
+ std::string latin1_string = read_latin1_data();
956
+ codecvt_8859_1<wchar_t> latin1_facet;
957
+ std::locale latin1_locale(std::locale(), latin1_facet);
958
+ fs::create_directory(fs::path(latin1_string, latin1_locale));
959
+ ```
960
+
961
+ For POSIX-based operating systems, the path is constructed by first
962
+ using `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string`
963
+ to a wide character string in the native wide
964
+ encoding ([[fs.def.native.encode]]). The resulting wide string is then
965
+ converted to a narrow character pathname string in the current native
966
+ narrow encoding. If the native wide encoding is UTF-16 or UTF-32, and
967
+ the current native narrow encoding is UTF-8, all of the characters in
968
+ the ISO/IEC 8859-1 character set will be converted to their Unicode
969
+ representation, but for other native narrow encodings some characters
970
+ may have no representation.
971
+
972
+ For Windows-based operating systems, the path is constructed by using
973
+ `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string` to a
974
+ UTF-16 encoded wide character pathname string. All of the characters in
975
+ the ISO/IEC 8859-1 character set will be converted to their Unicode
976
+ representation.
977
+
978
+ — *end example*]
979
+
980
+ ##### `path` assignments <a id="fs.path.assign">[[fs.path.assign]]</a>
981
+
982
+ ``` cpp
983
+ path& operator=(const path& p);
984
+ ```
985
+
986
+ *Effects:* If `*this` and `p` are the same object, has no effect.
987
+ Otherwise, sets both respective pathnames of `*this` to the respective
988
+ pathnames of `p`.
989
+
990
+ *Returns:* `*this`.
991
+
992
+ ``` cpp
993
+ path& operator=(path&& p) noexcept;
994
+ ```
995
+
996
+ *Effects:* If `*this` and `p` are the same object, has no effect.
997
+ Otherwise, sets both respective pathnames of `*this` to the respective
998
+ pathnames of `p`. `p` is left in a valid but unspecified state.
999
+
1000
+ [*Note 1*: A valid implementation is `swap(p)`. — *end note*]
1001
+
1002
+ *Returns:* `*this`.
1003
+
1004
+ ``` cpp
1005
+ path& operator=(string_type&& source);
1006
+ path& assign(string_type&& source);
1007
+ ```
1008
+
1009
+ *Effects:* Sets the pathname in the detected-format of `source` to the
1010
+ original value of `source`. `source` is left in a valid but unspecified
1011
+ state.
1012
+
1013
+ *Returns:* `*this`.
1014
+
1015
+ ``` cpp
1016
+ template <class Source>
1017
+ path& operator=(const Source& source);
1018
+ template <class Source>
1019
+ path& assign(const Source& source);
1020
+ template <class InputIterator>
1021
+ path& assign(InputIterator first, InputIterator last);
1022
+ ```
1023
+
1024
+ *Effects:* Let `s` be the effective range of `source` ([[fs.path.req]])
1025
+ or the range \[`first`, `last`), with the encoding converted if
1026
+ required ([[fs.path.cvt]]). Finds the detected-format of
1027
+ `s` ([[fs.path.fmt.cvt]]) and sets the pathname in that format to `s`.
1028
+
1029
+ *Returns:* `*this`.
1030
+
1031
+ ##### `path` appends <a id="fs.path.append">[[fs.path.append]]</a>
1032
+
1033
+ The append operations use `operator/=` to denote their semantic effect
1034
+ of appending *preferred-separator* when needed.
1035
+
1036
+ ``` cpp
1037
+ path& operator/=(const path& p);
1038
+ ```
1039
+
1040
+ *Effects:* If
1041
+ `p.is_absolute() || (p.has_root_name() && p.root_name() != root_name())`,
1042
+ then `operator=(p)`.
1043
+
1044
+ Otherwise, modifies `*this` as if by these steps:
1045
+
1046
+ - If `p.has_root_directory()`, then removes any root directory and
1047
+ relative path from the generic format pathname. Otherwise, if
1048
+ `!has_root_directory() && is_absolute()` is `true` or if
1049
+ `has_filename()` is `true`, then appends `path::preferred_separator`
1050
+ to the generic format pathname.
1051
+ - Then appends the native format pathname of `p`, omitting any
1052
+ *root-name* from its generic format pathname, to the native format
1053
+ pathname.
1054
+
1055
+ [*Example 2*:
1056
+
1057
+ Even if `//host` is interpreted as a *root-name*, both of the paths
1058
+ `path("//host")/"foo"` and `path("//host/")/"foo"` equal `"//host/foo"`.
1059
+
1060
+ Expression examples:
1061
+
1062
+ ``` cpp
1063
+ // On POSIX,
1064
+ path("foo") / ""; // yields "foo/"
1065
+ path("foo") / "/bar"; // yields "/bar"
1066
+ // On Windows, backslashes replace slashes in the above yields
1067
+
1068
+ // On Windows,
1069
+ path("foo") / "c:/bar"; // yields "c:/bar"
1070
+ path("foo") / "c:"; // yields "c:"
1071
+ path("c:") / ""; // yields "c:"
1072
+ path("c:foo") / "/bar"; // yields "c:/bar"
1073
+ path("c:foo") / "c:bar"; // yields "c:foo/bar"
1074
+ ```
1075
+
1076
+ — *end example*]
1077
+
1078
+ *Returns:* `*this`.
1079
+
1080
+ ``` cpp
1081
+ template <class Source>
1082
+ path& operator/=(const Source& source);
1083
+ template <class Source>
1084
+ path& append(const Source& source);
1085
+ ```
1086
+
1087
+ *Effects:* Equivalent to: `return operator/=(path(source));`
1088
+
1089
+ ``` cpp
1090
+ template <class InputIterator>
1091
+ path& append(InputIterator first, InputIterator last);
1092
+ ```
1093
+
1094
+ *Effects:* Equivalent to: `return operator/=(path(first, last));`
1095
+
1096
+ ##### `path` concatenation <a id="fs.path.concat">[[fs.path.concat]]</a>
1097
+
1098
+ ``` cpp
1099
+ path& operator+=(const path& x);
1100
+ path& operator+=(const string_type& x);
1101
+ path& operator+=(basic_string_view<value_type> x);
1102
+ path& operator+=(const value_type* x);
1103
+ path& operator+=(value_type x);
1104
+ template <class Source>
1105
+ path& operator+=(const Source& x);
1106
+ template <class EcharT>
1107
+ path& operator+=(EcharT x);
1108
+ template <class Source>
1109
+ path& concat(const Source& x);
1110
+ ```
1111
+
1112
+ *Effects:* Appends `path(x).native()` to the pathname in the native
1113
+ format.
1114
+
1115
+ [*Note 2*: This directly manipulates the value of `native()` and may
1116
+ not be portable between operating systems. — *end note*]
1117
+
1118
+ *Returns:* `*this`.
1119
+
1120
+ ``` cpp
1121
+ template <class InputIterator>
1122
+ path& concat(InputIterator first, InputIterator last);
1123
+ ```
1124
+
1125
+ *Effects:* Equivalent to `return *this += path(first, last)`.
1126
+
1127
+ ##### `path` modifiers <a id="fs.path.modifiers">[[fs.path.modifiers]]</a>
1128
+
1129
+ ``` cpp
1130
+ void clear() noexcept;
1131
+ ```
1132
+
1133
+ *Postconditions:* `empty() == true`.
1134
+
1135
+ ``` cpp
1136
+ path& make_preferred();
1137
+ ```
1138
+
1139
+ *Effects:* Each *directory-separator* of the pathname in the generic
1140
+ format is converted to *preferred-separator*.
1141
+
1142
+ *Returns:* `*this`.
1143
+
1144
+ [*Example 3*:
1145
+
1146
+ ``` cpp
1147
+ path p("foo/bar");
1148
+ std::cout << p << '\n';
1149
+ p.make_preferred();
1150
+ std::cout << p << '\n';
1151
+ ```
1152
+
1153
+ On an operating system where *preferred-separator* is a slash, the
1154
+ output is:
1155
+
1156
+ ``` cpp
1157
+ "foo/bar"
1158
+ "foo/bar"
1159
+ ```
1160
+
1161
+ On an operating system where *preferred-separator* is a backslash, the
1162
+ output is:
1163
+
1164
+ ``` cpp
1165
+ "foo/bar"
1166
+ "foo\bar"
1167
+ ```
1168
+
1169
+ — *end example*]
1170
+
1171
+ ``` cpp
1172
+ path& remove_filename();
1173
+ ```
1174
+
1175
+ *Postconditions:* `!has_filename()`.
1176
+
1177
+ *Effects:* Remove the generic format pathname of `filename()` from the
1178
+ generic format pathname.
1179
+
1180
+ *Returns:* `*this`.
1181
+
1182
+ [*Example 4*:
1183
+
1184
+ ``` cpp
1185
+ path("foo/bar").remove_filename(); // yields "foo/"
1186
+ path("foo/").remove_filename(); // yields "foo/"
1187
+ path("/foo").remove_filename(); // yields "/"
1188
+ path("/").remove_filename(); // yields "/"
1189
+ ```
1190
+
1191
+ — *end example*]
1192
+
1193
+ ``` cpp
1194
+ path& replace_filename(const path& replacement);
1195
+ ```
1196
+
1197
+ *Effects:* Equivalent to:
1198
+
1199
+ ``` cpp
1200
+ remove_filename();
1201
+ operator/=(replacement);
1202
+ ```
1203
+
1204
+ *Returns:* `*this`.
1205
+
1206
+ [*Example 5*:
1207
+
1208
+ ``` cpp
1209
+ path("/foo").replace_filename("bar"); // yields "/bar" on POSIX
1210
+ path("/").replace_filename("bar"); // yields "/bar" on POSIX
1211
+ ```
1212
+
1213
+ — *end example*]
1214
+
1215
+ ``` cpp
1216
+ path& replace_extension(const path& replacement = path());
1217
+ ```
1218
+
1219
+ *Effects:*
1220
+
1221
+ - Any existing `extension()(` [[fs.path.decompose]]`)` is removed from
1222
+ the pathname in the generic format, then
1223
+ - If `replacement` is not empty and does not begin with a dot character,
1224
+ a dot character is appended to the pathname in the generic format,
1225
+ then
1226
+ - `operator+=(replacement);`.
1227
+
1228
+ *Returns:* `*this`.
1229
+
1230
+ ``` cpp
1231
+ void swap(path& rhs) noexcept;
1232
+ ```
1233
+
1234
+ *Effects:* Swaps the contents (in all formats) of the two paths.
1235
+
1236
+ *Complexity:* Constant time.
1237
+
1238
+ ##### `path` native format observers <a id="fs.path.native.obs">[[fs.path.native.obs]]</a>
1239
+
1240
+ The string returned by all native format observers is in the native
1241
+ pathname format ([[fs.def.native]]).
1242
+
1243
+ ``` cpp
1244
+ const string_type& native() const noexcept;
1245
+ ```
1246
+
1247
+ *Returns:* The pathname in the native format.
1248
+
1249
+ ``` cpp
1250
+ const value_type* c_str() const noexcept;
1251
+ ```
1252
+
1253
+ *Returns:* Equivalent to `native().c_str()`.
1254
+
1255
+ ``` cpp
1256
+ operator string_type() const;
1257
+ ```
1258
+
1259
+ *Returns:* `native()`.
1260
+
1261
+ [*Note 3*: Conversion to `string_type` is provided so that an object of
1262
+ class `path` can be given as an argument to existing standard library
1263
+ file stream constructors and open functions. — *end note*]
1264
+
1265
+ ``` cpp
1266
+ template <class EcharT, class traits = char_traits<EcharT>,
1267
+ class Allocator = allocator<EcharT>>
1268
+ basic_string<EcharT, traits, Allocator>
1269
+ string(const Allocator& a = Allocator()) const;
1270
+ ```
1271
+
1272
+ *Returns:* `native()`.
1273
+
1274
+ *Remarks:* All memory allocation, including for the return value, shall
1275
+ be performed by `a`. Conversion, if any, is specified by
1276
+ [[fs.path.cvt]].
1277
+
1278
+ ``` cpp
1279
+ std::string string() const;
1280
+ std::wstring wstring() const;
1281
+ std::string u8string() const;
1282
+ std::u16string u16string() const;
1283
+ std::u32string u32string() const;
1284
+ ```
1285
+
1286
+ *Returns:* `pathstring`.
1287
+
1288
+ *Remarks:* Conversion, if any, is performed as specified by
1289
+ [[fs.path.cvt]]. The encoding of the string returned by `u8string()` is
1290
+ always UTF-8.
1291
+
1292
+ ##### `path` generic format observers <a id="fs.path.generic.obs">[[fs.path.generic.obs]]</a>
1293
+
1294
+ Generic format observer functions return strings formatted according to
1295
+ the generic pathname format ([[fs.path.generic]]). A single slash
1296
+ (`'/'`) character is used as the *directory-separator*.
1297
+
1298
+ [*Example 1*:
1299
+
1300
+ On an operating system that uses backslash as its *preferred-separator*,
1301
+
1302
+ ``` cpp
1303
+ path("foo\\bar").generic_string()
1304
+ ```
1305
+
1306
+ returns `"foo/bar"`.
1307
+
1308
+ — *end example*]
1309
+
1310
+ ``` cpp
1311
+ template <class EcharT, class traits = char_traits<EcharT>,
1312
+ class Allocator = allocator<EcharT>>
1313
+ basic_string<EcharT, traits, Allocator>
1314
+ generic_string(const Allocator& a = Allocator()) const;
1315
+ ```
1316
+
1317
+ *Returns:* The pathname in the generic format.
1318
+
1319
+ *Remarks:* All memory allocation, including for the return value, shall
1320
+ be performed by `a`. Conversion, if any, is specified by
1321
+ [[fs.path.cvt]].
1322
+
1323
+ ``` cpp
1324
+ std::string generic_string() const;
1325
+ std::wstring generic_wstring() const;
1326
+ std::string generic_u8string() const;
1327
+ std::u16string generic_u16string() const;
1328
+ std::u32string generic_u32string() const;
1329
+ ```
1330
+
1331
+ *Returns:* The pathname in the generic format.
1332
+
1333
+ *Remarks:* Conversion, if any, is specified by  [[fs.path.cvt]]. The
1334
+ encoding of the string returned by `generic_u8string()` is always UTF-8.
1335
+
1336
+ ##### `path` compare <a id="fs.path.compare">[[fs.path.compare]]</a>
1337
+
1338
+ ``` cpp
1339
+ int compare(const path& p) const noexcept;
1340
+ ```
1341
+
1342
+ *Returns:*
1343
+
1344
+ - A value less than `0`, if `native()` for the elements of `*this` are
1345
+ lexicographically less than `native()` for the elements of `p`;
1346
+ otherwise,
1347
+ - a value greater than `0`, if `native()` for the elements of `*this`
1348
+ are lexicographically greater than `native()` for the elements of `p`;
1349
+ otherwise,
1350
+ - `0`.
1351
+
1352
+ *Remarks:* The elements are determined as if by iteration over the
1353
+ half-open range \[`begin()`, `end()`) for `*this` and `p`.
1354
+
1355
+ ``` cpp
1356
+ int compare(const string_type& s) const
1357
+ int compare(basic_string_view<value_type> s) const;
1358
+ ```
1359
+
1360
+ *Returns:* `compare(path(s))`.
1361
+
1362
+ ``` cpp
1363
+ int compare(const value_type* s) const
1364
+ ```
1365
+
1366
+ *Returns:* `compare(path(s))`.
1367
+
1368
+ ##### `path` decomposition <a id="fs.path.decompose">[[fs.path.decompose]]</a>
1369
+
1370
+ ``` cpp
1371
+ path root_name() const;
1372
+ ```
1373
+
1374
+ *Returns:* *root-name*, if the pathname in the generic format includes
1375
+ *root-name*, otherwise `path()`.
1376
+
1377
+ ``` cpp
1378
+ path root_directory() const;
1379
+ ```
1380
+
1381
+ *Returns:* *root-directory*, if the pathname in the generic format
1382
+ includes *root-directory*, otherwise `path()`.
1383
+
1384
+ ``` cpp
1385
+ path root_path() const;
1386
+ ```
1387
+
1388
+ *Returns:* `root_name() / root_directory()`.
1389
+
1390
+ ``` cpp
1391
+ path relative_path() const;
1392
+ ```
1393
+
1394
+ *Returns:* A `path` composed from the pathname in the generic format, if
1395
+ `!empty()`, beginning with the first *filename* after *root-path*.
1396
+ Otherwise, `path()`.
1397
+
1398
+ ``` cpp
1399
+ path parent_path() const;
1400
+ ```
1401
+
1402
+ *Returns:* `*this` if `!has_relative_path()`, otherwise a path whose
1403
+ generic format pathname is the longest prefix of the generic format
1404
+ pathname of `*this` that produces one fewer element in its iteration.
1405
+
1406
+ ``` cpp
1407
+ path filename() const;
1408
+ ```
1409
+
1410
+ *Returns:* `relative_path().empty() ? path() : *–end()`.
1411
+
1412
+ [*Example 6*:
1413
+
1414
+ ``` cpp
1415
+ path("/foo/bar.txt").filename(); // yields "bar.txt"
1416
+ path("/foo/bar").filename(); // yields "bar"
1417
+ path("/foo/bar/").filename(); // yields ""
1418
+ path("/").filename(); // yields ""
1419
+ path("//host").filename(); // yields ""
1420
+ path(".").filename(); // yields "."
1421
+ path("..").filename(); // yields ".."
1422
+ ```
1423
+
1424
+ — *end example*]
1425
+
1426
+ ``` cpp
1427
+ path stem() const;
1428
+ ```
1429
+
1430
+ *Returns:* Let `f` be the generic format pathname of `filename()`.
1431
+ Returns a path whose pathname in the generic format is
1432
+
1433
+ - `f`, if it contains no periods other than a leading period or consists
1434
+ solely of one or two periods;
1435
+ - otherwise, the prefix of `f` ending before its last period.
1436
+
1437
+ [*Example 7*:
1438
+
1439
+ ``` cpp
1440
+ std::cout << path("/foo/bar.txt").stem(); // outputs "bar"
1441
+ path p = "foo.bar.baz.tar";
1442
+ for (; !p.extension().empty(); p = p.stem())
1443
+ std::cout << p.extension() << '\n';
1444
+ // outputs: .tar
1445
+ // .baz
1446
+ // .bar
1447
+ ```
1448
+
1449
+ — *end example*]
1450
+
1451
+ ``` cpp
1452
+ path extension() const;
1453
+ ```
1454
+
1455
+ *Returns:* a path whose pathname in the generic format is the suffix of
1456
+ `filename()` not included in `stem()`.
1457
+
1458
+ [*Example 8*:
1459
+
1460
+ ``` cpp
1461
+ path("/foo/bar.txt").extension(); // yields ".txt" and stem() is "bar"
1462
+ path("/foo/bar").extension(); // yields "" and stem() is "bar"
1463
+ path("/foo/.profile").extension(); // yields "" and stem() is ".profile"
1464
+ path(".bar").extension(); // yields "" and stem() is ".bar"
1465
+ path("..bar").extension(); // yields ".bar" and stem() is "."
1466
+ ```
1467
+
1468
+ — *end example*]
1469
+
1470
+ [*Note 4*: The period is included in the return value so that it is
1471
+ possible to distinguish between no extension and an empty
1472
+ extension. — *end note*]
1473
+
1474
+ [*Note 5*: On non-POSIX operating systems, for a path `p`, it may not
1475
+ be the case that `p.stem() + p.extension() == p.filename()`, even though
1476
+ the generic format pathnames are the same. — *end note*]
1477
+
1478
+ ##### `path` query <a id="fs.path.query">[[fs.path.query]]</a>
1479
+
1480
+ ``` cpp
1481
+ bool empty() const noexcept;
1482
+ ```
1483
+
1484
+ *Returns:* `true` if the pathname in the generic format is empty, else
1485
+ `false`.
1486
+
1487
+ ``` cpp
1488
+ bool has_root_path() const;
1489
+ ```
1490
+
1491
+ *Returns:* `!root_path().empty()`.
1492
+
1493
+ ``` cpp
1494
+ bool has_root_name() const;
1495
+ ```
1496
+
1497
+ *Returns:* `!root_name().empty()`.
1498
+
1499
+ ``` cpp
1500
+ bool has_root_directory() const;
1501
+ ```
1502
+
1503
+ *Returns:* `!root_directory().empty()`.
1504
+
1505
+ ``` cpp
1506
+ bool has_relative_path() const;
1507
+ ```
1508
+
1509
+ *Returns:* `!relative_path().empty()`.
1510
+
1511
+ ``` cpp
1512
+ bool has_parent_path() const;
1513
+ ```
1514
+
1515
+ *Returns:* `!parent_path().empty()`.
1516
+
1517
+ ``` cpp
1518
+ bool has_filename() const;
1519
+ ```
1520
+
1521
+ *Returns:* `!filename().empty()`.
1522
+
1523
+ ``` cpp
1524
+ bool has_stem() const;
1525
+ ```
1526
+
1527
+ *Returns:* `!stem().empty()`.
1528
+
1529
+ ``` cpp
1530
+ bool has_extension() const;
1531
+ ```
1532
+
1533
+ *Returns:* `!extension().empty()`.
1534
+
1535
+ ``` cpp
1536
+ bool is_absolute() const;
1537
+ ```
1538
+
1539
+ *Returns:* `true` if the pathname in the native format contains an
1540
+ absolute path ([[fs.def.absolute.path]]), else `false`.
1541
+
1542
+ [*Example 9*: `path("/").is_absolute()` is `true` for POSIX-based
1543
+ operating systems, and `false` for Windows-based operating
1544
+ systems. — *end example*]
1545
+
1546
+ ``` cpp
1547
+ bool is_relative() const;
1548
+ ```
1549
+
1550
+ *Returns:* `!is_absolute()`.
1551
+
1552
+ ##### `path` generation <a id="fs.path.gen">[[fs.path.gen]]</a>
1553
+
1554
+ ``` cpp
1555
+ path lexically_normal() const;
1556
+ ```
1557
+
1558
+ *Returns:* A path whose pathname in the generic format is the normal
1559
+ form ([[fs.def.normal.form]]) of the pathname in the generic format of
1560
+ `*this`.
1561
+
1562
+ [*Example 10*:
1563
+
1564
+ ``` cpp
1565
+ assert(path("foo/./bar/..").lexically_normal() == "foo/");
1566
+ assert(path("foo/.///bar/../").lexically_normal() == "foo/");
1567
+ ```
1568
+
1569
+ The above assertions will succeed. On Windows, the returned path’s
1570
+ *directory-separator* characters will be backslashes rather than
1571
+ slashes, but that does not affect `path` equality.
1572
+
1573
+ — *end example*]
1574
+
1575
+ ``` cpp
1576
+ path lexically_relative(const path& base) const;
1577
+ ```
1578
+
1579
+ *Returns:* `*this` made relative to `base`. Does not
1580
+ resolve ([[fs.def.pathres]]) symlinks. Does not first
1581
+ normalize ([[fs.def.normal.form]]) `*this` or `base`.
1582
+
1583
+ *Effects:* If `root_name() != base.root_name()` is `true` or
1584
+ `is_absolute() != base.is_absolute()` is `true` or
1585
+ `!has_root_directory() && base.has_root_directory()` is `true`, returns
1586
+ `path()`. Determines the first mismatched element of `*this` and `base`
1587
+ as if by:
1588
+
1589
+ ``` cpp
1590
+ auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());
1591
+ ```
1592
+
1593
+ Then,
1594
+
1595
+ - if `a == end()` and `b == base.end()`, returns `path(".")`; otherwise
1596
+ - let `n` be the number of *filename* elements in \[`b`, `base.end()`)
1597
+ that are not *dot* or *dot-dot* minus the number that are *dot-dot*.
1598
+ If `n<0,` returns `path()`; otherwise
1599
+ - returns an object of class `path` that is default-constructed,
1600
+ followed by
1601
+ - application of `operator/=(path(".."))` `n` times, and then
1602
+ - application of `operator/=` for each element in \[`a`, `end()`).
1603
+
1604
+ [*Example 11*:
1605
+
1606
+ ``` cpp
1607
+ assert(path("/a/d").lexically_relative("/a/b/c") == "../../d");
1608
+ assert(path("/a/b/c").lexically_relative("/a/d") == "../b/c");
1609
+ assert(path("a/b/c").lexically_relative("a") == "b/c");
1610
+ assert(path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");
1611
+ assert(path("a/b/c").lexically_relative("a/b/c") == ".");
1612
+ assert(path("a/b").lexically_relative("c/d") == "../../a/b");
1613
+ ```
1614
+
1615
+ The above assertions will succeed. On Windows, the returned path’s
1616
+ *directory-separator* characters will be backslashes rather than
1617
+ slashes, but that does not affect `path` equality.
1618
+
1619
+ — *end example*]
1620
+
1621
+ [*Note 6*: If symlink following semantics are desired, use the
1622
+ operational function `relative()`. — *end note*]
1623
+
1624
+ [*Note 7*: If normalization ([[fs.def.normal.form]]) is needed to
1625
+ ensure consistent matching of elements, apply `lexically_normal()` to
1626
+ `*this`, `base`, or both. — *end note*]
1627
+
1628
+ ``` cpp
1629
+ path lexically_proximate(const path& base) const;
1630
+ ```
1631
+
1632
+ *Returns:* If the value of `lexically_relative(base)` is not an empty
1633
+ path, return it. Otherwise return `*this`.
1634
+
1635
+ [*Note 8*: If symlink following semantics are desired, use the
1636
+ operational function `proximate()`. — *end note*]
1637
+
1638
+ [*Note 9*: If normalization ([[fs.def.normal.form]]) is needed to
1639
+ ensure consistent matching of elements, apply `lexically_normal()` to
1640
+ `*this`, `base`, or both. — *end note*]
1641
+
1642
+ #### `path` iterators <a id="fs.path.itr">[[fs.path.itr]]</a>
1643
+
1644
+ Path iterators iterate over the elements of the pathname in the generic
1645
+ format ([[fs.path.generic]]).
1646
+
1647
+ A `path::iterator` is a constant iterator satisfying all the
1648
+ requirements of a bidirectional iterator ([[bidirectional.iterators]])
1649
+ except that, for dereferenceable iterators `a` and `b` of type
1650
+ `path::iterator` with `a == b`, there is no requirement that `*a` and
1651
+ `*b` are bound to the same object. Its `value_type` is `path`.
1652
+
1653
+ Calling any non-const member function of a `path` object invalidates all
1654
+ iterators referring to elements of that object.
1655
+
1656
+ For the elements of the pathname in the generic format, the forward
1657
+ traversal order is as follows:
1658
+
1659
+ - The *root-name* element, if present.
1660
+ - The *root-directory* element, if present. \[*Note 1*: The generic
1661
+ format is required to ensure lexicographical comparison works
1662
+ correctly. — *end note*]
1663
+ - Each successive *filename* element, if present.
1664
+ - An empty element, if a trailing non-root *directory-separator* is
1665
+ present.
1666
+
1667
+ The backward traversal order is the reverse of forward traversal.
1668
+
1669
+ ``` cpp
1670
+ iterator begin() const;
1671
+ ```
1672
+
1673
+ *Returns:* An iterator for the first present element in the traversal
1674
+ list above. If no elements are present, the end iterator.
1675
+
1676
+ ``` cpp
1677
+ iterator end() const;
1678
+ ```
1679
+
1680
+ *Returns:* The end iterator.
1681
+
1682
+ #### `path` non-member functions <a id="fs.path.nonmember">[[fs.path.nonmember]]</a>
1683
+
1684
+ ``` cpp
1685
+ void swap(path& lhs, path& rhs) noexcept;
1686
+ ```
1687
+
1688
+ *Effects:* Equivalent to: `lhs.swap(rhs);`
1689
+
1690
+ ``` cpp
1691
+ size_t hash_value (const path& p) noexcept;
1692
+ ```
1693
+
1694
+ *Returns:* A hash value for the path `p`. If for two paths, `p1 == p2`
1695
+ then `hash_value(p1) == hash_value(p2)`.
1696
+
1697
+ ``` cpp
1698
+ bool operator< (const path& lhs, const path& rhs) noexcept;
1699
+ ```
1700
+
1701
+ *Returns:* `lhs.compare(rhs) < 0`.
1702
+
1703
+ ``` cpp
1704
+ bool operator<=(const path& lhs, const path& rhs) noexcept;
1705
+ ```
1706
+
1707
+ *Returns:* `!(rhs < lhs)`.
1708
+
1709
+ ``` cpp
1710
+ bool operator> (const path& lhs, const path& rhs) noexcept;
1711
+ ```
1712
+
1713
+ *Returns:* `rhs < lhs`.
1714
+
1715
+ ``` cpp
1716
+ bool operator>=(const path& lhs, const path& rhs) noexcept;
1717
+ ```
1718
+
1719
+ *Returns:* `!(lhs < rhs)`.
1720
+
1721
+ ``` cpp
1722
+ bool operator==(const path& lhs, const path& rhs) noexcept;
1723
+ ```
1724
+
1725
+ *Returns:* `!(lhs < rhs) && !(rhs < lhs)`.
1726
+
1727
+ [*Note 1*:
1728
+
1729
+ Path equality and path equivalence have different semantics.
1730
+
1731
+ - Equality is determined by the `path` non-member `operator==`, which
1732
+ considers the two path’s lexical representations only.
1733
+ \[*Example 1*: `path("foo") == "bar"` is never
1734
+ `true`. — *end example*]
1735
+ - Equivalence is determined by the `equivalent()` non-member function,
1736
+ which determines if two paths resolve ([[fs.def.pathres]]) to the
1737
+ same file system entity. \[*Example 2*: `equivalent("foo", "bar")`
1738
+ will be `true` when both paths resolve to the same
1739
+ file. — *end example*]
1740
+
1741
+ Programmers wishing to determine if two paths are “the same” must decide
1742
+ if “the same” means “the same representation” or “resolve to the same
1743
+ actual file”, and choose the appropriate function accordingly.
1744
+
1745
+ — *end note*]
1746
+
1747
+ ``` cpp
1748
+ bool operator!=(const path& lhs, const path& rhs) noexcept;
1749
+ ```
1750
+
1751
+ *Returns:* `!(lhs == rhs)`.
1752
+
1753
+ ``` cpp
1754
+ path operator/ (const path& lhs, const path& rhs);
1755
+ ```
1756
+
1757
+ *Effects:* Equivalent to: `return path(lhs) /= rhs;`
1758
+
1759
+ ##### `path` inserter and extractor <a id="fs.path.io">[[fs.path.io]]</a>
1760
+
1761
+ ``` cpp
1762
+ template <class charT, class traits>
1763
+ basic_ostream<charT, traits>&
1764
+ operator<<(basic_ostream<charT, traits>& os, const path& p);
1765
+ ```
1766
+
1767
+ *Effects:* Equivalent to: `os << quoted(p.string<charT, traits>());`
1768
+
1769
+ [*Note 2*: The `quoted` function is described
1770
+ in  [[quoted.manip]]. — *end note*]
1771
+
1772
+ *Returns:* `os`.
1773
+
1774
+ ``` cpp
1775
+ template <class charT, class traits>
1776
+ basic_istream<charT, traits>&
1777
+ operator>>(basic_istream<charT, traits>& is, path& p);
1778
+ ```
1779
+
1780
+ *Effects:* Equivalent to:
1781
+
1782
+ ``` cpp
1783
+ basic_string<charT, traits> tmp;
1784
+ is >> quoted(tmp);
1785
+ p = tmp;
1786
+ ```
1787
+
1788
+ *Returns:* `is`.
1789
+
1790
+ ##### `path` factory functions <a id="fs.path.factory">[[fs.path.factory]]</a>
1791
+
1792
+ ``` cpp
1793
+ template <class Source>
1794
+ path u8path(const Source& source);
1795
+ template <class InputIterator>
1796
+ path u8path(InputIterator first, InputIterator last);
1797
+ ```
1798
+
1799
+ *Requires:* The `source` and \[`first`, `last`) sequences are UTF-8
1800
+ encoded. The value type of `Source` and `InputIterator` is `char`.
1801
+
1802
+ *Returns:*
1803
+
1804
+ - If `value_type` is `char` and the current native narrow
1805
+ encoding ([[fs.def.native.encode]]) is UTF-8, return `path(source)`
1806
+ or `path(first, last)`; otherwise,
1807
+ - if `value_type` is `wchar_t` and the native wide encoding is UTF-16,
1808
+ or if `value_type` is `char16_t` or `char32_t`, convert `source` or
1809
+ \[`first`, `last`) to a temporary, `tmp`, of type `string_type` and
1810
+ return `path(tmp)`; otherwise,
1811
+ - convert `source` or \[`first`, `last`) to a temporary, `tmp`, of type
1812
+ `u32string` and return `path(tmp)`.
1813
+
1814
+ *Remarks:* Argument format conversion ([[fs.path.fmt.cvt]]) applies to
1815
+ the arguments for these functions. How Unicode encoding conversions are
1816
+ performed is unspecified.
1817
+
1818
+ [*Example 1*:
1819
+
1820
+ A string is to be read from a database that is encoded in UTF-8, and
1821
+ used to create a directory using the native encoding for filenames:
1822
+
1823
+ ``` cpp
1824
+ namespace fs = std::filesystem;
1825
+ std::string utf8_string = read_utf8_data();
1826
+ fs::create_directory(fs::u8path(utf8_string));
1827
+ ```
1828
+
1829
+ For POSIX-based operating systems with the native narrow encoding set to
1830
+ UTF-8, no encoding or type conversion occurs.
1831
+
1832
+ For POSIX-based operating systems with the native narrow encoding not
1833
+ set to UTF-8, a conversion to UTF-32 occurs, followed by a conversion to
1834
+ the current native narrow encoding. Some Unicode characters may have no
1835
+ native character set representation.
1836
+
1837
+ For Windows-based operating systems a conversion from UTF-8 to UTF-16
1838
+ occurs.
1839
+
1840
+ — *end example*]
1841
+
1842
+ ### Class `filesystem_error` <a id="fs.class.filesystem_error">[[fs.class.filesystem_error]]</a>
1843
+
1844
+ ``` cpp
1845
+ namespace std::filesystem {
1846
+ class filesystem_error : public system_error {
1847
+ public:
1848
+ filesystem_error(const string& what_arg, error_code ec);
1849
+ filesystem_error(const string& what_arg,
1850
+ const path& p1, error_code ec);
1851
+ filesystem_error(const string& what_arg,
1852
+ const path& p1, const path& p2, error_code ec);
1853
+
1854
+ const path& path1() const noexcept;
1855
+ const path& path2() const noexcept;
1856
+ const char* what() const noexcept override;
1857
+ };
1858
+ }
1859
+ ```
1860
+
1861
+ The class `filesystem_error` defines the type of objects thrown as
1862
+ exceptions to report file system errors from functions described in this
1863
+ subclause.
1864
+
1865
+ #### `filesystem_error` members <a id="filesystem_error.members">[[filesystem_error.members]]</a>
1866
+
1867
+ Constructors are provided that store zero, one, or two paths associated
1868
+ with an error.
1869
+
1870
+ ``` cpp
1871
+ filesystem_error(const string& what_arg, error_code ec);
1872
+ ```
1873
+
1874
+ *Postconditions:* The postconditions of this function are indicated in
1875
+ Table  [[tab:filesystem_error.1]].
1876
+
1877
+ **Table: `filesystem_error(const string&, error_code)` effects** <a id="tab:filesystem_error.1">[tab:filesystem_error.1]</a>
1878
+
1879
+ | Expression | Value |
1880
+ | ----------------------- | ------------------ |
1881
+ | `runtime_error::what()` | `what_arg.c_str()` |
1882
+ | `code()` | `ec` |
1883
+ | `path1().empty()` | `true` |
1884
+ | `path2().empty()` | `true` |
1885
+
1886
+ ``` cpp
1887
+ filesystem_error(const string& what_arg, const path& p1, error_code ec);
1888
+ ```
1889
+
1890
+ *Postconditions:* The postconditions of this function are indicated in
1891
+ Table  [[tab:filesystem_error.2]].
1892
+
1893
+ **Table: `filesystem_error(const string&, const path&, error_code)` effects** <a id="tab:filesystem_error.2">[tab:filesystem_error.2]</a>
1894
+
1895
+ | Expression | Value |
1896
+ | ----------------------- | -------------------------------- |
1897
+ | `runtime_error::what()` | `what_arg.c_str()` |
1898
+ | `code()` | `ec` |
1899
+ | `path1()` | Reference to stored copy of `p1` |
1900
+ | `path2().empty()` | `true` |
1901
+
1902
+ ``` cpp
1903
+ filesystem_error(const string& what_arg, const path& p1, const path& p2, error_code ec);
1904
+ ```
1905
+
1906
+ *Postconditions:* The postconditions of this function are indicated in
1907
+ Table  [[tab:filesystem_error.3]].
1908
+
1909
+ **Table: `filesystem_error(const string&, const path&, const path&, error_code)` effects** <a id="tab:filesystem_error.3">[tab:filesystem_error.3]</a>
1910
+
1911
+ | Expression | Value |
1912
+ | ----------------------- | -------------------------------- |
1913
+ | `runtime_error::what()` | `what_arg.c_str()` |
1914
+ | `code()` | `ec` |
1915
+ | `path1()` | Reference to stored copy of `p1` |
1916
+ | `path2()` | Reference to stored copy of `p2` |
1917
+
1918
+ ``` cpp
1919
+ const path& path1() const noexcept;
1920
+ ```
1921
+
1922
+ *Returns:* A reference to the copy of `p1` stored by the constructor,
1923
+ or, if none, an empty path.
1924
+
1925
+ ``` cpp
1926
+ const path& path2() const noexcept;
1927
+ ```
1928
+
1929
+ *Returns:* A reference to the copy of `p2` stored by the constructor,
1930
+ or, if none, an empty path.
1931
+
1932
+ ``` cpp
1933
+ const char* what() const noexcept override;
1934
+ ```
1935
+
1936
+ *Returns:* A string containing `runtime_error::what()`. The exact format
1937
+ is unspecified. Implementations are encouraged but not required to
1938
+ include `path1.native_string()` if not empty, `path2.native_string()` if
1939
+ not empty, and `system_error::what()` strings in the returned string.
1940
+
1941
+ ### Enumerations <a id="fs.enum">[[fs.enum]]</a>
1942
+
1943
+ #### Enum `path::format` <a id="fs.enum.path.format">[[fs.enum.path.format]]</a>
1944
+
1945
+ This enum specifies constants used to identify the format of the
1946
+ character sequence, with the meanings listed in Table 
1947
+ [[tab:enum.path.format]].
1948
+
1949
+ [*Note 1*: For POSIX-based systems, native and generic formats are
1950
+ equivalent and the character sequence should always be interpreted in
1951
+ the same way. — *end note*]
1952
+
1953
+ #### Enum class `file_type` <a id="fs.enum.file_type">[[fs.enum.file_type]]</a>
1954
+
1955
+ This enum class specifies constants used to identify file types, with
1956
+ the meanings listed in Table  [[tab:fs.enum.file_type]].
1957
+
1958
+ [*Note 1*: The file not being found is not considered an error while
1959
+ determining the type of a file. — *end note*]
1960
+
1961
+ #### Enum class `copy_options` <a id="fs.enum.copy.opts">[[fs.enum.copy.opts]]</a>
1962
+
1963
+ The `enum class` type `copy_options` is a bitmask type (
1964
+ [[bitmask.types]]) that specifies bitmask constants used to control the
1965
+ semantics of copy operations. The constants are specified in option
1966
+ groups with the meanings listed in Table  [[tab:fs.enum.copy_options]].
1967
+ Constant `none` is shown in each option group for purposes of
1968
+ exposition; implementations shall provide only a single definition.
1969
+
1970
+ **Table: Enum class `copy_options`** <a id="tab:fs.enum.copy_options">[tab:fs.enum.copy_options]</a>
1971
+
1972
+ | Constant | Meaning |
1973
+ | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
1974
+ | `none` | (Default) Error; file already exists. |
1975
+ | `skip_existing` | Do not overwrite existing file, do not report an error. |
1976
+ | `overwrite_existing` | Overwrite the existing file. |
1977
+ | `update_existing` | Overwrite the existing file if it is older than the replacement file. \ohdrx{2}{Option group controlling `copy` function effects for sub-directories} |
1978
+ | `recursive` | Recursively copy sub-directories and their contents. \ohdrx{2}{Option group controlling `copy` function effects for symbolic links} |
1979
+ | `copy_symlinks` | Copy symbolic links as symbolic links rather than copying the files that they point to. |
1980
+ | `skip_symlinks` | Ignore symbolic links. \ohdrx{2}{Option group controlling `copy` function effects for choosing the form of copying} |
1981
+ | `directories_only` | Copy directory structure only, do not copy non-directory files. |
1982
+ | `create_symlinks` | Make symbolic links instead of copies of files. The source path shall be an absolute path unless the destination path is in the current directory. |
1983
+ | `create_hard_links` | Make hard links instead of copies of files. |
1984
+
1985
+
1986
+ #### Enum class `perms` <a id="fs.enum.perms">[[fs.enum.perms]]</a>
1987
+
1988
+ The `enum class` type `perms` is a bitmask type ([[bitmask.types]])
1989
+ that specifies bitmask constants used to identify file permissions, with
1990
+ the meanings listed in Table  [[tab:fs.enum.perms]].
1991
+
1992
+ **Table: Enum class `perms`** <a id="tab:fs.enum.perms">[tab:fs.enum.perms]</a>
1993
+
1994
+ | Name | Value (octal) | POSIX macro | Definition or notes |
1995
+ | -------------- | ------------- | ----------- | ---------------------------------------------------------------------------------------------------------------- |
1996
+ | `none` | `0` | | There are no permissions set for the file. |
1997
+ | `owner_read` | `0400` | `S_IRUSR` | Read permission, owner |
1998
+ | `owner_write` | `0200` | `S_IWUSR` | Write permission, owner |
1999
+ | `owner_exec` | `0100` | `S_IXUSR` | Execute/search permission, owner |
2000
+ | `owner_all` | `0700` | `S_IRWXU` | Read, write, execute/search by owner;<br> `owner_read | owner_write | owner_exec` |
2001
+ | `group_read` | `040` | `S_IRGRP` | Read permission, group |
2002
+ | `group_write` | `020` | `S_IWGRP` | Write permission, group |
2003
+ | `group_exec` | `010` | `S_IXGRP` | Execute/search permission, group |
2004
+ | `group_all` | `070` | `S_IRWXG` | Read, write, execute/search by group;<br> `group_read | group_write | group_exec` |
2005
+ | `others_read` | `04` | `S_IROTH` | Read permission, others |
2006
+ | `others_write` | `02` | `S_IWOTH` | Write permission, others |
2007
+ | `others_exec` | `01` | `S_IXOTH` | Execute/search permission, others |
2008
+ | `others_all` | `07` | `S_IRWXO` | Read, write, execute/search by others;<br> `others_read | others_write | others_exec` |
2009
+ | `all` | `0777` | | `owner_all | group_all | others_all` |
2010
+ | `set_uid` | `04000` | `S_ISUID` | Set-user-ID on execution |
2011
+ | `set_gid` | `02000` | `S_ISGID` | Set-group-ID on execution |
2012
+ | `sticky_bit` | `01000` | `S_ISVTX` | Operating system dependent. |
2013
+ | `mask` | `07777` | | `all | set_uid | set_gid | sticky_bit` |
2014
+ | `unknown` | `0xFFFF` | | The permissions are not known, such as when a `file_status` object is created without specifying the permissions |
2015
+
2016
+
2017
+ #### Enum class `perm_options` <a id="fs.enum.perm.opts">[[fs.enum.perm.opts]]</a>
2018
+
2019
+ The `enum class` type `perm_options` is a bitmask type (
2020
+ [[bitmask.types]]) that specifies bitmask constants used to control the
2021
+ semantics of permissions operations, with the meanings listed in Table 
2022
+ [[tab:enum.perm_options]]. The bitmask constants are bitmask elements.
2023
+ In Table  [[tab:enum.perm_options]] `perm` denotes a value of type
2024
+ `perms` passed to `permissions`.
2025
+
2026
+ **Table: Enum class `perm_options`** <a id="tab:enum.perm_options">[tab:enum.perm_options]</a>
2027
+
2028
+ | Name | Meaning |
2029
+ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
2030
+ | `replace` | `permissions` shall replace the file's permission bits with `perm` |
2031
+ | `add` | `permissions` shall replace the file's permission bits with the bitwise OR of `perm` and the file's current permission bits. |
2032
+ | `remove` | `permissions` shall replace the file's permission bits with the bitwise AND of the complement of `perm` and the file's current permission bits. |
2033
+ | `nofollow` | `permissions` shall change the permissions of a symbolic link itself rather than the permissions of the file the link resolves to. |
2034
+
2035
+
2036
+ #### Enum class `directory_options` <a id="fs.enum.dir.opts">[[fs.enum.dir.opts]]</a>
2037
+
2038
+ The `enum class` type `directory_options` is a bitmask type (
2039
+ [[bitmask.types]]) that specifies bitmask constants used to identify
2040
+ directory traversal options, with the meanings listed in Table 
2041
+ [[tab:fs.enum.directory_options]].
2042
+
2043
+ **Table: Enum class `directory_options`** <a id="tab:fs.enum.directory_options">[tab:fs.enum.directory_options]</a>
2044
+
2045
+ | Name | Meaning |
2046
+ | -------------------------- | ------------------------------------------------------------------ |
2047
+ | `none` | (Default) Skip directory symlinks, permission denied is an error. |
2048
+ | `follow_directory_symlink` | Follow rather than skip directory symlinks. |
2049
+ | `skip_permission_denied` | Skip directories that would otherwise result in permission denied. |
2050
+
2051
+
2052
+ ### Class `file_status` <a id="fs.class.file_status">[[fs.class.file_status]]</a>
2053
+
2054
+ ``` cpp
2055
+ namespace std::filesystem {
2056
+ class file_status {
2057
+ public:
2058
+ // [fs.file_status.cons], constructors and destructor
2059
+ file_status() noexcept : file_status(file_type::none) {}
2060
+ explicit file_status(file_type ft,
2061
+ perms prms = perms::unknown) noexcept;
2062
+ file_status(const file_status&) noexcept = default;
2063
+ file_status(file_status&&) noexcept = default;
2064
+ ~file_status();
2065
+
2066
+ // assignments:
2067
+ file_status& operator=(const file_status&) noexcept = default;
2068
+ file_status& operator=(file_status&&) noexcept = default;
2069
+
2070
+ // [fs.file_status.mods], modifiers
2071
+ void type(file_type ft) noexcept;
2072
+ void permissions(perms prms) noexcept;
2073
+
2074
+ // [fs.file_status.obs], observers
2075
+ file_type type() const noexcept;
2076
+ perms permissions() const noexcept;
2077
+ };
2078
+ }
2079
+ ```
2080
+
2081
+ #### `file_status` constructors <a id="fs.file_status.cons">[[fs.file_status.cons]]</a>
2082
+
2083
+ ``` cpp
2084
+ explicit file_status(file_type ft, perms prms = perms::unknown) noexcept;
2085
+ ```
2086
+
2087
+ *Postconditions:* `type() == ft` and `permissions() == prms`.
2088
+
2089
+ #### `file_status` observers <a id="fs.file_status.obs">[[fs.file_status.obs]]</a>
2090
+
2091
+ ``` cpp
2092
+ file_type type() const noexcept;
2093
+ ```
2094
+
2095
+ *Returns:* The value of `type()` specified by the postconditions of the
2096
+ most recent call to a constructor, `operator=`, or `type(file_type)`
2097
+ function.
2098
+
2099
+ ``` cpp
2100
+ perms permissions() const noexcept;
2101
+ ```
2102
+
2103
+ *Returns:* The value of `permissions()` specified by the postconditions
2104
+ of the most recent call to a constructor, `operator=`, or
2105
+ `permissions(perms)` function.
2106
+
2107
+ #### `file_status` modifiers <a id="fs.file_status.mods">[[fs.file_status.mods]]</a>
2108
+
2109
+ ``` cpp
2110
+ void type(file_type ft) noexcept;
2111
+ ```
2112
+
2113
+ *Postconditions:* `type() == ft`.
2114
+
2115
+ ``` cpp
2116
+ void permissions(perms prms) noexcept;
2117
+ ```
2118
+
2119
+ *Postconditions:* `permissions() == prms`.
2120
+
2121
+ ### Class `directory_entry` <a id="fs.class.directory_entry">[[fs.class.directory_entry]]</a>
2122
+
2123
+ ``` cpp
2124
+ namespace std::filesystem {
2125
+ class directory_entry {
2126
+ public:
2127
+ // [fs.dir.entry.cons], constructors and destructor
2128
+ directory_entry() noexcept = default;
2129
+ directory_entry(const directory_entry&) = default;
2130
+ directory_entry(directory_entry&&) noexcept = default;
2131
+ explicit directory_entry(const path& p);
2132
+ directory_entry(const path& p, error_code& ec);
2133
+ ~directory_entry();
2134
+
2135
+ // assignments:
2136
+ directory_entry& operator=(const directory_entry&) = default;
2137
+ directory_entry& operator=(directory_entry&&) noexcept = default;
2138
+
2139
+ // [fs.dir.entry.mods], modifiers
2140
+ void assign(const path& p);
2141
+ void assign(const path& p, error_code& ec);
2142
+ void replace_filename(const path& p);
2143
+ void replace_filename(const path& p, error_code& ec);
2144
+ void refresh();
2145
+ void refresh(error_code& ec) noexcept;
2146
+
2147
+ // [fs.dir.entry.obs], observers
2148
+ const path& path() const noexcept;
2149
+ operator const path&() const noexcept;
2150
+ bool exists() const;
2151
+ bool exists(error_code& ec) const noexcept;
2152
+ bool is_block_file() const;
2153
+ bool is_block_file(error_code& ec) const noexcept;
2154
+ bool is_character_file() const;
2155
+ bool is_character_file(error_code& ec) const noexcept;
2156
+ bool is_directory() const;
2157
+ bool is_directory(error_code& ec) const noexcept;
2158
+ bool is_fifo() const;
2159
+ bool is_fifo(error_code& ec) const noexcept;
2160
+ bool is_other() const;
2161
+ bool is_other(error_code& ec) const noexcept;
2162
+ bool is_regular_file() const;
2163
+ bool is_regular_file(error_code& ec) const noexcept;
2164
+ bool is_socket() const;
2165
+ bool is_socket(error_code& ec) const noexcept;
2166
+ bool is_symlink() const;
2167
+ bool is_symlink(error_code& ec) const noexcept;
2168
+ uintmax_t file_size() const;
2169
+ uintmax_t file_size(error_code& ec) const noexcept;
2170
+ uintmax_t hard_link_count() const;
2171
+ uintmax_t hard_link_count(error_code& ec) const noexcept;
2172
+ file_time_type last_write_time() const;
2173
+ file_time_type last_write_time(error_code& ec) const noexcept;
2174
+ file_status status() const;
2175
+ file_status status(error_code& ec) const noexcept;
2176
+ file_status symlink_status() const;
2177
+ file_status symlink_status(error_code& ec) const noexcept;
2178
+
2179
+ bool operator< (const directory_entry& rhs) const noexcept;
2180
+ bool operator==(const directory_entry& rhs) const noexcept;
2181
+ bool operator!=(const directory_entry& rhs) const noexcept;
2182
+ bool operator<=(const directory_entry& rhs) const noexcept;
2183
+ bool operator> (const directory_entry& rhs) const noexcept;
2184
+ bool operator>=(const directory_entry& rhs) const noexcept;
2185
+
2186
+ private:
2187
+ path pathobject; // exposition only
2188
+ friend class directory_iterator; // exposition only
2189
+ };
2190
+ }
2191
+ ```
2192
+
2193
+ A `directory_entry` object stores a `path` object and may store
2194
+ additional objects for file attributes such as hard link count, status,
2195
+ symlink status, file size, and last write time.
2196
+
2197
+ Implementations are encouraged to store such additional file attributes
2198
+ during directory iteration if their values are available and storing the
2199
+ values would allow the implementation to eliminate file system accesses
2200
+ by `directory_entry` observer functions ([[fs.op.funcs]]). Such stored
2201
+ file attribute values are said to be *cached*.
2202
+
2203
+ [*Note 1*: For purposes of exposition, class `directory_iterator` (
2204
+ [[fs.class.directory_iterator]]) is shown above as a friend of class
2205
+ `directory_entry`. Friendship allows the `directory_iterator`
2206
+ implementation to cache already available attribute values directly into
2207
+ a `directory_entry` object without the cost of an unneeded call to
2208
+ `refresh()`. — *end note*]
2209
+
2210
+ [*Example 1*:
2211
+
2212
+ ``` cpp
2213
+ using namespace std::filesystem;
2214
+
2215
+ // use possibly cached last write time to minimize disk accesses
2216
+ for (auto&& x : directory_iterator("."))
2217
+ {
2218
+ std::cout << x.path() << " " << x.last_write_time() << std::endl;
2219
+ }
2220
+
2221
+ // call refresh() to refresh a stale cache
2222
+ for (auto&& x : directory_iterator("."))
2223
+ {
2224
+ lengthy_function(x.path()); // cache becomes stale
2225
+ x.refresh();
2226
+ std::cout << x.path() << " " << x.last_write_time() << std::endl;
2227
+ }
2228
+ ```
2229
+
2230
+ On implementations that do not cache the last write time, both loops
2231
+ will result in a potentially expensive call to the
2232
+ `std::filesystem::last_write_time` function. On implementations that do
2233
+ cache the last write time, the first loop will use the cached value and
2234
+ so will not result in a potentially expensive call to the
2235
+ `std::filesystem::last_write_time` function. The code is portable to any
2236
+ implementation, regardless of whether or not it employs caching.
2237
+
2238
+ — *end example*]
2239
+
2240
+ #### `directory_entry` constructors <a id="fs.dir.entry.cons">[[fs.dir.entry.cons]]</a>
2241
+
2242
+ ``` cpp
2243
+ explicit directory_entry(const path& p);
2244
+ directory_entry(const path& p, error_code& ec);
2245
+ ```
2246
+
2247
+ *Effects:* Constructs an object of type `directory_entry`, then
2248
+ `refresh()` or `refresh(ec)`, respectively.
2249
+
2250
+ *Postconditions:* `path() == p` if no error occurs, otherwise
2251
+ `path() == std::filesystem::path()`.
2252
+
2253
+ *Throws:* As specified in  [[fs.err.report]].
2254
+
2255
+ #### `directory_entry` modifiers <a id="fs.dir.entry.mods">[[fs.dir.entry.mods]]</a>
2256
+
2257
+ ``` cpp
2258
+ void assign(const path& p);
2259
+ void assign(const path& p, error_code& ec);
2260
+ ```
2261
+
2262
+ *Effects:* Equivalent to `pathobject = p`, then `refresh()` or
2263
+ `refresh(ec)`, respectively. If an error occurs, the values of any
2264
+ cached attributes are unspecified.
2265
+
2266
+ *Throws:* As specified in  [[fs.err.report]].
2267
+
2268
+ ``` cpp
2269
+ void replace_filename(const path& p);
2270
+ void replace_filename(const path& p, error_code& ec);
2271
+ ```
2272
+
2273
+ *Effects:* Equivalent to `pathobject.replace_filename(p)`, then
2274
+ `refresh()` or `refresh(ec)`, respectively. If an error occurs, the
2275
+ values of any cached attributes are unspecified.
2276
+
2277
+ *Throws:* As specified in  [[fs.err.report]].
2278
+
2279
+ ``` cpp
2280
+ void refresh();
2281
+ void refresh(error_code& ec) noexcept;
2282
+ ```
2283
+
2284
+ *Effects:* Stores the current values of any cached attributes of the
2285
+ file `p` resolves to. If an error occurs, an error is
2286
+ reported ([[fs.err.report]]) and the values of any cached attributes
2287
+ are unspecified.
2288
+
2289
+ *Throws:* As specified in  [[fs.err.report]].
2290
+
2291
+ [*Note 1*: Implementations of
2292
+ `directory_iterator` ([[fs.class.directory_iterator]]) are prohibited
2293
+ from directly or indirectly calling the `refresh` function since it must
2294
+ access the external file system, and the objective of caching is to
2295
+ avoid unnecessary file system accesses. — *end note*]
2296
+
2297
+ #### `directory_entry` observers <a id="fs.dir.entry.obs">[[fs.dir.entry.obs]]</a>
2298
+
2299
+ Unqualified function names in the *Returns:* elements of the
2300
+ `directory_entry` observers described below refer to members of the
2301
+ `std::filesystem` namespace.
2302
+
2303
+ ``` cpp
2304
+ const path& path() const noexcept;
2305
+ operator const path&() const noexcept;
2306
+ ```
2307
+
2308
+ *Returns:* `pathobject`.
2309
+
2310
+ ``` cpp
2311
+ bool exists() const;
2312
+ bool exists(error_code& ec) const noexcept;
2313
+ ```
2314
+
2315
+ *Returns:* `exists(this->status())` or `exists(this->status(), ec)`,
2316
+ respectively.
2317
+
2318
+ *Throws:* As specified in  [[fs.err.report]].
2319
+
2320
+ ``` cpp
2321
+ bool is_block_file() const;
2322
+ bool is_block_file(error_code& ec) const noexcept;
2323
+ ```
2324
+
2325
+ *Returns:* `is_block_file(this->status())` or
2326
+ `is_block_file(this->status(), ec)`, respectively.
2327
+
2328
+ *Throws:* As specified in  [[fs.err.report]].
2329
+
2330
+ ``` cpp
2331
+ bool is_character_file() const;
2332
+ bool is_character_file(error_code& ec) const noexcept;
2333
+ ```
2334
+
2335
+ *Returns:* `is_character_file(this->status())` or
2336
+ `is_character_file(this->status(), ec)`, respectively.
2337
+
2338
+ *Throws:* As specified in  [[fs.err.report]].
2339
+
2340
+ ``` cpp
2341
+ bool is_directory() const;
2342
+ bool is_directory(error_code& ec) const noexcept;
2343
+ ```
2344
+
2345
+ *Returns:* `is_directory(this->status())` or
2346
+ `is_directory(this->status(), ec)`, respectively.
2347
+
2348
+ *Throws:* As specified in  [[fs.err.report]].
2349
+
2350
+ ``` cpp
2351
+ bool is_fifo() const;
2352
+ bool is_fifo(error_code& ec) const noexcept;
2353
+ ```
2354
+
2355
+ *Returns:* `is_fifo(this->status())` or `is_fifo(this->status(), ec)`,
2356
+ respectively.
2357
+
2358
+ *Throws:* As specified in  [[fs.err.report]].
2359
+
2360
+ ``` cpp
2361
+ bool is_other() const;
2362
+ bool is_other(error_code& ec) const noexcept;
2363
+ ```
2364
+
2365
+ *Returns:* `is_other(this->status())` or `is_other(this->status(), ec)`,
2366
+ respectively.
2367
+
2368
+ *Throws:* As specified in  [[fs.err.report]].
2369
+
2370
+ ``` cpp
2371
+ bool is_regular_file() const;
2372
+ bool is_regular_file(error_code& ec) const noexcept;
2373
+ ```
2374
+
2375
+ *Returns:* `is_regular_file(this->status())` or
2376
+ `is_regular_file(this->status(), ec)`, respectively.
2377
+
2378
+ *Throws:* As specified in  [[fs.err.report]].
2379
+
2380
+ ``` cpp
2381
+ bool is_socket() const;
2382
+ bool is_socket(error_code& ec) const noexcept;
2383
+ ```
2384
+
2385
+ *Returns:* `is_socket(this->status())` or
2386
+ `is_socket(this->status(), ec)`, respectively.
2387
+
2388
+ *Throws:* As specified in  [[fs.err.report]].
2389
+
2390
+ ``` cpp
2391
+ bool is_symlink() const;
2392
+ bool is_symlink(error_code& ec) const noexcept;
2393
+ ```
2394
+
2395
+ *Returns:* `is_symlink(this->symlink_status())` or
2396
+ `is_symlink(this->symlink_status(), ec)`, respectively.
2397
+
2398
+ *Throws:* As specified in  [[fs.err.report]].
2399
+
2400
+ ``` cpp
2401
+ uintmax_t file_size() const;
2402
+ uintmax_t file_size(error_code& ec) const noexcept;
2403
+ ```
2404
+
2405
+ *Returns:* If cached, the file size attribute value. Otherwise,
2406
+ `file_size(path())` or `file_size(path(), ec)`, respectively.
2407
+
2408
+ *Throws:* As specified in  [[fs.err.report]].
2409
+
2410
+ ``` cpp
2411
+ uintmax_t hard_link_count() const;
2412
+ uintmax_t hard_link_count(error_code& ec) const noexcept;
2413
+ ```
2414
+
2415
+ *Returns:* If cached, the hard link count attribute value. Otherwise,
2416
+ `hard_link_count(path())` or `hard_link_count(path(), ec)`,
2417
+ respectively.
2418
+
2419
+ *Throws:* As specified in  [[fs.err.report]].
2420
+
2421
+ ``` cpp
2422
+ file_time_type last_write_time() const;
2423
+ file_time_type last_write_time(error_code& ec) const noexcept;
2424
+ ```
2425
+
2426
+ *Returns:* If cached, the last write time attribute value. Otherwise,
2427
+ `last_write_time(path())` or `last_write_time(path(), ec)`,
2428
+ respectively.
2429
+
2430
+ *Throws:* As specified in  [[fs.err.report]].
2431
+
2432
+ ``` cpp
2433
+ file_status status() const;
2434
+ file_status status(error_code& ec) const noexcept;
2435
+ ```
2436
+
2437
+ *Returns:* If cached, the status attribute value. Otherwise,
2438
+ `status(path())` or `status(path(), ec)`, respectively.
2439
+
2440
+ *Throws:* As specified in  [[fs.err.report]].
2441
+
2442
+ ``` cpp
2443
+ file_status symlink_status() const;
2444
+ file_status symlink_status(error_code& ec) const noexcept;
2445
+ ```
2446
+
2447
+ *Returns:* If cached, the symlink status attribute value. Otherwise,
2448
+ `symlink_status(path())` or `symlink_status(path(), ec)`, respectively.
2449
+
2450
+ *Throws:* As specified in  [[fs.err.report]].
2451
+
2452
+ ``` cpp
2453
+ bool operator==(const directory_entry& rhs) const noexcept;
2454
+ ```
2455
+
2456
+ *Returns:* `pathobject == rhs.pathobject`.
2457
+
2458
+ ``` cpp
2459
+ bool operator!=(const directory_entry& rhs) const noexcept;
2460
+ ```
2461
+
2462
+ *Returns:* `pathobject != rhs.pathobject`.
2463
+
2464
+ ``` cpp
2465
+ bool operator< (const directory_entry& rhs) const noexcept;
2466
+ ```
2467
+
2468
+ *Returns:* `pathobject < rhs.pathobject`.
2469
+
2470
+ ``` cpp
2471
+ bool operator<=(const directory_entry& rhs) const noexcept;
2472
+ ```
2473
+
2474
+ *Returns:* `pathobject <= rhs.pathobject`.
2475
+
2476
+ ``` cpp
2477
+ bool operator> (const directory_entry& rhs) const noexcept;
2478
+ ```
2479
+
2480
+ *Returns:* `pathobject > rhs.pathobject`.
2481
+
2482
+ ``` cpp
2483
+ bool operator>=(const directory_entry& rhs) const noexcept;
2484
+ ```
2485
+
2486
+ *Returns:* `pathobject >= rhs.pathobject`.
2487
+
2488
+ ### Class `directory_iterator` <a id="fs.class.directory_iterator">[[fs.class.directory_iterator]]</a>
2489
+
2490
+ An object of type `directory_iterator` provides an iterator for a
2491
+ sequence of `directory_entry` elements representing the path and any
2492
+ cached attribute values ([[fs.class.directory_entry]]) for each file in
2493
+ a directory or in an *implementation-defined* directory-like file type.
2494
+
2495
+ [*Note 1*: For iteration into sub-directories, see class
2496
+ `recursive_directory_iterator` (
2497
+ [[fs.class.rec.dir.itr]]). — *end note*]
2498
+
2499
+ ``` cpp
2500
+ namespace std::filesystem {
2501
+ class directory_iterator {
2502
+ public:
2503
+ using iterator_category = input_iterator_tag;
2504
+ using value_type = directory_entry;
2505
+ using difference_type = ptrdiff_t;
2506
+ using pointer = const directory_entry*;
2507
+ using reference = const directory_entry&;
2508
+
2509
+ // [fs.dir.itr.members], member functions
2510
+ directory_iterator() noexcept;
2511
+ explicit directory_iterator(const path& p);
2512
+ directory_iterator(const path& p, directory_options options);
2513
+ directory_iterator(const path& p, error_code& ec) noexcept;
2514
+ directory_iterator(const path& p, directory_options options,
2515
+ error_code& ec) noexcept;
2516
+ directory_iterator(const directory_iterator& rhs);
2517
+ directory_iterator(directory_iterator&& rhs) noexcept;
2518
+ ~directory_iterator();
2519
+
2520
+ directory_iterator& operator=(const directory_iterator& rhs);
2521
+ directory_iterator& operator=(directory_iterator&& rhs) noexcept;
2522
+
2523
+ const directory_entry& operator*() const;
2524
+ const directory_entry* operator->() const;
2525
+ directory_iterator& operator++();
2526
+ directory_iterator& increment(error_code& ec) noexcept;
2527
+
2528
+ // other members as required by [input.iterators], input iterators
2529
+ };
2530
+ }
2531
+ ```
2532
+
2533
+ `directory_iterator` satisfies the requirements of an input iterator (
2534
+ [[input.iterators]]).
2535
+
2536
+ If an iterator of type `directory_iterator` reports an error or is
2537
+ advanced past the last directory element, that iterator shall become
2538
+ equal to the end iterator value. The `directory_iterator` default
2539
+ constructor shall create an iterator equal to the end iterator value,
2540
+ and this shall be the only valid iterator for the end condition.
2541
+
2542
+ The end iterator is not dereferenceable.
2543
+
2544
+ Two end iterators are always equal. An end iterator shall not be equal
2545
+ to a non-end iterator.
2546
+
2547
+ The result of calling the `path()` member of the `directory_entry`
2548
+ object obtained by dereferencing a `directory_iterator` is a reference
2549
+ to a `path` object composed of the directory argument from which the
2550
+ iterator was constructed with filename of the directory entry appended
2551
+ as if by `operator/=`.
2552
+
2553
+ Directory iteration shall not yield directory entries for the current
2554
+ (*dot*) and parent (*dot-dot*) directories.
2555
+
2556
+ The order of directory entries obtained by dereferencing successive
2557
+ increments of a `directory_iterator` is unspecified.
2558
+
2559
+ Constructors and non-const `directory_iterator` member functions store
2560
+ the values of any cached attributes ([[fs.class.directory_entry]]) in
2561
+ the `directory_entry` element returned by `operator*()`.
2562
+ `directory_iterator` member functions shall not directly or indirectly
2563
+ call any `directory_entry` `refresh` function.
2564
+
2565
+ [*Note 2*: The exact mechanism for storing cached attribute values is
2566
+ not exposed to users. For exposition, class `directory_iterator` is
2567
+ shown in [[fs.class.directory_entry]] as a friend of class
2568
+ `directory_entry`. — *end note*]
2569
+
2570
+ [*Note 3*: Programs performing directory iteration may wish to test if
2571
+ the path obtained by dereferencing a directory iterator actually exists.
2572
+ It could be a symbolic link to a non-existent file. Programs recursively
2573
+ walking directory trees for purposes of removing and renaming entries
2574
+ may wish to avoid following symbolic links. — *end note*]
2575
+
2576
+ [*Note 4*: If a file is removed from or added to a directory after the
2577
+ construction of a `directory_iterator` for the directory, it is
2578
+ unspecified whether or not subsequently incrementing the iterator will
2579
+ ever result in an iterator referencing the removed or added directory
2580
+ entry. See POSIX `readdir_r`. — *end note*]
2581
+
2582
+ #### `directory_iterator` members <a id="fs.dir.itr.members">[[fs.dir.itr.members]]</a>
2583
+
2584
+ ``` cpp
2585
+ directory_iterator() noexcept;
2586
+ ```
2587
+
2588
+ *Effects:* Constructs the end iterator.
2589
+
2590
+ ``` cpp
2591
+ explicit directory_iterator(const path& p);
2592
+ directory_iterator(const path& p, directory_options options);
2593
+ directory_iterator(const path& p, error_code& ec) noexcept;
2594
+ directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
2595
+ ```
2596
+
2597
+ *Effects:* For the directory that `p` resolves to, constructs an
2598
+ iterator for the first element in a sequence of `directory_entry`
2599
+ elements representing the files in the directory, if any; otherwise the
2600
+ end iterator. However, if
2601
+
2602
+ ``` cpp
2603
+ (options & directory_options::skip_permission_denied) != directory_options::none
2604
+ ```
2605
+
2606
+ and construction encounters an error indicating that permission to
2607
+ access `p` is denied, constructs the end iterator and does not report an
2608
+ error.
2609
+
2610
+ *Throws:* As specified in  [[fs.err.report]].
2611
+
2612
+ [*Note 1*: To iterate over the current directory, use
2613
+ `directory_iterator(".")` rather than
2614
+ `directory_iterator("")`. — *end note*]
2615
+
2616
+ ``` cpp
2617
+ directory_iterator(const directory_iterator& rhs);
2618
+ directory_iterator(directory_iterator&& rhs) noexcept;
2619
+ ```
2620
+
2621
+ *Effects:* Constructs an object of class `directory_iterator`.
2622
+
2623
+ *Postconditions:* `*this` has the original value of `rhs`.
2624
+
2625
+ ``` cpp
2626
+ directory_iterator& operator=(const directory_iterator& rhs);
2627
+ directory_iterator& operator=(directory_iterator&& rhs) noexcept;
2628
+ ```
2629
+
2630
+ *Effects:* If `*this` and `rhs` are the same object, the member has no
2631
+ effect.
2632
+
2633
+ *Postconditions:* `*this` has the original value of `rhs`.
2634
+
2635
+ *Returns:* `*this`.
2636
+
2637
+ ``` cpp
2638
+ directory_iterator& operator++();
2639
+ directory_iterator& increment(error_code& ec) noexcept;
2640
+ ```
2641
+
2642
+ *Effects:* As specified for the prefix increment operation of Input
2643
+ iterators ([[input.iterators]]).
2644
+
2645
+ *Returns:* `*this`.
2646
+
2647
+ *Throws:* As specified in  [[fs.err.report]].
2648
+
2649
+ #### `directory_iterator` non-member functions <a id="fs.dir.itr.nonmembers">[[fs.dir.itr.nonmembers]]</a>
2650
+
2651
+ These functions enable range access for `directory_iterator`.
2652
+
2653
+ ``` cpp
2654
+ directory_iterator begin(directory_iterator iter) noexcept;
2655
+ ```
2656
+
2657
+ *Returns:* `iter`.
2658
+
2659
+ ``` cpp
2660
+ directory_iterator end(const directory_iterator&) noexcept;
2661
+ ```
2662
+
2663
+ *Returns:* `directory_iterator()`.
2664
+
2665
+ ### Class `recursive_directory_iterator` <a id="fs.class.rec.dir.itr">[[fs.class.rec.dir.itr]]</a>
2666
+
2667
+ An object of type `recursive_directory_iterator` provides an iterator
2668
+ for a sequence of `directory_entry` elements representing the files in a
2669
+ directory or in an *implementation-defined* directory-like file type,
2670
+ and its sub-directories.
2671
+
2672
+ ``` cpp
2673
+ namespace std::filesystem {
2674
+ class recursive_directory_iterator {
2675
+ public:
2676
+ using iterator_category = input_iterator_tag;
2677
+ using value_type = directory_entry;
2678
+ using difference_type = ptrdiff_t;
2679
+ using pointer = const directory_entry*;
2680
+ using reference = const directory_entry&;
2681
+
2682
+ // [fs.rec.dir.itr.members], constructors and destructor
2683
+ recursive_directory_iterator() noexcept;
2684
+ explicit recursive_directory_iterator(const path& p);
2685
+ recursive_directory_iterator(const path& p, directory_options options);
2686
+ recursive_directory_iterator(const path& p, directory_options options,
2687
+ error_code& ec) noexcept;
2688
+ recursive_directory_iterator(const path& p, error_code& ec) noexcept;
2689
+ recursive_directory_iterator(const recursive_directory_iterator& rhs);
2690
+ recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
2691
+ ~recursive_directory_iterator();
2692
+
2693
+ // [fs.rec.dir.itr.members], observers
2694
+ directory_options options() const;
2695
+ int depth() const;
2696
+ bool recursion_pending() const;
2697
+
2698
+ const directory_entry& operator*() const;
2699
+ const directory_entry* operator->() const;
2700
+
2701
+ // [fs.rec.dir.itr.members], modifiers
2702
+ recursive_directory_iterator&
2703
+ operator=(const recursive_directory_iterator& rhs);
2704
+ recursive_directory_iterator&
2705
+ operator=(recursive_directory_iterator&& rhs) noexcept;
2706
+
2707
+ recursive_directory_iterator& operator++();
2708
+ recursive_directory_iterator& increment(error_code& ec) noexcept;
2709
+
2710
+ void pop();
2711
+ void pop(error_code& ec);
2712
+ void disable_recursion_pending();
2713
+
2714
+ // other members as required by [input.iterators], input iterators
2715
+ };
2716
+ }
2717
+ ```
2718
+
2719
+ Calling `options`, `depth`, `recursion_pending`, `pop` or
2720
+ `disable_recursion_pending` on an iterator that is not dereferenceable
2721
+ results in undefined behavior.
2722
+
2723
+ The behavior of a `recursive_directory_iterator` is the same as a
2724
+ `directory_iterator` unless otherwise specified.
2725
+
2726
+ [*Note 1*: If the directory structure being iterated over contains
2727
+ cycles then the end iterator may be unreachable. — *end note*]
2728
+
2729
+ #### `recursive_directory_iterator` members <a id="fs.rec.dir.itr.members">[[fs.rec.dir.itr.members]]</a>
2730
+
2731
+ ``` cpp
2732
+ recursive_directory_iterator() noexcept;
2733
+ ```
2734
+
2735
+ *Effects:* Constructs the end iterator.
2736
+
2737
+ ``` cpp
2738
+ explicit recursive_directory_iterator(const path& p);
2739
+ recursive_directory_iterator(const path& p, directory_options options);
2740
+ recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
2741
+ recursive_directory_iterator(const path& p, error_code& ec) noexcept;
2742
+ ```
2743
+
2744
+ *Effects:* Constructs a iterator representing the first entry in the
2745
+ directory `p` resolves to, if any; otherwise, the end iterator. However,
2746
+ if
2747
+
2748
+ ``` cpp
2749
+ (options & directory_options::skip_permission_denied) != directory_options::none
2750
+ ```
2751
+
2752
+ and construction encounters an error indicating that permission to
2753
+ access `p` is denied, constructs the end iterator and does not report an
2754
+ error.
2755
+
2756
+ *Postconditions:* `options() == options` for the signatures with a
2757
+ `directory_options` argument, otherwise
2758
+ `options() == directory_options::none`.
2759
+
2760
+ *Throws:* As specified in  [[fs.err.report]].
2761
+
2762
+ [*Note 1*: To iterate over the current directory, use
2763
+ `recursive_directory_iterator(".")` rather than
2764
+ `recursive_directory_iterator("")`. — *end note*]
2765
+
2766
+ [*Note 2*: By default, `recursive_directory_iterator` does not follow
2767
+ directory symlinks. To follow directory symlinks, specify `options` as
2768
+ `directory_options::follow_directory_symlink` — *end note*]
2769
+
2770
+ ``` cpp
2771
+ recursive_directory_iterator(const recursive_directory_iterator& rhs);
2772
+ ```
2773
+
2774
+ *Effects:* Constructs an object of class `recursive_directory_iterator`.
2775
+
2776
+ *Postconditions:*
2777
+
2778
+ - `options() == rhs.options()`
2779
+ - `depth() == rhs.depth()`
2780
+ - `recursion_pending() == rhs.recursion_pending()`
2781
+
2782
+ ``` cpp
2783
+ recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
2784
+ ```
2785
+
2786
+ *Effects:* Constructs an object of class `recursive_directory_iterator`.
2787
+
2788
+ *Postconditions:* `options()`, `depth()`, and `recursion_pending()` have
2789
+ the values that `rhs.options()`, `rhs.depth()`, and
2790
+ `rhs.recursion_pending()`, respectively, had before the function call.
2791
+
2792
+ ``` cpp
2793
+ recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs);
2794
+ ```
2795
+
2796
+ *Effects:* If `*this` and `rhs` are the same object, the member has no
2797
+ effect.
2798
+
2799
+ *Postconditions:*
2800
+
2801
+ - `options() == rhs.options()`
2802
+ - `depth() == rhs.depth()`
2803
+ - `recursion_pending() == rhs.recursion_pending()`
2804
+
2805
+ *Returns:* `*this`.
2806
+
2807
+ ``` cpp
2808
+ recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept;
2809
+ ```
2810
+
2811
+ *Effects:* If `*this` and `rhs` are the same object, the member has no
2812
+ effect.
2813
+
2814
+ *Postconditions:* `options()`, `depth()`, and `recursion_pending()` have
2815
+ the values that `rhs.options()`, `rhs.depth()`, and
2816
+ `rhs.recursion_pending()`, respectively, had before the function call.
2817
+
2818
+ *Returns:* `*this`.
2819
+
2820
+ ``` cpp
2821
+ directory_options options() const;
2822
+ ```
2823
+
2824
+ *Returns:* The value of the argument passed to the constructor for the
2825
+ `options` parameter, if present, otherwise `directory_options::none`.
2826
+
2827
+ *Throws:* Nothing.
2828
+
2829
+ ``` cpp
2830
+ int depth() const;
2831
+ ```
2832
+
2833
+ *Returns:* The current depth of the directory tree being traversed.
2834
+
2835
+ [*Note 3*: The initial directory is depth `0`, its immediate
2836
+ subdirectories are depth `1`, and so forth. — *end note*]
2837
+
2838
+ *Throws:* Nothing.
2839
+
2840
+ ``` cpp
2841
+ bool recursion_pending() const;
2842
+ ```
2843
+
2844
+ *Returns:* `true` if `disable_recursion_pending()` has not been called
2845
+ subsequent to the prior construction or increment operation, otherwise
2846
+ `false`.
2847
+
2848
+ *Throws:* Nothing.
2849
+
2850
+ ``` cpp
2851
+ recursive_directory_iterator& operator++();
2852
+ recursive_directory_iterator& increment(error_code& ec) noexcept;
2853
+ ```
2854
+
2855
+ *Effects:* As specified for the prefix increment operation of Input
2856
+ iterators ([[input.iterators]]), except that:
2857
+
2858
+ - If there are no more entries at the current depth, then if
2859
+ `depth() != 0` iteration over the parent directory resumes; otherwise
2860
+ `*this = recursive_directory_iterator()`.
2861
+ - Otherwise if
2862
+ ``` cpp
2863
+ recursion_pending() && is_directory((*this)->status()) &&
2864
+ (!is_symlink((*this)->symlink_status()) ||
2865
+ (options() & directory_options::follow_directory_symlink) != directory_options::none)
2866
+ ```
2867
+
2868
+ then either directory `(*this)->path()` is recursively iterated into
2869
+ or, if
2870
+ ``` cpp
2871
+ (options() & directory_options::skip_permission_denied) != directory_options::none
2872
+ ```
2873
+
2874
+ and an error occurs indicating that permission to access directory
2875
+ `(*this)->path()` is denied, then directory `(*this)->path()` is
2876
+ treated as an empty directory and no error is reported.
2877
+
2878
+ *Returns:* `*this`.
2879
+
2880
+ *Throws:* As specified in  [[fs.err.report]].
2881
+
2882
+ ``` cpp
2883
+ void pop();
2884
+ void pop(error_code& ec);
2885
+ ```
2886
+
2887
+ *Effects:* If `depth() == 0`, set `*this` to
2888
+ `recursive_directory_iterator()`. Otherwise, cease iteration of the
2889
+ directory currently being iterated over, and continue iteration over the
2890
+ parent directory.
2891
+
2892
+ *Throws:* As specified in  [[fs.err.report]].
2893
+
2894
+ ``` cpp
2895
+ void disable_recursion_pending();
2896
+ ```
2897
+
2898
+ *Postconditions:* `recursion_pending() == false`.
2899
+
2900
+ [*Note 4*: `disable_recursion_pending``()` is used to prevent unwanted
2901
+ recursion into a directory. — *end note*]
2902
+
2903
+ #### `recursive_directory_iterator` non-member functions <a id="fs.rec.dir.itr.nonmembers">[[fs.rec.dir.itr.nonmembers]]</a>
2904
+
2905
+ These functions enable use of `recursive_directory_iterator` with
2906
+ range-based for statements.
2907
+
2908
+ ``` cpp
2909
+ recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
2910
+ ```
2911
+
2912
+ *Returns:* `iter`.
2913
+
2914
+ ``` cpp
2915
+ recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
2916
+ ```
2917
+
2918
+ *Returns:* `recursive_directory_iterator()`.
2919
+
2920
+ ### Filesystem operation functions <a id="fs.op.funcs">[[fs.op.funcs]]</a>
2921
+
2922
+ Filesystem operation functions query or modify files, including
2923
+ directories, in external storage.
2924
+
2925
+ [*Note 1*: Because hardware failures, network failures, file system
2926
+ races ([[fs.def.race]]), and many other kinds of errors occur
2927
+ frequently in file system operations, users should be aware that any
2928
+ filesystem operation function, no matter how apparently innocuous, may
2929
+ encounter an error; see  [[fs.err.report]]. — *end note*]
2930
+
2931
+ #### Absolute <a id="fs.op.absolute">[[fs.op.absolute]]</a>
2932
+
2933
+ ``` cpp
2934
+ path absolute(const path& p);
2935
+ path absolute(const path& p, error_code& ec);
2936
+ ```
2937
+
2938
+ *Effects:* Composes an absolute path referencing the same file system
2939
+ location as `p` according to the operating system ([[fs.conform.os]]).
2940
+
2941
+ *Returns:* The composed path. The signature with argument `ec` returns
2942
+ `path()` if an error occurs.
2943
+
2944
+ [*Note 1*: For the returned path, `rp`, `rp.is_absolute()` is `true`
2945
+ unless an error occurs. — *end note*]
2946
+
2947
+ *Throws:* As specified in  [[fs.err.report]].
2948
+
2949
+ [*Note 2*: To resolve symlinks, or perform other sanitization which
2950
+ might require queries to secondary storage, such as hard disks, consider
2951
+ `canonical` ([[fs.op.canonical]]). — *end note*]
2952
+
2953
+ [*Note 3*: Implementations are strongly encouraged to not query
2954
+ secondary storage, and not consider `!exists(p)` an
2955
+ error. — *end note*]
2956
+
2957
+ [*Example 1*: For POSIX-based operating systems, `absolute(p)` is
2958
+ simply `current_path()/p`. For Windows-based operating systems,
2959
+ `absolute` might have the same semantics as
2960
+ `GetFullPathNameW`. — *end example*]
2961
+
2962
+ #### Canonical <a id="fs.op.canonical">[[fs.op.canonical]]</a>
2963
+
2964
+ ``` cpp
2965
+ path canonical(const path& p, const path& base = current_path());
2966
+ path canonical(const path& p, error_code& ec);
2967
+ path canonical(const path& p, const path& base, error_code& ec);
2968
+ ```
2969
+
2970
+ *Effects:* Converts `p`, which must exist, to an absolute path that has
2971
+ no symbolic link, *dot*, or *dot-dot* elements in its pathname in the
2972
+ generic format.
2973
+
2974
+ *Returns:* A path that refers to the same file system object as
2975
+ `absolute(p, base)`. For the overload without a `base` argument, `base`
2976
+ is `current_path()`. Signatures with argument `ec` return `path()` if an
2977
+ error occurs.
2978
+
2979
+ *Throws:* As specified in  [[fs.err.report]].
2980
+
2981
+ *Remarks:* `!exists(p)` is an error.
2982
+
2983
+ #### Copy <a id="fs.op.copy">[[fs.op.copy]]</a>
2984
+
2985
+ ``` cpp
2986
+ void copy(const path& from, const path& to);
2987
+ ```
2988
+
2989
+ *Effects:* Equivalent to `copy(from, to, copy_options::none)`.
2990
+
2991
+ ``` cpp
2992
+ void copy(const path& from, const path& to, error_code& ec) noexcept;
2993
+ ```
2994
+
2995
+ *Effects:* Equivalent to `copy(from, to, copy_options::none, ec)`.
2996
+
2997
+ ``` cpp
2998
+ void copy(const path& from, const path& to, copy_options options);
2999
+ void copy(const path& from, const path& to, copy_options options,
3000
+ error_code& ec) noexcept;
3001
+ ```
3002
+
3003
+ *Requires:* At most one element from each option group
3004
+ ([[fs.enum.copy.opts]]) is set in `options`.
3005
+
3006
+ *Effects:* Before the first use of `f` and `t`:
3007
+
3008
+ - If
3009
+ ``` cpp
3010
+ (options & copy_options::create_symlinks) != copy_options::none ||
3011
+ (options & copy_options::skip_symlinks) != copy_options::none
3012
+ ```
3013
+
3014
+ then `auto f = symlink_status(from)` and if needed
3015
+ `auto t = symlink_status(to)`.
3016
+ - Otherwise, if
3017
+ ``` cpp
3018
+ (options & copy_options::copy_symlinks) != copy_options::none
3019
+ ```
3020
+
3021
+ then `auto f = symlink_status(from)` and if needed
3022
+ `auto t = status(to)`.
3023
+ - Otherwise, `auto f = status(from)` and if needed
3024
+ `auto t = status(to)`.
3025
+
3026
+ Effects are then as follows:
3027
+
3028
+ - If `f.type()` or `t.type()` is an implementation-defined file
3029
+ type ([[fs.enum.file_type]]), then the effects are
3030
+ *implementation-defined*.
3031
+ - Otherwise, an error is reported as specified in  [[fs.err.report]] if:
3032
+ - `!exists(f)`, or
3033
+ - `equivalent(from, to)`, or
3034
+ - `is_other(f) || is_other(t)`, or
3035
+ - `is_directory(f) && is_regular_file(t)`.
3036
+ - Otherwise, if `is_symlink(f)`, then:
3037
+ - If `(options & copy_options::skip_symlinks) != copy_options::none`
3038
+ then return.
3039
+ - Otherwise if
3040
+ ``` cpp
3041
+ !exists(t) && (options & copy_options::copy_symlinks) != copy_options::none
3042
+ ```
3043
+
3044
+ then `copy_symlink(from, to)`.
3045
+ - Otherwise report an error as specified in  [[fs.err.report]].
3046
+ - Otherwise, if `is_regular_file(f)`, then:
3047
+ - If
3048
+ `(options & copy_options::directories_only) != copy_options::none`,
3049
+ then return.
3050
+ - Otherwise, if
3051
+ `(options & copy_options::create_symlinks) `` != copy_options::none`,
3052
+ then create a symbolic link to the source file.
3053
+ - Otherwise, if
3054
+ `(options & copy_options::create_hard_links) != copy_options::none`,
3055
+ then create a hard link to the source file.
3056
+ - Otherwise, if `is_directory(t)`, then
3057
+ `copy_file(from, to/from.filename(), options)`.
3058
+ - Otherwise, `copy_file(from, to, options)`.
3059
+ - Otherwise, if
3060
+ ``` cpp
3061
+ is_directory(f) &&
3062
+ ((options & copy_options::recursive) != copy_options::none ||
3063
+ options == copy_options::none)
3064
+ ```
3065
+
3066
+ then:
3067
+ - If `!exists(t)`, then `create_directory(to, from)`.
3068
+ - Then, iterate over the files in `from`, as if by
3069
+ ``` cpp
3070
+ for (const directory_entry& x : directory_iterator(from))
3071
+ copy(x.path(), to/x.path().filename(), options | copy_options::unspecified)
3072
+ ```
3073
+ - Otherwise, for the signature with argument `ec`, `ec.clear()`.
3074
+ - Otherwise, no effects.
3075
+
3076
+ *Throws:* As specified in  [[fs.err.report]].
3077
+
3078
+ *Remarks:* For the signature with argument `ec`, any library functions
3079
+ called by the implementation shall have an `error_code` argument if
3080
+ applicable.
3081
+
3082
+ [*Example 1*:
3083
+
3084
+ Given this directory structure:
3085
+
3086
+ ``` cpp
3087
+ /dir1
3088
+ file1
3089
+ file2
3090
+ dir2
3091
+ file3
3092
+ ```
3093
+
3094
+ Calling `copy("/dir1", "/dir3")` would result in:
3095
+
3096
+ ``` cpp
3097
+ /dir1
3098
+ file1
3099
+ file2
3100
+ dir2
3101
+ file3
3102
+ /dir3
3103
+ file1
3104
+ file2
3105
+ ```
3106
+
3107
+ Alternatively, calling `copy("/dir1", "/dir3", copy_options::recursive)`
3108
+ would result in:
3109
+
3110
+ ``` cpp
3111
+ /dir1
3112
+ file1
3113
+ file2
3114
+ dir2
3115
+ file3
3116
+ /dir3
3117
+ file1
3118
+ file2
3119
+ dir2
3120
+ file3
3121
+ ```
3122
+
3123
+ — *end example*]
3124
+
3125
+ #### Copy file <a id="fs.op.copy_file">[[fs.op.copy_file]]</a>
3126
+
3127
+ ``` cpp
3128
+ bool copy_file(const path& from, const path& to);
3129
+ bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
3130
+ ```
3131
+
3132
+ *Returns:* `copy_file(from, to, copy_options::none)` or
3133
+ `copy_file(from, to, copy_options::none, ec)`, respectively.
3134
+
3135
+ *Throws:* As specified in  [[fs.err.report]].
3136
+
3137
+ ``` cpp
3138
+ bool copy_file(const path& from, const path& to, copy_options options);
3139
+ bool copy_file(const path& from, const path& to, copy_options options,
3140
+ error_code& ec) noexcept;
3141
+ ```
3142
+
3143
+ *Requires:* At most one element from each option group
3144
+ ([[fs.enum.copy.opts]]) is set in `options`.
3145
+
3146
+ *Effects:* As follows:
3147
+
3148
+ - Report a file already exists error as specified in  [[fs.err.report]]
3149
+ if:
3150
+ - `!is_regular_file(from)`, or
3151
+ - `exists(to)` and `!is_regular_file(to)`, or
3152
+ - `exists(to)` and `equivalent(from, to)`, or
3153
+ - `exists(to)` and
3154
+ ``` cpp
3155
+ (options & (copy_options::skip_existing |
3156
+ copy_options::overwrite_existing |
3157
+ copy_options::update_existing)) == copy_options::none
3158
+ ```
3159
+ - Otherwise, copy the contents and attributes of the file `from`
3160
+ resolves to, to the file `to` resolves to, if:
3161
+ - `!exists(to)`, or
3162
+ - `(options & copy_options::overwrite_existing) != copy_options::none`,
3163
+ or
3164
+ - `(options & copy_options::update_existing) `` `` != copy_options::none`
3165
+ and `from` is more recent than `to`, determined as if by use of the
3166
+ `last_write_time` function ([[fs.op.last_write_time]]).
3167
+ - Otherwise, no effects.
3168
+
3169
+ *Returns:* `true` if the `from` file was copied, otherwise `false`. The
3170
+ signature with argument `ec` returns `false` if an error occurs.
3171
+
3172
+ *Throws:* As specified in  [[fs.err.report]].
3173
+
3174
+ *Complexity:* At most one direct or indirect invocation of `status(to)`.
3175
+
3176
+ #### Copy symlink <a id="fs.op.copy_symlink">[[fs.op.copy_symlink]]</a>
3177
+
3178
+ ``` cpp
3179
+ void copy_symlink(const path& existing_symlink, const path& new_symlink);
3180
+ void copy_symlink(const path& existing_symlink, const path& new_symlink,
3181
+ error_code& ec) noexcept;
3182
+ ```
3183
+
3184
+ *Effects:* Equivalent to
3185
+ *`function`*`(read_symlink(existing_symlink), new_symlink)` or
3186
+ *`function`*`(read_symlink(existing_symlink, ec), new_symlink, ec)`,
3187
+ respectively, where in each case *`function`* is `create_symlink` or
3188
+ `create_directory_symlink` as appropriate.
3189
+
3190
+ *Throws:* As specified in  [[fs.err.report]].
3191
+
3192
+ #### Create directories <a id="fs.op.create_directories">[[fs.op.create_directories]]</a>
3193
+
3194
+ ``` cpp
3195
+ bool create_directories(const path& p);
3196
+ bool create_directories(const path& p, error_code& ec) noexcept;
3197
+ ```
3198
+
3199
+ *Effects:* Establishes the postcondition by calling `create_directory()`
3200
+ for any element of `p` that does not exist.
3201
+
3202
+ *Postconditions:* `is_directory(p)`.
3203
+
3204
+ *Returns:* `true` if a new directory was created, otherwise `false`. The
3205
+ signature with argument `ec` returns `false` if an error occurs.
3206
+
3207
+ *Throws:* As specified in  [[fs.err.report]].
3208
+
3209
+ *Complexity:* 𝑂(n) where *n* is the number of elements of `p` that do
3210
+ not exist.
3211
+
3212
+ #### Create directory <a id="fs.op.create_directory">[[fs.op.create_directory]]</a>
3213
+
3214
+ ``` cpp
3215
+ bool create_directory(const path& p);
3216
+ bool create_directory(const path& p, error_code& ec) noexcept;
3217
+ ```
3218
+
3219
+ *Effects:* Establishes the postcondition by attempting to create the
3220
+ directory `p` resolves to, as if by POSIX `mkdir()` with a second
3221
+ argument of `static_cast<int>(perms::all)`. Creation failure because `p`
3222
+ resolves to an existing directory shall not be treated as an error.
3223
+
3224
+ *Postconditions:* `is_directory(p)`.
3225
+
3226
+ *Returns:* `true` if a new directory was created, otherwise `false`. The
3227
+ signature with argument `ec` returns `false` if an error occurs.
3228
+
3229
+ *Throws:* As specified in  [[fs.err.report]].
3230
+
3231
+ ``` cpp
3232
+ bool create_directory(const path& p, const path& existing_p);
3233
+ bool create_directory(const path& p, const path& existing_p, error_code& ec) noexcept;
3234
+ ```
3235
+
3236
+ *Effects:* Establishes the postcondition by attempting to create the
3237
+ directory `p` resolves to, with attributes copied from directory
3238
+ `existing_p`. The set of attributes copied is operating system
3239
+ dependent. Creation failure because `p` resolves to an existing
3240
+ directory shall not be treated as an error.
3241
+
3242
+ [*Note 1*: For POSIX-based operating systems, the attributes are those
3243
+ copied by native API `stat(existing_p.c_str(), &attributes_stat)`
3244
+ followed by `mkdir(p.c_str(), attributes_stat.st_mode)`. For
3245
+ Windows-based operating systems, the attributes are those copied by
3246
+ native API
3247
+ `CreateDirectoryExW(existing_p.c_str(), p.c_str(), 0)`. — *end note*]
3248
+
3249
+ *Postconditions:* `is_directory(p)`.
3250
+
3251
+ *Returns:* `true` if a new directory was created, otherwise `false`. The
3252
+ signature with argument `ec` returns `false` if an error occurs.
3253
+
3254
+ *Throws:* As specified in  [[fs.err.report]].
3255
+
3256
+ #### Create directory symlink <a id="fs.op.create_dir_symlk">[[fs.op.create_dir_symlk]]</a>
3257
+
3258
+ ``` cpp
3259
+ void create_directory_symlink(const path& to, const path& new_symlink);
3260
+ void create_directory_symlink(const path& to, const path& new_symlink,
3261
+ error_code& ec) noexcept;
3262
+ ```
3263
+
3264
+ *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
3265
+
3266
+ *Postconditions:* `new_symlink` resolves to a symbolic link file that
3267
+ contains an unspecified representation of `to`.
3268
+
3269
+ *Throws:* As specified in  [[fs.err.report]].
3270
+
3271
+ [*Note 1*: Some operating systems require symlink creation to identify
3272
+ that the link is to a directory. Portable code should use
3273
+ `create_directory_symlink()` to create directory symlinks rather than
3274
+ `create_symlink()` — *end note*]
3275
+
3276
+ [*Note 2*: Some operating systems do not support symbolic links at all
3277
+ or support them only for regular files. Some file systems (such as the
3278
+ FAT file system) do not support symbolic links regardless of the
3279
+ operating system. — *end note*]
3280
+
3281
+ #### Create hard link <a id="fs.op.create_hard_lk">[[fs.op.create_hard_lk]]</a>
3282
+
3283
+ ``` cpp
3284
+ void create_hard_link(const path& to, const path& new_hard_link);
3285
+ void create_hard_link(const path& to, const path& new_hard_link,
3286
+ error_code& ec) noexcept;
3287
+ ```
3288
+
3289
+ *Effects:* Establishes the postcondition, as if by POSIX `link()`.
3290
+
3291
+ *Postconditions:*
3292
+
3293
+ - `exists(to) && exists(new_hard_link) && equivalent(to, new_hard_link)`
3294
+ - The contents of the file or directory `to` resolves to are unchanged.
3295
+
3296
+ *Throws:* As specified in  [[fs.err.report]].
3297
+
3298
+ [*Note 1*: Some operating systems do not support hard links at all or
3299
+ support them only for regular files. Some file systems (such as the FAT
3300
+ file system) do not support hard links regardless of the operating
3301
+ system. Some file systems limit the number of links per
3302
+ file. — *end note*]
3303
+
3304
+ #### Create symlink <a id="fs.op.create_symlink">[[fs.op.create_symlink]]</a>
3305
+
3306
+ ``` cpp
3307
+ void create_symlink(const path& to, const path& new_symlink);
3308
+ void create_symlink(const path& to, const path& new_symlink,
3309
+ error_code& ec) noexcept;
3310
+ ```
3311
+
3312
+ *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
3313
+
3314
+ *Postconditions:* `new_symlink` resolves to a symbolic link file that
3315
+ contains an unspecified representation of `to`.
3316
+
3317
+ *Throws:* As specified in  [[fs.err.report]].
3318
+
3319
+ [*Note 1*: Some operating systems do not support symbolic links at all
3320
+ or support them only for regular files. Some file systems (such as the
3321
+ FAT file system) do not support symbolic links regardless of the
3322
+ operating system. — *end note*]
3323
+
3324
+ #### Current path <a id="fs.op.current_path">[[fs.op.current_path]]</a>
3325
+
3326
+ ``` cpp
3327
+ path current_path();
3328
+ path current_path(error_code& ec);
3329
+ ```
3330
+
3331
+ *Returns:* The absolute path of the current working directory, whose
3332
+ pathname in the native format is obtained as if by POSIX `getcwd()`. The
3333
+ signature with argument `ec` returns `path()` if an error occurs.
3334
+
3335
+ *Throws:* As specified in  [[fs.err.report]].
3336
+
3337
+ *Remarks:* The current working directory is the directory, associated
3338
+ with the process, that is used as the starting location in pathname
3339
+ resolution for relative paths.
3340
+
3341
+ [*Note 1*: The `current_path()` name was chosen to emphasize that the
3342
+ returned value is a path, not just a single directory
3343
+ name. — *end note*]
3344
+
3345
+ [*Note 2*: The current path as returned by many operating systems is a
3346
+ dangerous global variable. It may be changed unexpectedly by a
3347
+ third-party or system library functions, or by another
3348
+ thread. — *end note*]
3349
+
3350
+ ``` cpp
3351
+ void current_path(const path& p);
3352
+ void current_path(const path& p, error_code& ec) noexcept;
3353
+ ```
3354
+
3355
+ *Effects:* Establishes the postcondition, as if by POSIX `chdir()`.
3356
+
3357
+ *Postconditions:* `equivalent(p, current_path())`.
3358
+
3359
+ *Throws:* As specified in  [[fs.err.report]].
3360
+
3361
+ [*Note 3*: The current path for many operating systems is a dangerous
3362
+ global state. It may be changed unexpectedly by a third-party or system
3363
+ library functions, or by another thread. — *end note*]
3364
+
3365
+ #### Equivalent <a id="fs.op.equivalent">[[fs.op.equivalent]]</a>
3366
+
3367
+ ``` cpp
3368
+ bool equivalent(const path& p1, const path& p2);
3369
+ bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
3370
+ ```
3371
+
3372
+ Let `s1` and `s2` be `file_status`s, determined as if by `status(p1)`
3373
+ and `status(p2)`, respectively.
3374
+
3375
+ *Effects:* Determines `s1` and `s2`. If
3376
+ `(!exists(s1) && !exists(s2)) || (is_other(s1) && is_other(s2))` an
3377
+ error is reported ([[fs.err.report]]).
3378
+
3379
+ *Returns:* `true`, if `s1 == s2` and `p1` and `p2` resolve to the same
3380
+ file system entity, else `false`. The signature with argument `ec`
3381
+ returns `false` if an error occurs.
3382
+
3383
+ Two paths are considered to resolve to the same file system entity if
3384
+ two candidate entities reside on the same device at the same location.
3385
+ This is determined as if by the values of the POSIX `stat` structure,
3386
+ obtained as if by `stat()` for the two paths, having equal `st_dev`
3387
+ values and equal `st_ino` values.
3388
+
3389
+ *Throws:* As specified in  [[fs.err.report]].
3390
+
3391
+ #### Exists <a id="fs.op.exists">[[fs.op.exists]]</a>
3392
+
3393
+ ``` cpp
3394
+ bool exists(file_status s) noexcept;
3395
+ ```
3396
+
3397
+ *Returns:* `status_known(s) && s.type() != file_type::not_found`.
3398
+
3399
+ ``` cpp
3400
+ bool exists(const path& p);
3401
+ bool exists(const path& p, error_code& ec) noexcept;
3402
+ ```
3403
+
3404
+ Let `s` be a `file_status`, determined as if by `status(p)` or
3405
+ `status(p, ec)`, respectively.
3406
+
3407
+ *Effects:* The signature with argument `ec` calls `ec.clear()` if
3408
+ `status_known(s)`.
3409
+
3410
+ *Returns:* `exists(s)`.
3411
+
3412
+ *Throws:* As specified in  [[fs.err.report]].
3413
+
3414
+ #### File size <a id="fs.op.file_size">[[fs.op.file_size]]</a>
3415
+
3416
+ ``` cpp
3417
+ uintmax_t file_size(const path& p);
3418
+ uintmax_t file_size(const path& p, error_code& ec) noexcept;
3419
+ ```
3420
+
3421
+ *Returns:*
3422
+
3423
+ - If `!exists(p)` an error is reported ([[fs.err.report]]).
3424
+ - Otherwise, if `is_regular_file(p)`, the size in bytes of the file `p`
3425
+ resolves to, determined as if by the value of the POSIX `stat`
3426
+ structure member `st_size` obtained as if by POSIX `stat()`.
3427
+ - Otherwise, the result is *implementation-defined*.
3428
+
3429
+ The signature with argument `ec` returns `static_cast<uintmax_t>(-1)` if
3430
+ an error occurs.
3431
+
3432
+ *Throws:* As specified in  [[fs.err.report]].
3433
+
3434
+ #### Hard link count <a id="fs.op.hard_lk_ct">[[fs.op.hard_lk_ct]]</a>
3435
+
3436
+ ``` cpp
3437
+ uintmax_t hard_link_count(const path& p);
3438
+ uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
3439
+ ```
3440
+
3441
+ *Returns:* The number of hard links for `p`. The signature with argument
3442
+ `ec` returns `static_cast<uintmax_t>(-1)` if an error occurs.
3443
+
3444
+ *Throws:* As specified in  [[fs.err.report]].
3445
+
3446
+ #### Is block file <a id="fs.op.is_block_file">[[fs.op.is_block_file]]</a>
3447
+
3448
+ ``` cpp
3449
+ bool is_block_file(file_status s) noexcept;
3450
+ ```
3451
+
3452
+ *Returns:* `s.type() == file_type::block`.
3453
+
3454
+ ``` cpp
3455
+ bool is_block_file(const path& p);
3456
+ bool is_block_file(const path& p, error_code& ec) noexcept;
3457
+ ```
3458
+
3459
+ *Returns:* `is_block_file(status(p))` or `is_block_file(status(p, ec))`,
3460
+ respectively. The signature with argument `ec` returns `false` if an
3461
+ error occurs.
3462
+
3463
+ *Throws:* As specified in  [[fs.err.report]].
3464
+
3465
+ #### Is character file <a id="fs.op.is_char_file">[[fs.op.is_char_file]]</a>
3466
+
3467
+ ``` cpp
3468
+ bool is_character_file(file_status s) noexcept;
3469
+ ```
3470
+
3471
+ *Returns:* `s.type() == file_type::character`.
3472
+
3473
+ ``` cpp
3474
+ bool is_character_file(const path& p);
3475
+ bool is_character_file(const path& p, error_code& ec) noexcept;
3476
+ ```
3477
+
3478
+ *Returns:* `is_character_file(status(p))` or
3479
+ `is_character_file(status(p, ec))`, respectively.
3480
+ The signature with argument `ec` returns `false` if an error occurs.
3481
+
3482
+ *Throws:* As specified in  [[fs.err.report]].
3483
+
3484
+ #### Is directory <a id="fs.op.is_directory">[[fs.op.is_directory]]</a>
3485
+
3486
+ ``` cpp
3487
+ bool is_directory(file_status s) noexcept;
3488
+ ```
3489
+
3490
+ *Returns:* `s.type() == file_type::directory`.
3491
+
3492
+ ``` cpp
3493
+ bool is_directory(const path& p);
3494
+ bool is_directory(const path& p, error_code& ec) noexcept;
3495
+ ```
3496
+
3497
+ *Returns:* `is_directory(status(p))` or `is_directory(status(p, ec))`,
3498
+ respectively. The signature with argument `ec` returns `false` if an
3499
+ error occurs.
3500
+
3501
+ *Throws:* As specified in  [[fs.err.report]].
3502
+
3503
+ #### Is empty <a id="fs.op.is_empty">[[fs.op.is_empty]]</a>
3504
+
3505
+ ``` cpp
3506
+ bool is_empty(const path& p);
3507
+ bool is_empty(const path& p, error_code& ec) noexcept;
3508
+ ```
3509
+
3510
+ *Effects:*
3511
+
3512
+ - Determine `file_status s`, as if by `status(p)` or `status(p, ec)`,
3513
+ respectively.
3514
+ - For the signature with argument `ec`, return `false` if an error
3515
+ occurred.
3516
+ - Otherwise, if `is_directory(s)`:
3517
+ - Create a variable `itr`, as if by `directory_iterator itr(p)` or
3518
+ `directory_iterator itr(p, ec)`, respectively.
3519
+ - For the signature with argument `ec`, return `false` if an error
3520
+ occurred.
3521
+ - Otherwise, return `itr == directory_iterator()`.
3522
+ - Otherwise:
3523
+ - Determine `uintmax_t sz`, as if by `file_size(p)` or
3524
+ `file_size(p, ec)`, respectively.
3525
+ - For the signature with argument `ec`, return `false` if an error
3526
+ occurred.
3527
+ - Otherwise, return `sz == 0`.
3528
+
3529
+ *Throws:* As specified in  [[fs.err.report]].
3530
+
3531
+ #### Is fifo <a id="fs.op.is_fifo">[[fs.op.is_fifo]]</a>
3532
+
3533
+ ``` cpp
3534
+ bool is_fifo(file_status s) noexcept;
3535
+ ```
3536
+
3537
+ *Returns:* `s.type() == file_type::fifo`.
3538
+
3539
+ ``` cpp
3540
+ bool is_fifo(const path& p);
3541
+ bool is_fifo(const path& p, error_code& ec) noexcept;
3542
+ ```
3543
+
3544
+ *Returns:* `is_fifo(status(p))` or `is_fifo(status(p, ec))`,
3545
+ respectively. The signature with argument `ec` returns `false` if an
3546
+ error occurs.
3547
+
3548
+ *Throws:* As specified in  [[fs.err.report]].
3549
+
3550
+ #### Is other <a id="fs.op.is_other">[[fs.op.is_other]]</a>
3551
+
3552
+ ``` cpp
3553
+ bool is_other(file_status s) noexcept;
3554
+ ```
3555
+
3556
+ *Returns:*
3557
+ `exists(s) && !is_regular_file(s) && !is_directory(s) && !is_symlink(s)`.
3558
+
3559
+ ``` cpp
3560
+ bool is_other(const path& p);
3561
+ bool is_other(const path& p, error_code& ec) noexcept;
3562
+ ```
3563
+
3564
+ *Returns:* `is_other(status(p))` or `is_other(status(p, ec))`,
3565
+ respectively. The signature with argument `ec` returns `false` if an
3566
+ error occurs.
3567
+
3568
+ *Throws:* As specified in  [[fs.err.report]].
3569
+
3570
+ #### Is regular file <a id="fs.op.is_regular_file">[[fs.op.is_regular_file]]</a>
3571
+
3572
+ ``` cpp
3573
+ bool is_regular_file(file_status s) noexcept;
3574
+ ```
3575
+
3576
+ *Returns:* `s.type() == file_type::regular`.
3577
+
3578
+ ``` cpp
3579
+ bool is_regular_file(const path& p);
3580
+ ```
3581
+
3582
+ *Returns:* `is_regular_file(status(p))`.
3583
+
3584
+ *Throws:* `filesystem_error` if `status(p)` would throw
3585
+ `filesystem_error.`
3586
+
3587
+ ``` cpp
3588
+ bool is_regular_file(const path& p, error_code& ec) noexcept;
3589
+ ```
3590
+
3591
+ *Effects:* Sets `ec` as if by `status(p, ec)`.
3592
+
3593
+ [*Note 1*: `file_type::none`, `file_type::not_found` and
3594
+ `file_type::unknown` cases set `ec` to error values. To distinguish
3595
+ between cases, call the `status` function directly. — *end note*]
3596
+
3597
+ *Returns:* `is_regular_file(status(p, ec))`. Returns `false` if an error
3598
+ occurs.
3599
+
3600
+ #### Is socket <a id="fs.op.is_socket">[[fs.op.is_socket]]</a>
3601
+
3602
+ ``` cpp
3603
+ bool is_socket(file_status s) noexcept;
3604
+ ```
3605
+
3606
+ *Returns:* `s.type() == file_type::socket`.
3607
+
3608
+ ``` cpp
3609
+ bool is_socket(const path& p);
3610
+ bool is_socket(const path& p, error_code& ec) noexcept;
3611
+ ```
3612
+
3613
+ *Returns:* `is_socket(status(p))` or `is_socket(status(p, ec))`,
3614
+ respectively. The signature with argument `ec` returns `false` if an
3615
+ error occurs.
3616
+
3617
+ *Throws:* As specified in  [[fs.err.report]].
3618
+
3619
+ #### Is symlink <a id="fs.op.is_symlink">[[fs.op.is_symlink]]</a>
3620
+
3621
+ ``` cpp
3622
+ bool is_symlink(file_status s) noexcept;
3623
+ ```
3624
+
3625
+ *Returns:* `s.type() == file_type::symlink`.
3626
+
3627
+ ``` cpp
3628
+ bool is_symlink(const path& p);
3629
+ bool is_symlink(const path& p, error_code& ec) noexcept;
3630
+ ```
3631
+
3632
+ *Returns:* `is_symlink(symlink_status(p))` or
3633
+ `is_symlink(symlink_status(p, ec))`, respectively. The signature with
3634
+ argument `ec` returns `false` if an error occurs.
3635
+
3636
+ *Throws:* As specified in  [[fs.err.report]].
3637
+
3638
+ #### Last write time <a id="fs.op.last_write_time">[[fs.op.last_write_time]]</a>
3639
+
3640
+ ``` cpp
3641
+ file_time_type last_write_time(const path& p);
3642
+ file_time_type last_write_time(const path& p, error_code& ec) noexcept;
3643
+ ```
3644
+
3645
+ *Returns:* The time of last data modification of `p`, determined as if
3646
+ by the value of the POSIX `stat` structure member `st_mtime` obtained as
3647
+ if by POSIX `stat()`. The signature with argument `ec` returns
3648
+ `file_time_type::min()` if an error occurs.
3649
+
3650
+ *Throws:* As specified in  [[fs.err.report]].
3651
+
3652
+ ``` cpp
3653
+ void last_write_time(const path& p, file_time_type new_time);
3654
+ void last_write_time(const path& p, file_time_type new_time,
3655
+ error_code& ec) noexcept;
3656
+ ```
3657
+
3658
+ *Effects:* Sets the time of last data modification of the file resolved
3659
+ to by `p` to `new_time`, as if by POSIX `futimens()`.
3660
+
3661
+ *Throws:* As specified in  [[fs.err.report]].
3662
+
3663
+ [*Note 1*: A postcondition of `last_write_time(p) == new_time` is not
3664
+ specified since it might not hold for file systems with coarse time
3665
+ granularity. — *end note*]
3666
+
3667
+ #### Permissions <a id="fs.op.permissions">[[fs.op.permissions]]</a>
3668
+
3669
+ ``` cpp
3670
+ void permissions(const path& p, perms prms, perm_options opts=perm_options::replace);
3671
+ void permissions(const path& p, perms prms, error_code& ec) noexcept;
3672
+ void permissions(const path& p, perms prms, perm_options opts, error_code& ec);
3673
+ ```
3674
+
3675
+ *Requires:* Exactly one of the `perm_options` constants `replace`,
3676
+ `add`, or `remove` is present in `opts`.
3677
+
3678
+ *Remarks:* The second signature behaves as if it had an additional
3679
+ parameter `perm_options` `opts` with an argument of
3680
+ `perm_options::replace`.
3681
+
3682
+ *Effects:* Applies the action specified by `opts` to the file `p`
3683
+ resolves to, or to file `p` itself if `p` is a symbolic link and
3684
+ `perm_options::nofollow` is set in `opts`. The action is applied as if
3685
+ by POSIX `fchmodat()`.
3686
+
3687
+ [*Note 1*: Conceptually permissions are viewed as bits, but the actual
3688
+ implementation may use some other mechanism. — *end note*]
3689
+
3690
+ *Throws:* As specified in  [[fs.err.report]].
3691
+
3692
+ #### Proximate <a id="fs.op.proximate">[[fs.op.proximate]]</a>
3693
+
3694
+ ``` cpp
3695
+ path proximate(const path& p, error_code& ec);
3696
+ ```
3697
+
3698
+ *Returns:* `proximate(p, current_path(), ec)`.
3699
+
3700
+ *Throws:* As specified in  [[fs.err.report]].
3701
+
3702
+ ``` cpp
3703
+ path proximate(const path& p, const path& base = current_path());
3704
+ path proximate(const path& p, const path& base, error_code& ec);
3705
+ ```
3706
+
3707
+ *Returns:* For the first form:
3708
+
3709
+ ``` cpp
3710
+ weakly_canonical(p).lexically_proximate(weakly_canonical(base));
3711
+ ```
3712
+
3713
+ For the second form:
3714
+
3715
+ ``` cpp
3716
+ weakly_canonical(p, ec).lexically_proximate(weakly_canonical(base, ec));
3717
+ ```
3718
+
3719
+ or `path()` at the first error occurrence, if any.
3720
+
3721
+ *Throws:* As specified in  [[fs.err.report]].
3722
+
3723
+ #### Read symlink <a id="fs.op.read_symlink">[[fs.op.read_symlink]]</a>
3724
+
3725
+ ``` cpp
3726
+ path read_symlink(const path& p);
3727
+ path read_symlink(const path& p, error_code& ec);
3728
+ ```
3729
+
3730
+ *Returns:* If `p` resolves to a symbolic link, a `path` object
3731
+ containing the contents of that symbolic link. The signature with
3732
+ argument `ec` returns `path()` if an error occurs.
3733
+
3734
+ *Throws:* As specified in  [[fs.err.report]].
3735
+
3736
+ [*Note 1*: It is an error if `p` does not resolve to a symbolic
3737
+ link. — *end note*]
3738
+
3739
+ #### Relative <a id="fs.op.relative">[[fs.op.relative]]</a>
3740
+
3741
+ ``` cpp
3742
+ path relative(const path& p, error_code& ec);
3743
+ ```
3744
+
3745
+ *Returns:* `relative(p, current_path(), ec)`.
3746
+
3747
+ *Throws:* As specified in  [[fs.err.report]].
3748
+
3749
+ ``` cpp
3750
+ path relative(const path& p, const path& base = current_path());
3751
+ path relative(const path& p, const path& base, error_code& ec);
3752
+ ```
3753
+
3754
+ *Returns:* For the first form:
3755
+
3756
+ ``` cpp
3757
+ weakly_canonical(p).lexically_relative(weakly_canonical(base));
3758
+ ```
3759
+
3760
+ For the second form:
3761
+
3762
+ ``` cpp
3763
+ weakly_canonical(p, ec).lexically_relative(weakly_canonical(base, ec));
3764
+ ```
3765
+
3766
+ or `path()` at the first error occurrence, if any.
3767
+
3768
+ *Throws:* As specified in  [[fs.err.report]].
3769
+
3770
+ #### Remove <a id="fs.op.remove">[[fs.op.remove]]</a>
3771
+
3772
+ ``` cpp
3773
+ bool remove(const path& p);
3774
+ bool remove(const path& p, error_code& ec) noexcept;
3775
+ ```
3776
+
3777
+ *Effects:* If `exists(symlink_status(p, ec))`, the file `p` is removed
3778
+ as if by POSIX `remove()`.
3779
+
3780
+ [*Note 1*: A symbolic link is itself removed, rather than the file it
3781
+ resolves to. — *end note*]
3782
+
3783
+ *Postconditions:* `!exists(symlink_status(p))`.
3784
+
3785
+ *Returns:* `false` if `p` did not exist, otherwise `true`. The signature
3786
+ with argument `ec` returns `false` if an error occurs.
3787
+
3788
+ *Throws:* As specified in  [[fs.err.report]].
3789
+
3790
+ #### Remove all <a id="fs.op.remove_all">[[fs.op.remove_all]]</a>
3791
+
3792
+ ``` cpp
3793
+ uintmax_t remove_all(const path& p);
3794
+ uintmax_t remove_all(const path& p, error_code& ec) noexcept;
3795
+ ```
3796
+
3797
+ *Effects:* Recursively deletes the contents of `p` if it exists, then
3798
+ deletes file `p` itself, as if by POSIX `remove()`.
3799
+
3800
+ [*Note 1*: A symbolic link is itself removed, rather than the file it
3801
+ resolves to. — *end note*]
3802
+
3803
+ *Postconditions:* `!exists(symlink_status(p))`.
3804
+
3805
+ *Returns:* The number of files removed. The signature with argument `ec`
3806
+ returns `static_cast< uintmax_t>(-1)` if an error occurs.
3807
+
3808
+ *Throws:* As specified in  [[fs.err.report]].
3809
+
3810
+ #### Rename <a id="fs.op.rename">[[fs.op.rename]]</a>
3811
+
3812
+ ``` cpp
3813
+ void rename(const path& old_p, const path& new_p);
3814
+ void rename(const path& old_p, const path& new_p, error_code& ec) noexcept;
3815
+ ```
3816
+
3817
+ *Effects:* Renames `old_p` to `new_p`, as if by POSIX `rename()`.
3818
+
3819
+ [*Note 1*:
3820
+
3821
+ - If `old_p` and `new_p` resolve to the same existing file, no action is
3822
+ taken.
3823
+ - Otherwise, the rename may include the following effects:
3824
+ - if `new_p` resolves to an existing non-directory file, `new_p` is
3825
+ removed; otherwise,
3826
+ - if `new_p` resolves to an existing directory, `new_p` is removed if
3827
+ empty on POSIX compliant operating systems but may be an error on
3828
+ other operating systems.
3829
+
3830
+ A symbolic link is itself renamed, rather than the file it resolves to.
3831
+
3832
+ — *end note*]
3833
+
3834
+ *Throws:* As specified in  [[fs.err.report]].
3835
+
3836
+ #### Resize file <a id="fs.op.resize_file">[[fs.op.resize_file]]</a>
3837
+
3838
+ ``` cpp
3839
+ void resize_file(const path& p, uintmax_t new_size);
3840
+ void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept;
3841
+ ```
3842
+
3843
+ *Postconditions:* `file_size(p) == new_size`.
3844
+
3845
+ *Throws:* As specified in  [[fs.err.report]].
3846
+
3847
+ *Remarks:* Achieves its postconditions as if by POSIX `truncate()`.
3848
+
3849
+ #### Space <a id="fs.op.space">[[fs.op.space]]</a>
3850
+
3851
+ ``` cpp
3852
+ space_info space(const path& p);
3853
+ space_info space(const path& p, error_code& ec) noexcept;
3854
+ ```
3855
+
3856
+ *Returns:* An object of type `space_info`. The value of the `space_info`
3857
+ object is determined as if by using POSIX `statvfs` to obtain a POSIX
3858
+ `struct statvfs`, and then multiplying its `f_blocks`, `f_bfree`, and
3859
+ `f_bavail` members by its `f_frsize` member, and assigning the results
3860
+ to the `capacity`, `free`, and `available` members respectively. Any
3861
+ members for which the value cannot be determined shall be set to
3862
+ `static_cast<uintmax_t>(-1)`. For the signature with argument `ec`, all
3863
+ members are set to `static_cast<uintmax_t>(-1)` if an error occurs.
3864
+
3865
+ *Throws:* As specified in  [[fs.err.report]].
3866
+
3867
+ *Remarks:* The value of member `space_info::available` is operating
3868
+ system dependent.
3869
+
3870
+ [*Note 1*: `available` may be less than `free`. — *end note*]
3871
+
3872
+ #### Status <a id="fs.op.status">[[fs.op.status]]</a>
3873
+
3874
+ ``` cpp
3875
+ file_status status(const path& p);
3876
+ ```
3877
+
3878
+ *Effects:* As if:
3879
+
3880
+ ``` cpp
3881
+ error_code ec;
3882
+ file_status result = status(p, ec);
3883
+ if (result.type() == file_type::none)
3884
+ throw filesystem_error(implementation-supplied-message, p, ec);
3885
+ return result;
3886
+ ```
3887
+
3888
+ *Returns:* See above.
3889
+
3890
+ *Throws:* `filesystem_error`.
3891
+
3892
+ [*Note 1*: `result` values of `file_status(file_type::not_found)` and
3893
+ `file_status(file_type::unknown)` are not considered failures and do not
3894
+ cause an exception to be thrown. — *end note*]
3895
+
3896
+ ``` cpp
3897
+ file_status status(const path& p, error_code& ec) noexcept;
3898
+ ```
3899
+
3900
+ *Effects:* If possible, determines the attributes of the file `p`
3901
+ resolves to, as if by using POSIX `stat()` to obtain a POSIX
3902
+ `struct stat`. If, during attribute determination, the underlying file
3903
+ system API reports an error, sets `ec` to indicate the specific error
3904
+ reported. Otherwise, `ec.clear()`.
3905
+
3906
+ [*Note 2*: This allows users to inspect the specifics of underlying API
3907
+ errors even when the value returned by `status()` is not
3908
+ `file_status(file_type::none)`. — *end note*]
3909
+
3910
+ Let `prms` denote the result of `(m & perms::mask)`, where `m` is
3911
+ determined as if by converting the `st_mode` member of the obtained
3912
+ `struct stat` to the type `perms`.
3913
+
3914
+ *Returns:*
3915
+
3916
+ - If `ec != error_code()`:
3917
+ - If the specific error indicates that `p` cannot be resolved because
3918
+ some element of the path does not exist, returns
3919
+ `file_status(file_type::not_found)`.
3920
+ - Otherwise, if the specific error indicates that `p` can be resolved
3921
+ but the attributes cannot be determined, returns
3922
+ `file_status(file_type::unknown)`.
3923
+ - Otherwise, returns `file_status(file_type::none)`.
3924
+
3925
+ \[*Note 1*: These semantics distinguish between `p` being known not to
3926
+ exist, `p` existing but not being able to determine its attributes,
3927
+ and there being an error that prevents even knowing if `p` exists.
3928
+ These distinctions are important to some use cases. — *end note*]
3929
+ - Otherwise,
3930
+ - If the attributes indicate a regular file, as if by POSIX `S_ISREG`,
3931
+ returns `file_status(file_type::regular, prms)`.
3932
+ \[*Note 2*: `file_type::regular` implies appropriate `<fstream>`
3933
+ operations would succeed, assuming no hardware, permission, access,
3934
+ or file system race errors. Lack of `file_type::regular` does not
3935
+ necessarily imply `<fstream>` operations would fail on a
3936
+ directory. — *end note*]
3937
+ - Otherwise, if the attributes indicate a directory, as if by POSIX
3938
+ `S_ISDIR`, returns `file_status(file_type::directory, prms)`.
3939
+ \[*Note 3*: `file_type::directory` implies that calling
3940
+ `directory_iterator(p)` would succeed. — *end note*]
3941
+ - Otherwise, if the attributes indicate a block special file, as if by
3942
+ POSIX `S_ISBLK`, returns `file_status(file_type::block, prms)`.
3943
+ - Otherwise, if the attributes indicate a character special file, as
3944
+ if by POSIX `S_ISCHR`, returns
3945
+ `file_status(file_type::character, prms)`.
3946
+ - Otherwise, if the attributes indicate a fifo or pipe file, as if by
3947
+ POSIX `S_ISFIFO`, returns `file_status(file_type::fifo, prms)`.
3948
+ - Otherwise, if the attributes indicate a socket, as if by POSIX
3949
+ `S_ISSOCK`, returns `file_status(file_type::socket, prms)`.
3950
+ - Otherwise, if the attributes indicate an implementation-defined file
3951
+ type ([[fs.enum.file_type]]), returns
3952
+ `file_status(file_type::`*`A`*`, prms)`, where *A* is the constant
3953
+ for the *implementation-defined* file type.
3954
+ - Otherwise, returns `file_status(file_type::unknown, prms)`.
3955
+
3956
+ *Remarks:* If a symbolic link is encountered during pathname resolution,
3957
+ pathname resolution continues using the contents of the symbolic link.
3958
+
3959
+ #### Status known <a id="fs.op.status_known">[[fs.op.status_known]]</a>
3960
+
3961
+ ``` cpp
3962
+ bool status_known(file_status s) noexcept;
3963
+ ```
3964
+
3965
+ *Returns:* `s.type() != file_type::none`.
3966
+
3967
+ #### Symlink status <a id="fs.op.symlink_status">[[fs.op.symlink_status]]</a>
3968
+
3969
+ ``` cpp
3970
+ file_status symlink_status(const path& p);
3971
+ file_status symlink_status(const path& p, error_code& ec) noexcept;
3972
+ ```
3973
+
3974
+ *Effects:* Same as `status()`, above, except that the attributes of `p`
3975
+ are determined as if by using POSIX `lstat()` to obtain a POSIX
3976
+ `struct stat`.
3977
+
3978
+ Let `prms` denote the result of `(m & perms::mask)`, where `m` is
3979
+ determined as if by converting the `st_mode` member of the obtained
3980
+ `struct stat` to the type `perms`.
3981
+
3982
+ *Returns:* Same as `status()`, above, except that if the attributes
3983
+ indicate a symbolic link, as if by POSIX `S_ISLNK`, returns
3984
+ `file_status(file_type::symlink, prms)`. The signature with argument
3985
+ `ec` returns `file_status(file_type::none)` if an error occurs.
3986
+
3987
+ *Remarks:* Pathname resolution terminates if `p` names a symbolic link.
3988
+
3989
+ *Throws:* As specified in  [[fs.err.report]].
3990
+
3991
+ #### Temporary directory path <a id="fs.op.temp_dir_path">[[fs.op.temp_dir_path]]</a>
3992
+
3993
+ ``` cpp
3994
+ path temp_directory_path();
3995
+ path temp_directory_path(error_code& ec);
3996
+ ```
3997
+
3998
+ *Returns:* An unspecifed directory path suitable for temporary files. An
3999
+ error shall be reported if `!exists(p) || !is_directory(p)`, where `p`
4000
+ is the path to be returned. The signature with argument `ec` returns
4001
+ `path()` if an error occurs.
4002
+
4003
+ *Throws:* As specified in  [[fs.err.report]].
4004
+
4005
+ [*Example 1*: For POSIX-based operating systems, an implementation
4006
+ might return the path supplied by the first environment variable found
4007
+ in the list TMPDIR, TMP, TEMP, TEMPDIR, or if none of these are found,
4008
+ `"/tmp"`. For Windows-based operating systems, an implementation might
4009
+ return the path reported by the Windows `GetTempPath` API
4010
+ function. — *end example*]
4011
+
4012
+ #### Weakly canonical <a id="fs.op.weakly_canonical">[[fs.op.weakly_canonical]]</a>
4013
+
4014
+ ``` cpp
4015
+ path weakly_canonical(const path& p);
4016
+ path weakly_canonical(const path& p, error_code& ec);
4017
+ ```
4018
+
4019
+ *Returns:* `p` with symlinks resolved and the result
4020
+ normalized ([[fs.def.normal.form]]).
4021
+
4022
+ *Effects:* Using `status(p)` or `status(p, ec)`, respectively, to
4023
+ determine existence, return a path composed by `operator/=` from the
4024
+ result of calling `canonical()` without a `base` argument and with a
4025
+ path argument composed of the leading elements of `p` that exist, if
4026
+ any, followed by the elements of `p` that do not exist, if any. For the
4027
+ first form, `canonical()` is called without an `error_code` argument.
4028
+ For the second form, `canonical()` is called with `ec` as an
4029
+ `error_code` argument, and `path()` is returned at the first error
4030
+ occurrence, if any.
4031
+
4032
+ *Postconditions:* The returned path is in normal
4033
+ form ([[fs.def.normal.form]]).
4034
+
4035
+ *Remarks:* Implementations are encouraged to avoid unnecessary
4036
+ normalization such as when `canonical` has already been called on the
4037
+ entirety of `p`.
4038
+
4039
+ *Throws:* As specified in  [[fs.err.report]].
4040
+