From Jason Turner

[mem]

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

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp3ze7m322/{from.md → to.md} +5188 -0
tmp/tmp3ze7m322/{from.md → to.md} RENAMED
@@ -0,0 +1,5188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Memory management library <a id="mem">[[mem]]</a>
2
+
3
+ ## General <a id="mem.general">[[mem.general]]</a>
4
+
5
+ This Clause describes components for memory management.
6
+
7
+ The following subclauses describe general memory management facilities,
8
+ smart pointers, memory resources, and scoped allocators, as summarized
9
+ in [[mem.summary]].
10
+
11
+ **Table: Memory management library summary** <a id="mem.summary">[mem.summary]</a>
12
+
13
+ | Subclause | | Header |
14
+ | --------------------- | ----------------- | ----------------------- |
15
+ | [[memory]] | Memory | `<cstdlib>`, `<memory>` |
16
+ | [[smartptr]] | Smart pointers | `<memory>` |
17
+ | [[mem.res]] | Memory resources | `<memory_resource>` |
18
+ | [[allocator.adaptor]] | Scoped allocators | `<scoped_allocator>` |
19
+
20
+
21
+ ## Memory <a id="memory">[[memory]]</a>
22
+
23
+ ### In general <a id="memory.general">[[memory.general]]</a>
24
+
25
+ Subclause  [[memory]] describes the contents of the header `<memory>`
26
+ and some of the contents of the header `<cstdlib>`.
27
+
28
+ ### Header `<memory>` synopsis <a id="memory.syn">[[memory.syn]]</a>
29
+
30
+ The header `<memory>` defines several types and function templates that
31
+ describe properties of pointers and pointer-like types, manage memory
32
+ for containers and other template types, destroy objects, and construct
33
+ objects in uninitialized memory buffers ([[pointer.traits]]–
34
+ [[specialized.addressof]] and [[specialized.algorithms]]). The header
35
+ also defines the templates `unique_ptr`, `shared_ptr`, `weak_ptr`,
36
+ `out_ptr_t`, `inout_ptr_t`, and various function templates that operate
37
+ on objects of these types [[smartptr]].
38
+
39
+ Let `POINTER_OF(T)` denote a type that is
40
+
41
+ - `T::pointer` if the *qualified-id* `T::pointer` is valid and denotes a
42
+ type,
43
+ - otherwise, `T::element_type*` if the *qualified-id* `T::element_type`
44
+ is valid and denotes a type,
45
+ - otherwise, `pointer_traits<T>::element_type*`.
46
+
47
+ Let `POINTER_OF_OR(T, U)` denote a type that is:
48
+
49
+ - `POINTER_OF(T)` if `POINTER_OF(T)` is valid and denotes a type,
50
+ - otherwise, `U`.
51
+
52
+ ``` cpp
53
+ #include <compare> // see [compare.syn]
54
+
55
+ namespace std {
56
+ // [pointer.traits], pointer traits
57
+ template<class Ptr> struct pointer_traits; // freestanding
58
+ template<class T> struct pointer_traits<T*>; // freestanding
59
+
60
+ // [pointer.conversion], pointer conversion
61
+ template<class T>
62
+ constexpr T* to_address(T* p) noexcept; // freestanding
63
+ template<class Ptr>
64
+ constexpr auto to_address(const Ptr& p) noexcept; // freestanding
65
+
66
+ // [ptr.align], pointer alignment
67
+ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); // freestanding
68
+ template<size_t N, class T>
69
+ [[nodiscard]] constexpr T* assume_aligned(T* ptr); // freestanding
70
+
71
+ // [obj.lifetime], explicit lifetime management
72
+ template<class T>
73
+ T* start_lifetime_as(void* p) noexcept; // freestanding
74
+ template<class T>
75
+ const T* start_lifetime_as(const void* p) noexcept; // freestanding
76
+ template<class T>
77
+ volatile T* start_lifetime_as(volatile void* p) noexcept; // freestanding
78
+ template<class T>
79
+ const volatile T* start_lifetime_as(const volatile void* p) noexcept; // freestanding
80
+ template<class T>
81
+ T* start_lifetime_as_array(void* p, size_t n) noexcept; // freestanding
82
+ template<class T>
83
+ const T* start_lifetime_as_array(const void* p, size_t n) noexcept; // freestanding
84
+ template<class T>
85
+ volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept; // freestanding
86
+ template<class T>
87
+ const volatile T* start_lifetime_as_array(const volatile void* p, // freestanding
88
+ size_t n) noexcept;
89
+
90
+ // [allocator.tag], allocator argument tag
91
+ struct allocator_arg_t { // freestanding
92
+ explicit allocator_arg_t() = default; // freestanding
93
+ };
94
+ inline constexpr allocator_arg_t allocator_arg{}; // freestanding
95
+
96
+ // [allocator.uses], uses_allocator
97
+ template<class T, class Alloc> struct uses_allocator; // freestanding
98
+
99
+ // [allocator.uses.trait], uses_allocator
100
+ template<class T, class Alloc>
101
+ constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value; // freestanding
102
+
103
+ // [allocator.uses.construction], uses-allocator construction
104
+ template<class T, class Alloc, class... Args>
105
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
106
+ Args&&... args) noexcept;
107
+ template<class T, class Alloc, class Tuple1, class Tuple2>
108
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
109
+ piecewise_construct_t,
110
+ Tuple1&& x, Tuple2&& y) noexcept;
111
+ template<class T, class Alloc>
112
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept; // freestanding
113
+ template<class T, class Alloc, class U, class V>
114
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
115
+ U&& u, V&& v) noexcept;
116
+ template<class T, class Alloc, class U, class V>
117
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
118
+ pair<U, V>& pr) noexcept;
119
+ template<class T, class Alloc, class U, class V>
120
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
121
+ const pair<U, V>& pr) noexcept;
122
+ template<class T, class Alloc, class U, class V>
123
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
124
+ pair<U, V>&& pr) noexcept;
125
+ template<class T, class Alloc, class U, class V>
126
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
127
+ const pair<U, V>&& pr) noexcept;
128
+ template<class T, class Alloc, pair-like P>
129
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
130
+ P&& p) noexcept;
131
+ template<class T, class Alloc, class U>
132
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
133
+ U&& u) noexcept;
134
+ template<class T, class Alloc, class... Args>
135
+ constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args); // freestanding
136
+ template<class T, class Alloc, class... Args>
137
+ constexpr T* uninitialized_construct_using_allocator(T* p, // freestanding
138
+ const Alloc& alloc, Args&&... args);
139
+
140
+ // [allocator.traits], allocator traits
141
+ template<class Alloc> struct allocator_traits; // freestanding
142
+
143
+ template<class Pointer, class SizeType = size_t>
144
+ struct allocation_result { // freestanding
145
+ Pointer ptr;
146
+ SizeType count;
147
+ };
148
+
149
+ // [default.allocator], the default allocator
150
+ template<class T> class allocator;
151
+ template<class T, class U>
152
+ constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
153
+
154
+ // [specialized.addressof], addressof
155
+ template<class T>
156
+ constexpr T* addressof(T& r) noexcept; // freestanding
157
+ template<class T>
158
+ const T* addressof(const T&&) = delete; // freestanding
159
+
160
+ // [specialized.algorithms], specialized algorithms
161
+ // [special.mem.concepts], special memory concepts
162
+ template<class I>
163
+ concept nothrow-input-iterator = see below; // exposition only
164
+ template<class I>
165
+ concept nothrow-forward-iterator = see below; // exposition only
166
+ template<class S, class I>
167
+ concept nothrow-sentinel-for = see below; // exposition only
168
+ template<class R>
169
+ concept nothrow-input-range = see below; // exposition only
170
+ template<class R>
171
+ concept nothrow-forward-range = see below; // exposition only
172
+
173
+ template<class NoThrowForwardIterator>
174
+ void uninitialized_default_construct(NoThrowForwardIterator first, // freestanding
175
+ NoThrowForwardIterator last);
176
+ template<class ExecutionPolicy, class NoThrowForwardIterator>
177
+ void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
178
+ NoThrowForwardIterator first,
179
+ NoThrowForwardIterator last);
180
+ template<class NoThrowForwardIterator, class Size>
181
+ NoThrowForwardIterator
182
+ uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); // freestanding
183
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
184
+ NoThrowForwardIterator
185
+ uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
186
+ NoThrowForwardIterator first, Size n);
187
+
188
+ namespace ranges {
189
+ template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
190
+ requires default_initializable<iter_value_t<I>>
191
+ I uninitialized_default_construct(I first, S last); // freestanding
192
+ template<nothrow-forward-range R>
193
+ requires default_initializable<range_value_t<R>>
194
+ borrowed_iterator_t<R> uninitialized_default_construct(R&& r); // freestanding
195
+
196
+ template<nothrow-forward-iterator I>
197
+ requires default_initializable<iter_value_t<I>>
198
+ I uninitialized_default_construct_n(I first, iter_difference_t<I> n); // freestanding
199
+ }
200
+
201
+ template<class NoThrowForwardIterator>
202
+ void uninitialized_value_construct(NoThrowForwardIterator first, // freestanding
203
+ NoThrowForwardIterator last);
204
+ template<class ExecutionPolicy, class NoThrowForwardIterator>
205
+ void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
206
+ NoThrowForwardIterator first,
207
+ NoThrowForwardIterator last);
208
+ template<class NoThrowForwardIterator, class Size>
209
+ NoThrowForwardIterator
210
+ uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); // freestanding
211
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
212
+ NoThrowForwardIterator
213
+ uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
214
+ NoThrowForwardIterator first, Size n);
215
+
216
+ namespace ranges {
217
+ template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
218
+ requires default_initializable<iter_value_t<I>>
219
+ I uninitialized_value_construct(I first, S last); // freestanding
220
+ template<nothrow-forward-range R>
221
+ requires default_initializable<range_value_t<R>>
222
+ borrowed_iterator_t<R> uninitialized_value_construct(R&& r); // freestanding
223
+
224
+ template<nothrow-forward-iterator I>
225
+ requires default_initializable<iter_value_t<I>>
226
+ I uninitialized_value_construct_n(I first, iter_difference_t<I> n); // freestanding
227
+ }
228
+
229
+ template<class InputIterator, class NoThrowForwardIterator>
230
+ NoThrowForwardIterator uninitialized_copy(InputIterator first, // freestanding
231
+ InputIterator last,
232
+ NoThrowForwardIterator result);
233
+ template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
234
+ NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
235
+ ForwardIterator first, ForwardIterator last,
236
+ NoThrowForwardIterator result);
237
+ template<class InputIterator, class Size, class NoThrowForwardIterator>
238
+ NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, // freestanding
239
+ NoThrowForwardIterator result);
240
+ template<class ExecutionPolicy, class ForwardIterator, class Size,
241
+ class NoThrowForwardIterator>
242
+ NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
243
+ ForwardIterator first, Size n,
244
+ NoThrowForwardIterator result);
245
+
246
+ namespace ranges {
247
+ template<class I, class O>
248
+ using uninitialized_copy_result = in_out_result<I, O>; // freestanding
249
+ template<input_iterator I, sentinel_for<I> S1,
250
+ nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
251
+ requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
252
+ uninitialized_copy_result<I, O>
253
+ uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
254
+ template<input_range IR, nothrow-forward-range OR>
255
+ requires constructible_from<range_value_t<OR>, range_reference_t<IR>>
256
+ uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
257
+ uninitialized_copy(IR&& in_range, OR&& out_range); // freestanding
258
+
259
+ template<class I, class O>
260
+ using uninitialized_copy_n_result = in_out_result<I, O>; // freestanding
261
+ template<input_iterator I, nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
262
+ requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
263
+ uninitialized_copy_n_result<I, O>
264
+ uninitialized_copy_n(I ifirst, iter_difference_t<I> n, // freestanding
265
+ O ofirst, S olast);
266
+ }
267
+
268
+ template<class InputIterator, class NoThrowForwardIterator>
269
+ NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding
270
+ InputIterator last,
271
+ NoThrowForwardIterator result);
272
+ template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
273
+ NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
274
+ ForwardIterator first, ForwardIterator last,
275
+ NoThrowForwardIterator result);
276
+ template<class InputIterator, class Size, class NoThrowForwardIterator>
277
+ pair<InputIterator, NoThrowForwardIterator>
278
+ uninitialized_move_n(InputIterator first, Size n, // freestanding
279
+ NoThrowForwardIterator result);
280
+ template<class ExecutionPolicy, class ForwardIterator, class Size,
281
+ class NoThrowForwardIterator>
282
+ pair<ForwardIterator, NoThrowForwardIterator>
283
+ uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
284
+ ForwardIterator first, Size n, NoThrowForwardIterator result);
285
+
286
+ namespace ranges {
287
+ template<class I, class O>
288
+ using uninitialized_move_result = in_out_result<I, O>; // freestanding
289
+ template<input_iterator I, sentinel_for<I> S1,
290
+ nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
291
+ requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
292
+ uninitialized_move_result<I, O>
293
+ uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
294
+ template<input_range IR, nothrow-forward-range OR>
295
+ requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>>
296
+ uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
297
+ uninitialized_move(IR&& in_range, OR&& out_range); // freestanding
298
+
299
+ template<class I, class O>
300
+ using uninitialized_move_n_result = in_out_result<I, O>; // freestanding
301
+ template<input_iterator I,
302
+ nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
303
+ requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
304
+ uninitialized_move_n_result<I, O>
305
+ uninitialized_move_n(I ifirst, iter_difference_t<I> n, // freestanding
306
+ O ofirst, S olast);
307
+ }
308
+
309
+ template<class NoThrowForwardIterator, class T>
310
+ void uninitialized_fill(NoThrowForwardIterator first, // freestanding
311
+ NoThrowForwardIterator last, const T& x);
312
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class T>
313
+ void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
314
+ NoThrowForwardIterator first, NoThrowForwardIterator last,
315
+ const T& x);
316
+ template<class NoThrowForwardIterator, class Size, class T>
317
+ NoThrowForwardIterator
318
+ uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); // freestanding
319
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T>
320
+ NoThrowForwardIterator
321
+ uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
322
+ NoThrowForwardIterator first, Size n, const T& x);
323
+
324
+ namespace ranges {
325
+ template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S, class T>
326
+ requires constructible_from<iter_value_t<I>, const T&>
327
+ I uninitialized_fill(I first, S last, const T& x); // freestanding
328
+ template<nothrow-forward-range R, class T>
329
+ requires constructible_from<range_value_t<R>, const T&>
330
+ borrowed_iterator_t<R> uninitialized_fill(R&& r, const T& x); // freestanding
331
+
332
+ template<nothrow-forward-iterator I, class T>
333
+ requires constructible_from<iter_value_t<I>, const T&>
334
+ I uninitialized_fill_n(I first, iter_difference_t<I> n, const T& x); // freestanding
335
+ }
336
+
337
+ // [specialized.construct], construct_at
338
+ template<class T, class... Args>
339
+ constexpr T* construct_at(T* location, Args&&... args); // freestanding
340
+
341
+ namespace ranges {
342
+ template<class T, class... Args>
343
+ constexpr T* construct_at(T* location, Args&&... args); // freestanding
344
+ }
345
+
346
+ // [specialized.destroy], destroy
347
+ template<class T>
348
+ constexpr void destroy_at(T* location); // freestanding
349
+ template<class NoThrowForwardIterator>
350
+ constexpr void destroy(NoThrowForwardIterator first, // freestanding
351
+ NoThrowForwardIterator last);
352
+ template<class ExecutionPolicy, class NoThrowForwardIterator>
353
+ void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
354
+ NoThrowForwardIterator first, NoThrowForwardIterator last);
355
+ template<class NoThrowForwardIterator, class Size>
356
+ constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, // freestanding
357
+ Size n);
358
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
359
+ NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
360
+ NoThrowForwardIterator first, Size n);
361
+
362
+ namespace ranges {
363
+ template<destructible T>
364
+ constexpr void destroy_at(T* location) noexcept; // freestanding
365
+
366
+ template<nothrow-input-iterator I, nothrow-sentinel-for<I> S>
367
+ requires destructible<iter_value_t<I>>
368
+ constexpr I destroy(I first, S last) noexcept; // freestanding
369
+ template<nothrow-input-range R>
370
+ requires destructible<range_value_t<R>>
371
+ constexpr borrowed_iterator_t<R> destroy(R&& r) noexcept; // freestanding
372
+
373
+ template<nothrow-input-iterator I>
374
+ requires destructible<iter_value_t<I>>
375
+ constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept; // freestanding
376
+ }
377
+
378
+ // [unique.ptr], class template unique_ptr
379
+ template<class T> struct default_delete; // freestanding
380
+ template<class T> struct default_delete<T[]>; // freestanding
381
+ template<class T, class D = default_delete<T>> class unique_ptr; // freestanding
382
+ template<class T, class D> class unique_ptr<T[], D>; // freestanding
383
+
384
+ template<class T, class... Args>
385
+ constexpr unique_ptr<T> make_unique(Args&&... args); // T is not array
386
+ template<class T>
387
+ constexpr unique_ptr<T> make_unique(size_t n); // T is U[]
388
+ template<class T, class... Args>
389
+ unspecified make_unique(Args&&...) = delete; // T is U[N]
390
+
391
+ template<class T>
392
+ constexpr unique_ptr<T> make_unique_for_overwrite(); // T is not array
393
+ template<class T>
394
+ constexpr unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[]
395
+ template<class T, class... Args>
396
+ unspecified make_unique_for_overwrite(Args&&...) = delete; // T is U[N]
397
+
398
+ template<class T, class D>
399
+ constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; // freestanding
400
+
401
+ template<class T1, class D1, class T2, class D2>
402
+ constexpr bool operator==(const unique_ptr<T1, D1>& x, // freestanding
403
+ const unique_ptr<T2, D2>& y);
404
+ template<class T1, class D1, class T2, class D2>
405
+ bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
406
+ template<class T1, class D1, class T2, class D2>
407
+ bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
408
+ template<class T1, class D1, class T2, class D2>
409
+ bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
410
+ template<class T1, class D1, class T2, class D2>
411
+ bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
412
+ template<class T1, class D1, class T2, class D2>
413
+ requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
414
+ typename unique_ptr<T2, D2>::pointer>
415
+ compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
416
+ typename unique_ptr<T2, D2>::pointer>
417
+ operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
418
+
419
+ template<class T, class D>
420
+ constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; // freestanding
421
+ template<class T, class D>
422
+ constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t); // freestanding
423
+ template<class T, class D>
424
+ constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& y); // freestanding
425
+ template<class T, class D>
426
+ constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t); // freestanding
427
+ template<class T, class D>
428
+ constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& y); // freestanding
429
+ template<class T, class D>
430
+ constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t); // freestanding
431
+ template<class T, class D>
432
+ constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& y); // freestanding
433
+ template<class T, class D>
434
+ constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t); // freestanding
435
+ template<class T, class D>
436
+ constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& y); // freestanding
437
+ template<class T, class D>
438
+ requires three_way_comparable<typename unique_ptr<T, D>::pointer>
439
+ constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
440
+ operator<=>(const unique_ptr<T, D>& x, nullptr_t); // freestanding
441
+
442
+ template<class E, class T, class Y, class D>
443
+ basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const unique_ptr<Y, D>& p);
444
+
445
+ // [util.smartptr.weak.bad], class bad_weak_ptr
446
+ class bad_weak_ptr;
447
+
448
+ // [util.smartptr.shared], class template shared_ptr
449
+ template<class T> class shared_ptr;
450
+
451
+ // [util.smartptr.shared.create], shared_ptr creation
452
+ template<class T, class... Args>
453
+ shared_ptr<T> make_shared(Args&&... args); // T is not array
454
+ template<class T, class A, class... Args>
455
+ shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
456
+
457
+ template<class T>
458
+ shared_ptr<T> make_shared(size_t N); // T is U[]
459
+ template<class T, class A>
460
+ shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
461
+
462
+ template<class T>
463
+ shared_ptr<T> make_shared(); // T is U[N]
464
+ template<class T, class A>
465
+ shared_ptr<T> allocate_shared(const A& a); // T is U[N]
466
+
467
+ template<class T>
468
+ shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[]
469
+ template<class T, class A>
470
+ shared_ptr<T> allocate_shared(const A& a, size_t N,
471
+ const remove_extent_t<T>& u); // T is U[]
472
+
473
+ template<class T>
474
+ shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
475
+ template<class T, class A>
476
+ shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N]
477
+
478
+ template<class T>
479
+ shared_ptr<T> make_shared_for_overwrite(); // T is not U[]
480
+ template<class T, class A>
481
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[]
482
+
483
+ template<class T>
484
+ shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[]
485
+ template<class T, class A>
486
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[]
487
+
488
+ // [util.smartptr.shared.cmp], shared_ptr comparisons
489
+ template<class T, class U>
490
+ bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
491
+ template<class T, class U>
492
+ strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
493
+
494
+ template<class T>
495
+ bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
496
+ template<class T>
497
+ strong_ordering operator<=>(const shared_ptr<T>& x, nullptr_t) noexcept;
498
+
499
+ // [util.smartptr.shared.spec], shared_ptr specialized algorithms
500
+ template<class T>
501
+ void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
502
+
503
+ // [util.smartptr.shared.cast], shared_ptr casts
504
+ template<class T, class U>
505
+ shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
506
+ template<class T, class U>
507
+ shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
508
+ template<class T, class U>
509
+ shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
510
+ template<class T, class U>
511
+ shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
512
+ template<class T, class U>
513
+ shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
514
+ template<class T, class U>
515
+ shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
516
+ template<class T, class U>
517
+ shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
518
+ template<class T, class U>
519
+ shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
520
+
521
+ // [util.smartptr.getdeleter], shared_ptr get_deleter
522
+ template<class D, class T>
523
+ D* get_deleter(const shared_ptr<T>& p) noexcept;
524
+
525
+ // [util.smartptr.shared.io], shared_ptr I/O
526
+ template<class E, class T, class Y>
527
+ basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);
528
+
529
+ // [util.smartptr.weak], class template weak_ptr
530
+ template<class T> class weak_ptr;
531
+
532
+ // [util.smartptr.weak.spec], weak_ptr specialized algorithms
533
+ template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
534
+
535
+ // [util.smartptr.ownerless], class template owner_less
536
+ template<class T = void> struct owner_less;
537
+
538
+ // [util.smartptr.enab], class template enable_shared_from_this
539
+ template<class T> class enable_shared_from_this;
540
+
541
+ // [util.smartptr.hash], hash support
542
+ template<class T> struct hash; // freestanding
543
+ template<class T, class D> struct hash<unique_ptr<T, D>>; // freestanding
544
+ template<class T> struct hash<shared_ptr<T>>;
545
+
546
+ // [util.smartptr.atomic], atomic smart pointers
547
+ template<class T> struct atomic; // freestanding
548
+ template<class T> struct atomic<shared_ptr<T>>;
549
+ template<class T> struct atomic<weak_ptr<T>>;
550
+
551
+ // [out.ptr.t], class template out_ptr_t
552
+ template<class Smart, class Pointer, class... Args>
553
+ class out_ptr_t;
554
+
555
+ // [out.ptr], function template out_ptr
556
+ template<class Pointer = void, class Smart, class... Args>
557
+ auto out_ptr(Smart& s, Args&&... args);
558
+
559
+ // [inout.ptr.t], class template inout_ptr_t
560
+ template<class Smart, class Pointer, class... Args>
561
+ class inout_ptr_t;
562
+
563
+ // [inout.ptr], function template inout_ptr
564
+ template<class Pointer = void, class Smart, class... Args>
565
+ auto inout_ptr(Smart& s, Args&&... args);
566
+ }
567
+ ```
568
+
569
+ ### Pointer traits <a id="pointer.traits">[[pointer.traits]]</a>
570
+
571
+ #### General <a id="pointer.traits.general">[[pointer.traits.general]]</a>
572
+
573
+ The class template `pointer_traits` supplies a uniform interface to
574
+ certain attributes of pointer-like types.
575
+
576
+ ``` cpp
577
+ namespace std {
578
+ template<class Ptr> struct pointer_traits {
579
+ see below;
580
+ };
581
+
582
+ template<class T> struct pointer_traits<T*> {
583
+ using pointer = T*;
584
+ using element_type = T;
585
+ using difference_type = ptrdiff_t;
586
+
587
+ template<class U> using rebind = U*;
588
+
589
+ static constexpr pointer pointer_to(see below r) noexcept;
590
+ };
591
+ }
592
+ ```
593
+
594
+ #### Member types <a id="pointer.traits.types">[[pointer.traits.types]]</a>
595
+
596
+ The definitions in this subclause make use of the following
597
+ exposition-only class template and concept:
598
+
599
+ ``` cpp
600
+ template<class T>
601
+ struct ptr-traits-elem // exposition only
602
+ { };
603
+
604
+ template<class T> requires requires { typename T::element_type; }
605
+ struct ptr-traits-elem<T>
606
+ { using type = typename T::element_type; };
607
+
608
+ template<template<class...> class SomePointer, class T, class... Args>
609
+ requires (!requires { typename SomePointer<T, Args...>::element_type; })
610
+ struct ptr-traits-elem<SomePointer<T, Args...>>
611
+ { using type = T; };
612
+
613
+ template<class Ptr>
614
+ concept has-elem-type = // exposition only
615
+ requires { typename ptr-traits-elem<Ptr>::type; }
616
+ ```
617
+
618
+ If `Ptr` satisfies `has-elem-type`, a specialization
619
+ `pointer_traits<Ptr>` generated from the `pointer_traits` primary
620
+ template has the following members as well as those described in 
621
+ [[pointer.traits.functions]]; otherwise, such a specialization has no
622
+ members by any of those names.
623
+
624
+ ``` cpp
625
+ using pointer = see below;
626
+ ```
627
+
628
+ *Type:* `Ptr`.
629
+
630
+ ``` cpp
631
+ using element_type = see below;
632
+ ```
633
+
634
+ *Type:* `typename `*`ptr-traits-elem`*`<Ptr>::type`.
635
+
636
+ ``` cpp
637
+ using difference_type = see below;
638
+ ```
639
+
640
+ *Type:* `Ptr::difference_type` if the *qualified-id*
641
+ `Ptr::difference_type` is valid and denotes a type [[temp.deduct]];
642
+ otherwise, `ptrdiff_t`.
643
+
644
+ ``` cpp
645
+ template<class U> using rebind = see below;
646
+ ```
647
+
648
+ *Alias template:* `Ptr::rebind<U>` if the *qualified-id*
649
+ `Ptr::rebind<U>` is valid and denotes a type [[temp.deduct]]; otherwise,
650
+ `SomePointer<U, Args>` if `Ptr` is a class template instantiation of the
651
+ form `SomePointer<T, Args>`, where `Args` is zero or more type
652
+ arguments; otherwise, the instantiation of `rebind` is ill-formed.
653
+
654
+ #### Member functions <a id="pointer.traits.functions">[[pointer.traits.functions]]</a>
655
+
656
+ ``` cpp
657
+ static pointer pointer_traits::pointer_to(see below r);
658
+ static constexpr pointer pointer_traits<T*>::pointer_to(see below r) noexcept;
659
+ ```
660
+
661
+ *Mandates:* For the first member function, `Ptr::pointer_to(r)` is
662
+ well-formed.
663
+
664
+ *Preconditions:* For the first member function, `Ptr::pointer_to(r)`
665
+ returns a pointer to `r` through which indirection is valid.
666
+
667
+ *Returns:* The first member function returns `Ptr::pointer_to(r)`. The
668
+ second member function returns `addressof(r)`.
669
+
670
+ *Remarks:* If `element_type` is cv `void`, the type of `r` is
671
+ unspecified; otherwise, it is `element_type&`.
672
+
673
+ #### Optional members <a id="pointer.traits.optmem">[[pointer.traits.optmem]]</a>
674
+
675
+ Specializations of `pointer_traits` may define the member declared in
676
+ this subclause to customize the behavior of the standard library. A
677
+ specialization generated from the `pointer_traits` primary template has
678
+ no member by this name.
679
+
680
+ ``` cpp
681
+ static element_type* to_address(pointer p) noexcept;
682
+ ```
683
+
684
+ *Returns:* A pointer of type `element_type*` that references the same
685
+ location as the argument `p`.
686
+
687
+ [*Note 1*: This function is intended to be the inverse of `pointer_to`.
688
+ If defined, it customizes the behavior of the non-member function
689
+ `to_address` [[pointer.conversion]]. — *end note*]
690
+
691
+ ### Pointer conversion <a id="pointer.conversion">[[pointer.conversion]]</a>
692
+
693
+ ``` cpp
694
+ template<class T> constexpr T* to_address(T* p) noexcept;
695
+ ```
696
+
697
+ *Mandates:* `T` is not a function type.
698
+
699
+ *Returns:* `p`.
700
+
701
+ ``` cpp
702
+ template<class Ptr> constexpr auto to_address(const Ptr& p) noexcept;
703
+ ```
704
+
705
+ *Returns:* `pointer_traits<Ptr>::to_address(p)` if that expression is
706
+ well-formed (see [[pointer.traits.optmem]]), otherwise
707
+ `to_address(p.operator->())`.
708
+
709
+ ### Pointer alignment <a id="ptr.align">[[ptr.align]]</a>
710
+
711
+ ``` cpp
712
+ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
713
+ ```
714
+
715
+ *Preconditions:*
716
+
717
+ - `alignment` is a power of two
718
+ - `ptr` represents the address of contiguous storage of at least `space`
719
+ bytes
720
+
721
+ *Effects:* If it is possible to fit `size` bytes of storage aligned by
722
+ `alignment` into the buffer pointed to by `ptr` with length `space`, the
723
+ function updates `ptr` to represent the first possible address of such
724
+ storage and decreases `space` by the number of bytes used for alignment.
725
+ Otherwise, the function does nothing.
726
+
727
+ *Returns:* A null pointer if the requested aligned buffer would not fit
728
+ into the available space, otherwise the adjusted value of `ptr`.
729
+
730
+ [*Note 1*: The function updates its `ptr` and `space` arguments so that
731
+ it can be called repeatedly with possibly different `alignment` and
732
+ `size` arguments for the same buffer. — *end note*]
733
+
734
+ ``` cpp
735
+ template<size_t N, class T>
736
+ [[nodiscard]] constexpr T* assume_aligned(T* ptr);
737
+ ```
738
+
739
+ *Mandates:* `N` is a power of two.
740
+
741
+ *Preconditions:* `ptr` points to an object `X` of a type
742
+ similar [[conv.qual]] to `T`, where `X` has alignment `N`
743
+ [[basic.align]].
744
+
745
+ *Returns:* `ptr`.
746
+
747
+ *Throws:* Nothing.
748
+
749
+ [*Note 2*: The alignment assumption on an object `X` expressed by a
750
+ call to `assume_aligned` might result in generation of more efficient
751
+ code. It is up to the program to ensure that the assumption actually
752
+ holds. The call does not cause the implementation to verify or enforce
753
+ this. An implementation might only make the assumption for those
754
+ operations on `X` that access `X` through the pointer returned by
755
+ `assume_aligned`. — *end note*]
756
+
757
+ ### Explicit lifetime management <a id="obj.lifetime">[[obj.lifetime]]</a>
758
+
759
+ ``` cpp
760
+ template<class T>
761
+ T* start_lifetime_as(void* p) noexcept;
762
+ template<class T>
763
+ const T* start_lifetime_as(const void* p) noexcept;
764
+ template<class T>
765
+ volatile T* start_lifetime_as(volatile void* p) noexcept;
766
+ template<class T>
767
+ const volatile T* start_lifetime_as(const volatile void* p) noexcept;
768
+ ```
769
+
770
+ *Mandates:* `T` is an implicit-lifetime type [[basic.types.general]] and
771
+ not an incomplete type [[term.incomplete.type]].
772
+
773
+ *Preconditions:* \[`p`, `(char*)p + sizeof(T)`) denotes a region of
774
+ allocated storage that is a subset of the region of storage reachable
775
+ through [[basic.compound]] `p` and suitably aligned for the type `T`.
776
+
777
+ *Effects:* Implicitly creates objects [[intro.object]] within the
778
+ denoted region consisting of an object *a* of type `T` whose address is
779
+ `p`, and objects nested within *a*, as follows: The object
780
+ representation of *a* is the contents of the storage prior to the call
781
+ to `start_lifetime_as`. The value of each created object *o* of
782
+ trivially-copyable type `U` is determined in the same manner as for a
783
+ call to `bit_cast<U>(E)` [[bit.cast]], where `E` is an lvalue of type
784
+ `U` denoting *o*, except that the storage is not accessed. The value of
785
+ any other created object is unspecified.
786
+
787
+ [*Note 1*: The unspecified value can be indeterminate. — *end note*]
788
+
789
+ *Returns:* A pointer to the *a* defined in the *Effects* paragraph.
790
+
791
+ ``` cpp
792
+ template<class T>
793
+ T* start_lifetime_as_array(void* p, size_t n) noexcept;
794
+ template<class T>
795
+ const T* start_lifetime_as_array(const void* p, size_t n) noexcept;
796
+ template<class T>
797
+ volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept;
798
+ template<class T>
799
+ const volatile T* start_lifetime_as_array(const volatile void* p, size_t n) noexcept;
800
+ ```
801
+
802
+ *Mandates:* `T` is a complete type.
803
+
804
+ *Preconditions:* `p` is suitably aligned for an array of `T` or is null.
805
+ `n <= size_t(-1) / sizeof(T)` is `true`. If `n > 0` is `true`,
806
+ \[`(char*)p`, `(char*)p + (n * sizeof(T))`) denotes a region of
807
+ allocated storage that is a subset of the region of storage reachable
808
+ through [[basic.compound]] `p`.
809
+
810
+ *Effects:* If `n > 0` is `true`, equivalent to `start_lifetime_as<U>(p)`
811
+ where `U` is the type “array of `n` `T`”. Otherwise, there are no
812
+ effects.
813
+
814
+ *Returns:* A pointer to the first element of the created array, if any;
815
+ otherwise, a pointer that compares equal to `p` [[expr.eq]].
816
+
817
+ ### Allocator argument tag <a id="allocator.tag">[[allocator.tag]]</a>
818
+
819
+ ``` cpp
820
+ namespace std {
821
+ struct allocator_arg_t { explicit allocator_arg_t() = default; };
822
+ inline constexpr allocator_arg_t allocator_arg{};
823
+ }
824
+ ```
825
+
826
+ The `allocator_arg_t` struct is an empty class type used as a unique
827
+ type to disambiguate constructor and function overloading. Specifically,
828
+ several types (see `tuple`  [[tuple]]) have constructors with
829
+ `allocator_arg_t` as the first argument, immediately followed by an
830
+ argument of a type that meets the *Cpp17Allocator* requirements
831
+ [[allocator.requirements.general]].
832
+
833
+ ### `uses_allocator` <a id="allocator.uses">[[allocator.uses]]</a>
834
+
835
+ #### `uses_allocator` trait <a id="allocator.uses.trait">[[allocator.uses.trait]]</a>
836
+
837
+ ``` cpp
838
+ template<class T, class Alloc> struct uses_allocator;
839
+ ```
840
+
841
+ *Remarks:* Automatically detects whether `T` has a nested
842
+ `allocator_type` that is convertible from `Alloc`. Meets the
843
+ *Cpp17BinaryTypeTrait* requirements [[meta.rqmts]]. The implementation
844
+ shall provide a definition that is derived from `true_type` if the
845
+ *qualified-id* `T::allocator_type` is valid and denotes a
846
+ type [[temp.deduct]] and
847
+ `is_convertible_v<Alloc, T::allocator_type> != false`, otherwise it
848
+ shall be derived from `false_type`. A program may specialize this
849
+ template to derive from `true_type` for a program-defined type `T` that
850
+ does not have a nested `allocator_type` but nonetheless can be
851
+ constructed with an allocator where either:
852
+
853
+ - the first argument of a constructor has type `allocator_arg_t` and the
854
+ second argument has type `Alloc` or
855
+ - the last argument of a constructor has type `Alloc`.
856
+
857
+ #### Uses-allocator construction <a id="allocator.uses.construction">[[allocator.uses.construction]]</a>
858
+
859
+ *Uses-allocator construction* with allocator `alloc` and constructor
860
+ arguments `args...` refers to the construction of an object of type `T`
861
+ such that `alloc` is passed to the constructor of `T` if `T` uses an
862
+ allocator type compatible with `alloc`. When applied to the construction
863
+ of an object of type `T`, it is equivalent to initializing it with the
864
+ value of the expression `make_obj_using_allocator<T>(alloc, args...)`,
865
+ described below.
866
+
867
+ The following utility functions support three conventions for passing
868
+ `alloc` to a constructor:
869
+
870
+ - If `T` does not use an allocator compatible with `alloc`, then `alloc`
871
+ is ignored.
872
+ - Otherwise, if `T` has a constructor invocable as
873
+ `T(allocator_arg, alloc, args...)` (leading-allocator convention),
874
+ then uses-allocator construction chooses this constructor form.
875
+ - Otherwise, if `T` has a constructor invocable as `T(args..., alloc)`
876
+ (trailing-allocator convention), then uses-allocator construction
877
+ chooses this constructor form.
878
+
879
+ The `uses_allocator_construction_args` function template takes an
880
+ allocator and argument list and produces (as a tuple) a new argument
881
+ list matching one of the above conventions. Additionally, overloads are
882
+ provided that treat specializations of `pair` such that uses-allocator
883
+ construction is applied individually to the `first` and `second` data
884
+ members. The `make_obj_using_allocator` and
885
+ `uninitialized_construct_using_allocator` function templates apply the
886
+ modified constructor arguments to construct an object of type `T` as a
887
+ return value or in-place, respectively.
888
+
889
+ [*Note 1*: For `uses_allocator_construction_args` and
890
+ `make_obj_using_allocator`, type `T` is not deduced and must therefore
891
+ be specified explicitly by the caller. — *end note*]
892
+
893
+ ``` cpp
894
+ template<class T, class Alloc, class... Args>
895
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
896
+ Args&&... args) noexcept;
897
+ ```
898
+
899
+ *Constraints:* `remove_cv_t<T>` is not a specialization of `pair`.
900
+
901
+ *Returns:* A `tuple` value determined as follows:
902
+
903
+ - If `uses_allocator_v<remove_cv_t<T>, Alloc>` is `false` and
904
+ `is_constructible_v<T,Args...>` is `true`, return
905
+ `forward_as_tuple(std::forward<Args>(args)...)`.
906
+ - Otherwise, if `uses_allocator_v<remove_cv_t<T>, Alloc>` is `true` and
907
+ `is_constructible_v<T, allocator_arg_t, const Alloc&, Args...>` is
908
+ `true`, return
909
+ ``` cpp
910
+ tuple<allocator_arg_t, const Alloc&, Args&&...>(
911
+ allocator_arg, alloc, std::forward<Args>(args)...)
912
+ ```
913
+ - Otherwise, if `uses_allocator_v<remove_cv_t<T>, Alloc>` is `true` and
914
+ `is_constructible_v<T, Args..., const Alloc&>` is `true`, return
915
+ `forward_as_tuple(std::forward<Args>(args)..., alloc)`.
916
+ - Otherwise, the program is ill-formed.
917
+
918
+ [*Note 1*: This definition prevents a silent failure to pass the
919
+ allocator to a constructor of a type for which
920
+ `uses_allocator_v<T, Alloc>` is `true`. — *end note*]
921
+
922
+ ``` cpp
923
+ template<class T, class Alloc, class Tuple1, class Tuple2>
924
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
925
+ Tuple1&& x, Tuple2&& y) noexcept;
926
+ ```
927
+
928
+ Let `T1` be `T::first_type`. Let `T2` be `T::second_type`.
929
+
930
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
931
+
932
+ *Effects:* Equivalent to:
933
+
934
+ ``` cpp
935
+ return make_tuple(
936
+ piecewise_construct,
937
+ apply([&alloc](auto&&... args1) {
938
+ return uses_allocator_construction_args<T1>(
939
+ alloc, std::forward<decltype(args1)>(args1)...);
940
+ }, std::forward<Tuple1>(x)),
941
+ apply([&alloc](auto&&... args2) {
942
+ return uses_allocator_construction_args<T2>(
943
+ alloc, std::forward<decltype(args2)>(args2)...);
944
+ }, std::forward<Tuple2>(y)));
945
+ ```
946
+
947
+ ``` cpp
948
+ template<class T, class Alloc>
949
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept;
950
+ ```
951
+
952
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
953
+
954
+ *Effects:* Equivalent to:
955
+
956
+ ``` cpp
957
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
958
+ tuple<>{}, tuple<>{});
959
+ ```
960
+
961
+ ``` cpp
962
+ template<class T, class Alloc, class U, class V>
963
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
964
+ U&& u, V&& v) noexcept;
965
+ ```
966
+
967
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
968
+
969
+ *Effects:* Equivalent to:
970
+
971
+ ``` cpp
972
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
973
+ forward_as_tuple(std::forward<U>(u)),
974
+ forward_as_tuple(std::forward<V>(v)));
975
+ ```
976
+
977
+ ``` cpp
978
+ template<class T, class Alloc, class U, class V>
979
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
980
+ pair<U, V>& pr) noexcept;
981
+ template<class T, class Alloc, class U, class V>
982
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
983
+ const pair<U, V>& pr) noexcept;
984
+ ```
985
+
986
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
987
+
988
+ *Effects:* Equivalent to:
989
+
990
+ ``` cpp
991
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
992
+ forward_as_tuple(pr.first),
993
+ forward_as_tuple(pr.second));
994
+ ```
995
+
996
+ ``` cpp
997
+ template<class T, class Alloc, class U, class V>
998
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
999
+ pair<U, V>&& pr) noexcept;
1000
+ template<class T, class Alloc, class U, class V>
1001
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
1002
+ const pair<U, V>&& pr) noexcept;
1003
+ ```
1004
+
1005
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
1006
+
1007
+ *Effects:* Equivalent to:
1008
+
1009
+ ``` cpp
1010
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
1011
+ forward_as_tuple(get<0>(std::move(pr))),
1012
+ forward_as_tuple(get<1>(std::move(pr))));
1013
+ ```
1014
+
1015
+ ``` cpp
1016
+ template<class T, class Alloc, pair-like P>
1017
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;
1018
+ ```
1019
+
1020
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair` and
1021
+ `remove_cvref_t<P>` is not a specialization of `ranges::subrange`.
1022
+
1023
+ *Effects:* Equivalent to:
1024
+
1025
+ ``` cpp
1026
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
1027
+ forward_as_tuple(get<0>(std::forward<P>(p))),
1028
+ forward_as_tuple(get<1>(std::forward<P>(p))));
1029
+ ```
1030
+
1031
+ ``` cpp
1032
+ template<class T, class Alloc, class U>
1033
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;
1034
+ ```
1035
+
1036
+ Let *FUN* be the function template:
1037
+
1038
+ ``` cpp
1039
+ template<class A, class B>
1040
+ void FUN(const pair<A, B>&);
1041
+ ```
1042
+
1043
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`, and
1044
+ either:
1045
+
1046
+ - `remove_cvref_t<U>` is a specialization of `ranges::subrange`, or
1047
+ - `U` does not satisfy `pair-like` and the expression *`FUN`*`(u)` is
1048
+ not well-formed when considered as an unevaluated operand.
1049
+
1050
+ Let *pair-constructor* be an exposition-only class defined as follows:
1051
+
1052
+ ``` cpp
1053
+ class pair-constructor {
1054
+ using pair-type = remove_cv_t<T>; // exposition only
1055
+
1056
+ constexpr auto do-construct(const pair-type& p) const { // exposition only
1057
+ return make_obj_using_allocator<pair-type>(alloc_, p);
1058
+ }
1059
+ constexpr auto do-construct(pair-type&& p) const { // exposition only
1060
+ return make_obj_using_allocator<pair-type>(alloc_, std::move(p));
1061
+ }
1062
+
1063
+ const Alloc& alloc_; // exposition only
1064
+ U& u_; // exposition only
1065
+
1066
+ public:
1067
+ constexpr operator pair-type() const {
1068
+ return do-construct(std::forward<U>(u_));
1069
+ }
1070
+ };
1071
+ ```
1072
+
1073
+ *Returns:* `make_tuple(pc)`, where `pc` is a *pair-constructor* object
1074
+ whose *alloc\_* member is initialized with `alloc` and whose *u\_*
1075
+ member is initialized with `u`.
1076
+
1077
+ ``` cpp
1078
+ template<class T, class Alloc, class... Args>
1079
+ constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
1080
+ ```
1081
+
1082
+ *Effects:* Equivalent to:
1083
+
1084
+ ``` cpp
1085
+ return make_from_tuple<T>(uses_allocator_construction_args<T>(
1086
+ alloc, std::forward<Args>(args)...));
1087
+ ```
1088
+
1089
+ ``` cpp
1090
+ template<class T, class Alloc, class... Args>
1091
+ constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
1092
+ ```
1093
+
1094
+ *Effects:* Equivalent to:
1095
+
1096
+ ``` cpp
1097
+ return apply([&]<class... U>(U&&... xs) {
1098
+ return construct_at(p, std::forward<U>(xs)...);
1099
+ }, uses_allocator_construction_args<T>(alloc, std::forward<Args>(args)...));
1100
+ ```
1101
+
1102
+ ### Allocator traits <a id="allocator.traits">[[allocator.traits]]</a>
1103
+
1104
+ #### General <a id="allocator.traits.general">[[allocator.traits.general]]</a>
1105
+
1106
+ The class template `allocator_traits` supplies a uniform interface to
1107
+ all allocator types. An allocator cannot be a non-class type, however,
1108
+ even if `allocator_traits` supplies the entire required interface.
1109
+
1110
+ [*Note 1*: Thus, it is always possible to create a derived class from
1111
+ an allocator. — *end note*]
1112
+
1113
+ If a program declares an explicit or partial specialization of
1114
+ `allocator_traits`, the program is ill-formed, no diagnostic required.
1115
+
1116
+ ``` cpp
1117
+ namespace std {
1118
+ template<class Alloc> struct allocator_traits {
1119
+ using allocator_type = Alloc;
1120
+
1121
+ using value_type = typename Alloc::value_type;
1122
+
1123
+ using pointer = see below;
1124
+ using const_pointer = see below;
1125
+ using void_pointer = see below;
1126
+ using const_void_pointer = see below;
1127
+
1128
+ using difference_type = see below;
1129
+ using size_type = see below;
1130
+
1131
+ using propagate_on_container_copy_assignment = see below;
1132
+ using propagate_on_container_move_assignment = see below;
1133
+ using propagate_on_container_swap = see below;
1134
+ using is_always_equal = see below;
1135
+
1136
+ template<class T> using rebind_alloc = see below;
1137
+ template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
1138
+
1139
+ [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
1140
+ [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n,
1141
+ const_void_pointer hint);
1142
+ [[nodiscard]] static constexpr allocation_result<pointer, size_type>
1143
+ allocate_at_least(Alloc& a, size_type n);
1144
+
1145
+ static constexpr void deallocate(Alloc& a, pointer p, size_type n);
1146
+
1147
+ template<class T, class... Args>
1148
+ static constexpr void construct(Alloc& a, T* p, Args&&... args);
1149
+
1150
+ template<class T>
1151
+ static constexpr void destroy(Alloc& a, T* p);
1152
+
1153
+ static constexpr size_type max_size(const Alloc& a) noexcept;
1154
+
1155
+ static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs);
1156
+ };
1157
+ }
1158
+ ```
1159
+
1160
+ #### Member types <a id="allocator.traits.types">[[allocator.traits.types]]</a>
1161
+
1162
+ ``` cpp
1163
+ using pointer = see below;
1164
+ ```
1165
+
1166
+ *Type:* `Alloc::pointer` if the *qualified-id* `Alloc::pointer` is valid
1167
+ and denotes a type [[temp.deduct]]; otherwise, `value_type*`.
1168
+
1169
+ ``` cpp
1170
+ using const_pointer = see below;
1171
+ ```
1172
+
1173
+ *Type:* `Alloc::const_pointer` if the *qualified-id*
1174
+ `Alloc::const_pointer` is valid and denotes a type [[temp.deduct]];
1175
+ otherwise, `pointer_traits<pointer>::rebind<const value_type>`.
1176
+
1177
+ ``` cpp
1178
+ using void_pointer = see below;
1179
+ ```
1180
+
1181
+ *Type:* `Alloc::void_pointer` if the *qualified-id*
1182
+ `Alloc::void_pointer` is valid and denotes a type [[temp.deduct]];
1183
+ otherwise, `pointer_traits<pointer>::rebind<void>`.
1184
+
1185
+ ``` cpp
1186
+ using const_void_pointer = see below;
1187
+ ```
1188
+
1189
+ *Type:* `Alloc::const_void_pointer` if the *qualified-id*
1190
+ `Alloc::const_void_pointer` is valid and denotes a type [[temp.deduct]];
1191
+ otherwise, `pointer_traits<pointer>::rebind<const void>`.
1192
+
1193
+ ``` cpp
1194
+ using difference_type = see below;
1195
+ ```
1196
+
1197
+ *Type:* `Alloc::difference_type` if the *qualified-id*
1198
+ `Alloc::difference_type` is valid and denotes a type [[temp.deduct]];
1199
+ otherwise, `pointer_traits<pointer>::difference_type`.
1200
+
1201
+ ``` cpp
1202
+ using size_type = see below;
1203
+ ```
1204
+
1205
+ *Type:* `Alloc::size_type` if the *qualified-id* `Alloc::size_type` is
1206
+ valid and denotes a type [[temp.deduct]]; otherwise,
1207
+ `make_unsigned_t<difference_type>`.
1208
+
1209
+ ``` cpp
1210
+ using propagate_on_container_copy_assignment = see below;
1211
+ ```
1212
+
1213
+ *Type:* `Alloc::propagate_on_container_copy_assignment` if the
1214
+ *qualified-id* `Alloc::propagate_on_container_copy_assignment` is valid
1215
+ and denotes a type [[temp.deduct]]; otherwise `false_type`.
1216
+
1217
+ ``` cpp
1218
+ using propagate_on_container_move_assignment = see below;
1219
+ ```
1220
+
1221
+ *Type:* `Alloc::propagate_on_container_move_assignment` if the
1222
+ *qualified-id* `Alloc::propagate_on_container_move_assignment` is valid
1223
+ and denotes a type [[temp.deduct]]; otherwise `false_type`.
1224
+
1225
+ ``` cpp
1226
+ using propagate_on_container_swap = see below;
1227
+ ```
1228
+
1229
+ *Type:* `Alloc::propagate_on_container_swap` if the *qualified-id*
1230
+ `Alloc::propagate_on_container_swap` is valid and denotes a
1231
+ type [[temp.deduct]]; otherwise `false_type`.
1232
+
1233
+ ``` cpp
1234
+ using is_always_equal = see below;
1235
+ ```
1236
+
1237
+ *Type:* `Alloc::is_always_equal` if the *qualified-id*
1238
+ `Alloc::is_always_equal` is valid and denotes a type [[temp.deduct]];
1239
+ otherwise `is_empty<Alloc>::type`.
1240
+
1241
+ ``` cpp
1242
+ template<class T> using rebind_alloc = see below;
1243
+ ```
1244
+
1245
+ *Alias template:* `Alloc::rebind<T>::other` if the *qualified-id*
1246
+ `Alloc::rebind<T>::other` is valid and denotes a type [[temp.deduct]];
1247
+ otherwise, `Alloc<T, Args>` if `Alloc` is a class template instantiation
1248
+ of the form `Alloc<U, Args>`, where `Args` is zero or more type
1249
+ arguments; otherwise, the instantiation of `rebind_alloc` is ill-formed.
1250
+
1251
+ #### Static member functions <a id="allocator.traits.members">[[allocator.traits.members]]</a>
1252
+
1253
+ ``` cpp
1254
+ [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
1255
+ ```
1256
+
1257
+ *Returns:* `a.allocate(n)`.
1258
+
1259
+ ``` cpp
1260
+ [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
1261
+ ```
1262
+
1263
+ *Returns:* `a.allocate(n, hint)` if that expression is well-formed;
1264
+ otherwise, `a.allocate(n)`.
1265
+
1266
+ ``` cpp
1267
+ [[nodiscard]] static constexpr allocation_result<pointer, size_type>
1268
+ allocate_at_least(Alloc& a, size_type n);
1269
+ ```
1270
+
1271
+ *Returns:* `a.allocate_at_least(n)` if that expression is well-formed;
1272
+ otherwise, `{a.allocate(n), n}`.
1273
+
1274
+ ``` cpp
1275
+ static constexpr void deallocate(Alloc& a, pointer p, size_type n);
1276
+ ```
1277
+
1278
+ *Effects:* Calls `a.deallocate(p, n)`.
1279
+
1280
+ *Throws:* Nothing.
1281
+
1282
+ ``` cpp
1283
+ template<class T, class... Args>
1284
+ static constexpr void construct(Alloc& a, T* p, Args&&... args);
1285
+ ```
1286
+
1287
+ *Effects:* Calls `a.construct(p, std::forward<Args>(args)...)` if that
1288
+ call is well-formed; otherwise, invokes
1289
+ `construct_at(p, std::forward<Args>(args)...)`.
1290
+
1291
+ ``` cpp
1292
+ template<class T>
1293
+ static constexpr void destroy(Alloc& a, T* p);
1294
+ ```
1295
+
1296
+ *Effects:* Calls `a.destroy(p)` if that call is well-formed; otherwise,
1297
+ invokes `destroy_at(p)`.
1298
+
1299
+ ``` cpp
1300
+ static constexpr size_type max_size(const Alloc& a) noexcept;
1301
+ ```
1302
+
1303
+ *Returns:* `a.max_size()` if that expression is well-formed; otherwise,
1304
+ `numeric_limits<size_type>::max()/sizeof(value_type)`.
1305
+
1306
+ ``` cpp
1307
+ static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs);
1308
+ ```
1309
+
1310
+ *Returns:* `rhs.select_on_container_copy_construction()` if that
1311
+ expression is well-formed; otherwise, `rhs`.
1312
+
1313
+ #### Other <a id="allocator.traits.other">[[allocator.traits.other]]</a>
1314
+
1315
+ The class template `allocation_result` has the template parameters, data
1316
+ members, and special members specified above. It has no base classes or
1317
+ members other than those specified.
1318
+
1319
+ ### The default allocator <a id="default.allocator">[[default.allocator]]</a>
1320
+
1321
+ #### General <a id="default.allocator.general">[[default.allocator.general]]</a>
1322
+
1323
+ All specializations of the default allocator meet the allocator
1324
+ completeness requirements [[allocator.requirements.completeness]].
1325
+
1326
+ ``` cpp
1327
+ namespace std {
1328
+ template<class T> class allocator {
1329
+ public:
1330
+ using value_type = T;
1331
+ using size_type = size_t;
1332
+ using difference_type = ptrdiff_t;
1333
+ using propagate_on_container_move_assignment = true_type;
1334
+
1335
+ constexpr allocator() noexcept;
1336
+ constexpr allocator(const allocator&) noexcept;
1337
+ template<class U> constexpr allocator(const allocator<U>&) noexcept;
1338
+ constexpr ~allocator();
1339
+ constexpr allocator& operator=(const allocator&) = default;
1340
+
1341
+ [[nodiscard]] constexpr T* allocate(size_t n);
1342
+ [[nodiscard]] constexpr allocation_result<T*> allocate_at_least(size_t n);
1343
+ constexpr void deallocate(T* p, size_t n);
1344
+ };
1345
+ }
1346
+ ```
1347
+
1348
+ `allocator_traits<allocator<T>>::is_always_equal::value`
1349
+
1350
+ is `true` for any `T`.
1351
+
1352
+ #### Members <a id="allocator.members">[[allocator.members]]</a>
1353
+
1354
+ Except for the destructor, member functions of the default allocator
1355
+ shall not introduce data races [[intro.multithread]] as a result of
1356
+ concurrent calls to those member functions from different threads. Calls
1357
+ to these functions that allocate or deallocate a particular unit of
1358
+ storage shall occur in a single total order, and each such deallocation
1359
+ call shall happen before the next allocation (if any) in this order.
1360
+
1361
+ ``` cpp
1362
+ [[nodiscard]] constexpr T* allocate(size_t n);
1363
+ ```
1364
+
1365
+ *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1366
+
1367
+ *Returns:* A pointer to the initial element of an array of `n` `T`.
1368
+
1369
+ *Throws:* `bad_array_new_length` if
1370
+ `numeric_limits<size_t>::max() / sizeof(T) < n`, or `bad_alloc` if the
1371
+ storage cannot be obtained.
1372
+
1373
+ *Remarks:* The storage for the array is obtained by calling
1374
+ `::operator new` [[new.delete]], but it is unspecified when or how often
1375
+ this function is called. This function starts the lifetime of the array
1376
+ object, but not that of any of the array elements.
1377
+
1378
+ ``` cpp
1379
+ [[nodiscard]] constexpr allocation_result<T*> allocate_at_least(size_t n);
1380
+ ```
1381
+
1382
+ *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1383
+
1384
+ *Returns:* `allocation_result<T*>{ptr, count}`, where `ptr` is a pointer
1385
+ to the initial element of an array of `count` `T` and `count` ≥ `n`.
1386
+
1387
+ *Throws:* `bad_array_new_length` if
1388
+ `numeric_limits<size_t>::max() / sizeof(T)` < `n`, or `bad_alloc` if the
1389
+ storage cannot be obtained.
1390
+
1391
+ *Remarks:* The storage for the array is obtained by calling
1392
+ `::operator new`, but it is unspecified when or how often this function
1393
+ is called. This function starts the lifetime of the array object, but
1394
+ not that of any of the array elements.
1395
+
1396
+ ``` cpp
1397
+ constexpr void deallocate(T* p, size_t n);
1398
+ ```
1399
+
1400
+ *Preconditions:*
1401
+
1402
+ - If `p` is memory that was obtained by a call to `allocate_at_least`,
1403
+ let `ret` be the value returned and `req` be the value passed as the
1404
+ first argument to that call. `p` is equal to `ret.ptr` and `n` is a
1405
+ value such that `req` ≤ `n` ≤ `ret.count`.
1406
+ - Otherwise, `p` is a pointer value obtained from `allocate`. `n` equals
1407
+ the value passed as the first argument to the invocation of `allocate`
1408
+ which returned `p`.
1409
+
1410
+ *Effects:* Deallocates the storage referenced by `p`.
1411
+
1412
+ *Remarks:* Uses `::operator delete` [[new.delete]], but it is
1413
+ unspecified when this function is called.
1414
+
1415
+ #### Operators <a id="allocator.globals">[[allocator.globals]]</a>
1416
+
1417
+ ``` cpp
1418
+ template<class T, class U>
1419
+ constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
1420
+ ```
1421
+
1422
+ *Returns:* `true`.
1423
+
1424
+ ### `addressof` <a id="specialized.addressof">[[specialized.addressof]]</a>
1425
+
1426
+ ``` cpp
1427
+ template<class T> constexpr T* addressof(T& r) noexcept;
1428
+ ```
1429
+
1430
+ *Returns:* The actual address of the object or function referenced by
1431
+ `r`, even in the presence of an overloaded `operator&`.
1432
+
1433
+ *Remarks:* An expression `addressof(E)` is a constant
1434
+ subexpression [[defns.const.subexpr]] if `E` is an lvalue constant
1435
+ subexpression.
1436
+
1437
+ ### C library memory allocation <a id="c.malloc">[[c.malloc]]</a>
1438
+
1439
+ [*Note 1*: The header `<cstdlib>` declares the functions described in
1440
+ this subclause. — *end note*]
1441
+
1442
+ ``` cpp
1443
+ void* aligned_alloc(size_t alignment, size_t size);
1444
+ void* calloc(size_t nmemb, size_t size);
1445
+ void* malloc(size_t size);
1446
+ void* realloc(void* ptr, size_t size);
1447
+ ```
1448
+
1449
+ *Effects:* These functions have the semantics specified in the C
1450
+ standard library.
1451
+
1452
+ *Remarks:* These functions do not attempt to allocate storage by calling
1453
+ `::operator new()` [[new.delete]].
1454
+
1455
+ These functions implicitly create objects [[intro.object]] in the
1456
+ returned region of storage and return a pointer to a suitable created
1457
+ object. In the case of `calloc` and `realloc`, the objects are created
1458
+ before the storage is zeroed or copied, respectively.
1459
+
1460
+ ``` cpp
1461
+ void free(void* ptr);
1462
+ ```
1463
+
1464
+ *Effects:* This function has the semantics specified in the C standard
1465
+ library.
1466
+
1467
+ *Remarks:* This function does not attempt to deallocate storage by
1468
+ calling `::operator delete()`.
1469
+
1470
+ See also: ISO C 7.22.3
1471
+
1472
+ ## Smart pointers <a id="smartptr">[[smartptr]]</a>
1473
+
1474
+ ### Unique-ownership pointers <a id="unique.ptr">[[unique.ptr]]</a>
1475
+
1476
+ #### General <a id="unique.ptr.general">[[unique.ptr.general]]</a>
1477
+
1478
+ A *unique pointer* is an object that owns another object and manages
1479
+ that other object through a pointer. More precisely, a unique pointer is
1480
+ an object *u* that stores a pointer to a second object *p* and will
1481
+ dispose of *p* when *u* is itself destroyed (e.g., when leaving block
1482
+ scope [[stmt.dcl]]). In this context, *u* is said to *own* `p`.
1483
+
1484
+ The mechanism by which *u* disposes of *p* is known as *p*’s associated
1485
+ *deleter*, a function object whose correct invocation results in *p*’s
1486
+ appropriate disposition (typically its deletion).
1487
+
1488
+ Let the notation *u.p* denote the pointer stored by *u*, and let *u.d*
1489
+ denote the associated deleter. Upon request, *u* can *reset* (replace)
1490
+ *u.p* and *u.d* with another pointer and deleter, but properly disposes
1491
+ of its owned object via the associated deleter before such replacement
1492
+ is considered completed.
1493
+
1494
+ Each object of a type `U` instantiated from the `unique_ptr` template
1495
+ specified in [[unique.ptr]] has the strict ownership semantics,
1496
+ specified above, of a unique pointer. In partial satisfaction of these
1497
+ semantics, each such `U` is *Cpp17MoveConstructible* and
1498
+ *Cpp17MoveAssignable*, but is not *Cpp17CopyConstructible* nor
1499
+ *Cpp17CopyAssignable*. The template parameter `T` of `unique_ptr` may be
1500
+ an incomplete type.
1501
+
1502
+ [*Note 1*: The uses of `unique_ptr` include providing exception safety
1503
+ for dynamically allocated memory, passing ownership of dynamically
1504
+ allocated memory to a function, and returning dynamically allocated
1505
+ memory from a function. — *end note*]
1506
+
1507
+ #### Default deleters <a id="unique.ptr.dltr">[[unique.ptr.dltr]]</a>
1508
+
1509
+ ##### In general <a id="unique.ptr.dltr.general">[[unique.ptr.dltr.general]]</a>
1510
+
1511
+ The class template `default_delete` serves as the default deleter
1512
+ (destruction policy) for the class template `unique_ptr`.
1513
+
1514
+ The template parameter `T` of `default_delete` may be an incomplete
1515
+ type.
1516
+
1517
+ ##### `default_delete` <a id="unique.ptr.dltr.dflt">[[unique.ptr.dltr.dflt]]</a>
1518
+
1519
+ ``` cpp
1520
+ namespace std {
1521
+ template<class T> struct default_delete {
1522
+ constexpr default_delete() noexcept = default;
1523
+ template<class U> constexpr default_delete(const default_delete<U>&) noexcept;
1524
+ constexpr void operator()(T*) const;
1525
+ };
1526
+ }
1527
+ ```
1528
+
1529
+ ``` cpp
1530
+ template<class U> constexpr default_delete(const default_delete<U>& other) noexcept;
1531
+ ```
1532
+
1533
+ *Constraints:* `U*` is implicitly convertible to `T*`.
1534
+
1535
+ *Effects:* Constructs a `default_delete` object from another
1536
+ `default_delete<U>` object.
1537
+
1538
+ ``` cpp
1539
+ constexpr void operator()(T* ptr) const;
1540
+ ```
1541
+
1542
+ *Mandates:* `T` is a complete type.
1543
+
1544
+ *Effects:* Calls `delete` on `ptr`.
1545
+
1546
+ ##### `default_delete<T[]>` <a id="unique.ptr.dltr.dflt1">[[unique.ptr.dltr.dflt1]]</a>
1547
+
1548
+ ``` cpp
1549
+ namespace std {
1550
+ template<class T> struct default_delete<T[]> {
1551
+ constexpr default_delete() noexcept = default;
1552
+ template<class U> constexpr default_delete(const default_delete<U[]>&) noexcept;
1553
+ template<class U> constexpr void operator()(U* ptr) const;
1554
+ };
1555
+ }
1556
+ ```
1557
+
1558
+ ``` cpp
1559
+ template<class U> constexpr default_delete(const default_delete<U[]>& other) noexcept;
1560
+ ```
1561
+
1562
+ *Constraints:* `U(*)[]` is convertible to `T(*)[]`.
1563
+
1564
+ *Effects:* Constructs a `default_delete` object from another
1565
+ `default_delete<U[]>` object.
1566
+
1567
+ ``` cpp
1568
+ template<class U> constexpr void operator()(U* ptr) const;
1569
+ ```
1570
+
1571
+ *Constraints:* `U(*)[]` is convertible to `T(*)[]`.
1572
+
1573
+ *Mandates:* `U` is a complete type.
1574
+
1575
+ *Effects:* Calls `delete[]` on `ptr`.
1576
+
1577
+ #### `unique_ptr` for single objects <a id="unique.ptr.single">[[unique.ptr.single]]</a>
1578
+
1579
+ ##### General <a id="unique.ptr.single.general">[[unique.ptr.single.general]]</a>
1580
+
1581
+ ``` cpp
1582
+ namespace std {
1583
+ template<class T, class D = default_delete<T>> class unique_ptr {
1584
+ public:
1585
+ using pointer = see below;
1586
+ using element_type = T;
1587
+ using deleter_type = D;
1588
+
1589
+ // [unique.ptr.single.ctor], constructors
1590
+ constexpr unique_ptr() noexcept;
1591
+ constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept;
1592
+ constexpr unique_ptr(type_identity_t<pointer> p, see below d1) noexcept;
1593
+ constexpr unique_ptr(type_identity_t<pointer> p, see below d2) noexcept;
1594
+ constexpr unique_ptr(unique_ptr&& u) noexcept;
1595
+ constexpr unique_ptr(nullptr_t) noexcept;
1596
+ template<class U, class E>
1597
+ constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
1598
+
1599
+ // [unique.ptr.single.dtor], destructor
1600
+ constexpr ~unique_ptr();
1601
+
1602
+ // [unique.ptr.single.asgn], assignment
1603
+ constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;
1604
+ template<class U, class E>
1605
+ constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
1606
+ constexpr unique_ptr& operator=(nullptr_t) noexcept;
1607
+
1608
+ // [unique.ptr.single.observers], observers
1609
+ constexpr add_lvalue_reference_t<T> operator*() const noexcept(see below);
1610
+ constexpr pointer operator->() const noexcept;
1611
+ constexpr pointer get() const noexcept;
1612
+ constexpr deleter_type& get_deleter() noexcept;
1613
+ constexpr const deleter_type& get_deleter() const noexcept;
1614
+ constexpr explicit operator bool() const noexcept;
1615
+
1616
+ // [unique.ptr.single.modifiers], modifiers
1617
+ constexpr pointer release() noexcept;
1618
+ constexpr void reset(pointer p = pointer()) noexcept;
1619
+ constexpr void swap(unique_ptr& u) noexcept;
1620
+
1621
+ // disable copy from lvalue
1622
+ unique_ptr(const unique_ptr&) = delete;
1623
+ unique_ptr& operator=(const unique_ptr&) = delete;
1624
+ };
1625
+ }
1626
+ ```
1627
+
1628
+ The default type for the template parameter `D` is `default_delete`. A
1629
+ client-supplied template argument `D` shall be a function object type
1630
+ [[function.objects]], lvalue reference to function, or lvalue reference
1631
+ to function object type for which, given a value `d` of type `D` and a
1632
+ value `ptr` of type `unique_ptr<T, D>::pointer`, the expression `d(ptr)`
1633
+ is valid and has the effect of disposing of the pointer as appropriate
1634
+ for that deleter.
1635
+
1636
+ If the deleter’s type `D` is not a reference type, `D` shall meet the
1637
+ *Cpp17Destructible* requirements ([[cpp17.destructible]]).
1638
+
1639
+ If the *qualified-id* `remove_reference_t<D>::pointer` is valid and
1640
+ denotes a type [[temp.deduct]], then `unique_ptr<T,
1641
+ D>::pointer` shall be a synonym for `remove_reference_t<D>::pointer`.
1642
+ Otherwise `unique_ptr<T, D>::pointer` shall be a synonym for
1643
+ `element_type*`. The type `unique_ptr<T,
1644
+ D>::pointer` shall meet the *Cpp17NullablePointer* requirements (
1645
+ [[cpp17.nullablepointer]]).
1646
+
1647
+ [*Example 1*: Given an allocator type `X`
1648
+ [[allocator.requirements.general]] and letting `A` be a synonym for
1649
+ `allocator_traits<X>`, the types `A::pointer`, `A::const_pointer`,
1650
+ `A::void_pointer`, and `A::const_void_pointer` may be used as
1651
+ `unique_ptr<T, D>::pointer`. — *end example*]
1652
+
1653
+ ##### Constructors <a id="unique.ptr.single.ctor">[[unique.ptr.single.ctor]]</a>
1654
+
1655
+ ``` cpp
1656
+ constexpr unique_ptr() noexcept;
1657
+ constexpr unique_ptr(nullptr_t) noexcept;
1658
+ ```
1659
+
1660
+ *Constraints:* `is_pointer_v<deleter_type>` is `false` and
1661
+ `is_default_constructible_v<deleter_type>` is `true`.
1662
+
1663
+ *Preconditions:* `D` meets the *Cpp17DefaultConstructible* requirements
1664
+ ([[cpp17.defaultconstructible]]), and that construction does not throw
1665
+ an exception.
1666
+
1667
+ *Effects:* Constructs a `unique_ptr` object that owns nothing,
1668
+ value-initializing the stored pointer and the stored deleter.
1669
+
1670
+ *Ensures:* `get() == nullptr`. `get_deleter()` returns a reference to
1671
+ the stored deleter.
1672
+
1673
+ ``` cpp
1674
+ constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept;
1675
+ ```
1676
+
1677
+ *Constraints:* `is_pointer_v<deleter_type>` is `false` and
1678
+ `is_default_constructible_v<deleter_type>` is `true`.
1679
+
1680
+ *Preconditions:* `D` meets the *Cpp17DefaultConstructible* requirements
1681
+ ([[cpp17.defaultconstructible]]), and that construction does not throw
1682
+ an exception.
1683
+
1684
+ *Effects:* Constructs a `unique_ptr` which owns `p`, initializing the
1685
+ stored pointer with `p` and value-initializing the stored deleter.
1686
+
1687
+ *Ensures:* `get() == p`. `get_deleter()` returns a reference to the
1688
+ stored deleter.
1689
+
1690
+ ``` cpp
1691
+ constexpr unique_ptr(type_identity_t<pointer> p, const D& d) noexcept;
1692
+ constexpr unique_ptr(type_identity_t<pointer> p, remove_reference_t<D>&& d) noexcept;
1693
+ ```
1694
+
1695
+ *Constraints:* `is_constructible_v<D, decltype(d)>` is `true`.
1696
+
1697
+ *Preconditions:* For the first constructor, if `D` is not a reference
1698
+ type, `D` meets the *Cpp17CopyConstructible* requirements and such
1699
+ construction does not exit via an exception. For the second constructor,
1700
+ if `D` is not a reference type, `D` meets the *Cpp17MoveConstructible*
1701
+ requirements and such construction does not exit via an exception.
1702
+
1703
+ *Effects:* Constructs a `unique_ptr` object which owns `p`, initializing
1704
+ the stored pointer with `p` and initializing the deleter from
1705
+ `std::forward<decltype(d)>(d)`.
1706
+
1707
+ *Ensures:* `get() == p`. `get_deleter()` returns a reference to the
1708
+ stored deleter. If `D` is a reference type then `get_deleter()` returns
1709
+ a reference to the lvalue `d`.
1710
+
1711
+ *Remarks:* If `D` is a reference type, the second constructor is defined
1712
+ as deleted.
1713
+
1714
+ [*Example 1*:
1715
+
1716
+ ``` cpp
1717
+ D d;
1718
+ unique_ptr<int, D> p1(new int, D()); // D must be Cpp17MoveConstructible
1719
+ unique_ptr<int, D> p2(new int, d); // D must be Cpp17CopyConstructible
1720
+ unique_ptr<int, D&> p3(new int, d); // p3 holds a reference to d
1721
+ unique_ptr<int, const D&> p4(new int, D()); // error: rvalue deleter object combined
1722
+ // with reference deleter type
1723
+ ```
1724
+
1725
+ — *end example*]
1726
+
1727
+ ``` cpp
1728
+ constexpr unique_ptr(unique_ptr&& u) noexcept;
1729
+ ```
1730
+
1731
+ *Constraints:* `is_move_constructible_v<D>` is `true`.
1732
+
1733
+ *Preconditions:* If `D` is not a reference type, `D` meets the
1734
+ *Cpp17MoveConstructible* requirements ([[cpp17.moveconstructible]]).
1735
+ Construction of the deleter from an rvalue of type `D` does not throw an
1736
+ exception.
1737
+
1738
+ *Effects:* Constructs a `unique_ptr` from `u`. If `D` is a reference
1739
+ type, this deleter is copy constructed from `u`’s deleter; otherwise,
1740
+ this deleter is move constructed from `u`’s deleter.
1741
+
1742
+ [*Note 1*: The construction of the deleter can be implemented with
1743
+ `std::forward<D>`. — *end note*]
1744
+
1745
+ *Ensures:* `get()` yields the value `u.get()` yielded before the
1746
+ construction. `u.get() == nullptr`. `get_deleter()` returns a reference
1747
+ to the stored deleter that was constructed from `u.get_deleter()`. If
1748
+ `D` is a reference type then `get_deleter()` and `u.get_deleter()` both
1749
+ reference the same lvalue deleter.
1750
+
1751
+ ``` cpp
1752
+ template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
1753
+ ```
1754
+
1755
+ *Constraints:*
1756
+
1757
+ - `unique_ptr<U, E>::pointer` is implicitly convertible to `pointer`,
1758
+ - `U` is not an array type, and
1759
+ - either `D` is a reference type and `E` is the same type as `D`, or `D`
1760
+ is not a reference type and `E` is implicitly convertible to `D`.
1761
+
1762
+ *Preconditions:* If `E` is not a reference type, construction of the
1763
+ deleter from an rvalue of type `E` is well-formed and does not throw an
1764
+ exception. Otherwise, `E` is a reference type and construction of the
1765
+ deleter from an lvalue of type `E` is well-formed and does not throw an
1766
+ exception.
1767
+
1768
+ *Effects:* Constructs a `unique_ptr` from `u`. If `E` is a reference
1769
+ type, this deleter is copy constructed from `u`’s deleter; otherwise,
1770
+ this deleter is move constructed from `u`’s deleter.
1771
+
1772
+ [*Note 2*: The deleter constructor can be implemented with
1773
+ `std::forward<E>`. — *end note*]
1774
+
1775
+ *Ensures:* `get()` yields the value `u.get()` yielded before the
1776
+ construction. `u.get() == nullptr`. `get_deleter()` returns a reference
1777
+ to the stored deleter that was constructed from `u.get_deleter()`.
1778
+
1779
+ ##### Destructor <a id="unique.ptr.single.dtor">[[unique.ptr.single.dtor]]</a>
1780
+
1781
+ ``` cpp
1782
+ constexpr ~unique_ptr();
1783
+ ```
1784
+
1785
+ *Effects:* Equivalent to: `if (get()) get_deleter()(get());`
1786
+
1787
+ [*Note 3*: The use of `default_delete` requires `T` to be a complete
1788
+ type. — *end note*]
1789
+
1790
+ *Remarks:* The behavior is undefined if the evaluation of
1791
+ `get_deleter()(get())` throws an exception.
1792
+
1793
+ ##### Assignment <a id="unique.ptr.single.asgn">[[unique.ptr.single.asgn]]</a>
1794
+
1795
+ ``` cpp
1796
+ constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;
1797
+ ```
1798
+
1799
+ *Constraints:* `is_move_assignable_v<D>` is `true`.
1800
+
1801
+ *Preconditions:* If `D` is not a reference type, `D` meets the
1802
+ *Cpp17MoveAssignable* requirements ([[cpp17.moveassignable]]) and
1803
+ assignment of the deleter from an rvalue of type `D` does not throw an
1804
+ exception. Otherwise, `D` is a reference type; `remove_reference_t<D>`
1805
+ meets the *Cpp17CopyAssignable* requirements and assignment of the
1806
+ deleter from an lvalue of type `D` does not throw an exception.
1807
+
1808
+ *Effects:* Calls `reset(u.release())` followed by
1809
+ `get_deleter() = std::forward<D>(u.get_deleter())`.
1810
+
1811
+ *Ensures:* If `this != addressof(u)`, `u.get() == nullptr`, otherwise
1812
+ `u.get()` is unchanged.
1813
+
1814
+ *Returns:* `*this`.
1815
+
1816
+ ``` cpp
1817
+ template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
1818
+ ```
1819
+
1820
+ *Constraints:*
1821
+
1822
+ - `unique_ptr<U, E>::pointer` is implicitly convertible to `pointer`,
1823
+ and
1824
+ - `U` is not an array type, and
1825
+ - `is_assignable_v<D&, E&&>` is `true`.
1826
+
1827
+ *Preconditions:* If `E` is not a reference type, assignment of the
1828
+ deleter from an rvalue of type `E` is well-formed and does not throw an
1829
+ exception. Otherwise, `E` is a reference type and assignment of the
1830
+ deleter from an lvalue of type `E` is well-formed and does not throw an
1831
+ exception.
1832
+
1833
+ *Effects:* Calls `reset(u.release())` followed by
1834
+ `get_deleter() = std::forward<E>(u.get_deleter())`.
1835
+
1836
+ *Ensures:* `u.get() == nullptr`.
1837
+
1838
+ *Returns:* `*this`.
1839
+
1840
+ ``` cpp
1841
+ constexpr unique_ptr& operator=(nullptr_t) noexcept;
1842
+ ```
1843
+
1844
+ *Effects:* As if by `reset()`.
1845
+
1846
+ *Ensures:* `get() == nullptr`.
1847
+
1848
+ *Returns:* `*this`.
1849
+
1850
+ ##### Observers <a id="unique.ptr.single.observers">[[unique.ptr.single.observers]]</a>
1851
+
1852
+ ``` cpp
1853
+ constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));
1854
+ ```
1855
+
1856
+ *Preconditions:* `get() != nullptr`.
1857
+
1858
+ *Returns:* `*get()`.
1859
+
1860
+ ``` cpp
1861
+ constexpr pointer operator->() const noexcept;
1862
+ ```
1863
+
1864
+ *Preconditions:* `get() != nullptr`.
1865
+
1866
+ *Returns:* `get()`.
1867
+
1868
+ [*Note 4*: The use of this function typically requires that `T` be a
1869
+ complete type. — *end note*]
1870
+
1871
+ ``` cpp
1872
+ constexpr pointer get() const noexcept;
1873
+ ```
1874
+
1875
+ *Returns:* The stored pointer.
1876
+
1877
+ ``` cpp
1878
+ constexpr deleter_type& get_deleter() noexcept;
1879
+ constexpr const deleter_type& get_deleter() const noexcept;
1880
+ ```
1881
+
1882
+ *Returns:* A reference to the stored deleter.
1883
+
1884
+ ``` cpp
1885
+ constexpr explicit operator bool() const noexcept;
1886
+ ```
1887
+
1888
+ *Returns:* `get() != nullptr`.
1889
+
1890
+ ##### Modifiers <a id="unique.ptr.single.modifiers">[[unique.ptr.single.modifiers]]</a>
1891
+
1892
+ ``` cpp
1893
+ constexpr pointer release() noexcept;
1894
+ ```
1895
+
1896
+ *Ensures:* `get() == nullptr`.
1897
+
1898
+ *Returns:* The value `get()` had at the start of the call to `release`.
1899
+
1900
+ ``` cpp
1901
+ constexpr void reset(pointer p = pointer()) noexcept;
1902
+ ```
1903
+
1904
+ *Effects:* Assigns `p` to the stored pointer, and then, with the old
1905
+ value of the stored pointer, `old_p`, evaluates
1906
+ `if (old_p) get_deleter()(old_p);`
1907
+
1908
+ [*Note 5*: The order of these operations is significant because the
1909
+ call to `get_deleter()` might destroy `*this`. — *end note*]
1910
+
1911
+ *Ensures:* `get() == p`.
1912
+
1913
+ [*Note 6*: The postcondition does not hold if the call to
1914
+ `get_deleter()` destroys `*this` since `this->get()` is no longer a
1915
+ valid expression. — *end note*]
1916
+
1917
+ *Remarks:* The behavior is undefined if the evaluation of
1918
+ `get_deleter()(old_p)` throws an exception.
1919
+
1920
+ ``` cpp
1921
+ constexpr void swap(unique_ptr& u) noexcept;
1922
+ ```
1923
+
1924
+ *Preconditions:* `get_deleter()` is swappable [[swappable.requirements]]
1925
+ and does not throw an exception under `swap`.
1926
+
1927
+ *Effects:* Invokes `swap` on the stored pointers and on the stored
1928
+ deleters of `*this` and `u`.
1929
+
1930
+ #### `unique_ptr` for array objects with a runtime length <a id="unique.ptr.runtime">[[unique.ptr.runtime]]</a>
1931
+
1932
+ ##### General <a id="unique.ptr.runtime.general">[[unique.ptr.runtime.general]]</a>
1933
+
1934
+ ``` cpp
1935
+ namespace std {
1936
+ template<class T, class D> class unique_ptr<T[], D> {
1937
+ public:
1938
+ using pointer = see below;
1939
+ using element_type = T;
1940
+ using deleter_type = D;
1941
+
1942
+ // [unique.ptr.runtime.ctor], constructors
1943
+ constexpr unique_ptr() noexcept;
1944
+ template<class U> constexpr explicit unique_ptr(U p) noexcept;
1945
+ template<class U> constexpr unique_ptr(U p, see below d) noexcept;
1946
+ template<class U> constexpr unique_ptr(U p, see below d) noexcept;
1947
+ constexpr unique_ptr(unique_ptr&& u) noexcept;
1948
+ template<class U, class E>
1949
+ constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
1950
+ constexpr unique_ptr(nullptr_t) noexcept;
1951
+
1952
+ // destructor
1953
+ constexpr ~unique_ptr();
1954
+
1955
+ // assignment
1956
+ constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;
1957
+ template<class U, class E>
1958
+ constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
1959
+ constexpr unique_ptr& operator=(nullptr_t) noexcept;
1960
+
1961
+ // [unique.ptr.runtime.observers], observers
1962
+ constexpr T& operator[](size_t i) const;
1963
+ constexpr pointer get() const noexcept;
1964
+ constexpr deleter_type& get_deleter() noexcept;
1965
+ constexpr const deleter_type& get_deleter() const noexcept;
1966
+ constexpr explicit operator bool() const noexcept;
1967
+
1968
+ // [unique.ptr.runtime.modifiers], modifiers
1969
+ constexpr pointer release() noexcept;
1970
+ template<class U> constexpr void reset(U p) noexcept;
1971
+ constexpr void reset(nullptr_t = nullptr) noexcept;
1972
+ constexpr void swap(unique_ptr& u) noexcept;
1973
+
1974
+ // disable copy from lvalue
1975
+ unique_ptr(const unique_ptr&) = delete;
1976
+ unique_ptr& operator=(const unique_ptr&) = delete;
1977
+ };
1978
+ }
1979
+ ```
1980
+
1981
+ A specialization for array types is provided with a slightly altered
1982
+ interface.
1983
+
1984
+ - Conversions between different types of `unique_ptr<T[], D>` that would
1985
+ be disallowed for the corresponding pointer-to-array types, and
1986
+ conversions to or from the non-array forms of `unique_ptr`, produce an
1987
+ ill-formed program.
1988
+ - Pointers to types derived from `T` are rejected by the constructors,
1989
+ and by `reset`.
1990
+ - The observers `operator*` and `operator->` are not provided.
1991
+ - The indexing observer `operator[]` is provided.
1992
+ - The default deleter will call `delete[]`.
1993
+
1994
+ Descriptions are provided below only for members that differ from the
1995
+ primary template.
1996
+
1997
+ The template argument `T` shall be a complete type.
1998
+
1999
+ ##### Constructors <a id="unique.ptr.runtime.ctor">[[unique.ptr.runtime.ctor]]</a>
2000
+
2001
+ ``` cpp
2002
+ template<class U> constexpr explicit unique_ptr(U p) noexcept;
2003
+ ```
2004
+
2005
+ This constructor behaves the same as the constructor in the primary
2006
+ template that takes a single parameter of type `pointer`.
2007
+
2008
+ *Constraints:*
2009
+
2010
+ - `U` is the same type as `pointer`, or
2011
+ - `pointer` is the same type as `element_type*`, `U` is a pointer type
2012
+ `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.
2013
+
2014
+ ``` cpp
2015
+ template<class U> constexpr unique_ptr(U p, see below d) noexcept;
2016
+ template<class U> constexpr unique_ptr(U p, see below d) noexcept;
2017
+ ```
2018
+
2019
+ These constructors behave the same as the constructors in the primary
2020
+ template that take a parameter of type `pointer` and a second parameter.
2021
+
2022
+ *Constraints:*
2023
+
2024
+ - `U` is the same type as `pointer`,
2025
+ - `U` is `nullptr_t`, or
2026
+ - `pointer` is the same type as `element_type*`, `U` is a pointer type
2027
+ `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.
2028
+
2029
+ ``` cpp
2030
+ template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
2031
+ ```
2032
+
2033
+ This constructor behaves the same as in the primary template.
2034
+
2035
+ *Constraints:* Where `UP` is `unique_ptr<U, E>`:
2036
+
2037
+ - `U` is an array type, and
2038
+ - `pointer` is the same type as `element_type*`, and
2039
+ - `UP::pointer` is the same type as `UP::element_type*`, and
2040
+ - `UP::element_type(*)[]` is convertible to `element_type(*)[]`, and
2041
+ - either `D` is a reference type and `E` is the same type as `D`, or `D`
2042
+ is not a reference type and `E` is implicitly convertible to `D`.
2043
+
2044
+ [*Note 1*: This replaces the *Constraints:* specification of the
2045
+ primary template. — *end note*]
2046
+
2047
+ ##### Assignment <a id="unique.ptr.runtime.asgn">[[unique.ptr.runtime.asgn]]</a>
2048
+
2049
+ ``` cpp
2050
+ template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
2051
+ ```
2052
+
2053
+ This operator behaves the same as in the primary template.
2054
+
2055
+ *Constraints:* Where `UP` is `unique_ptr<U, E>`:
2056
+
2057
+ - `U` is an array type, and
2058
+ - `pointer` is the same type as `element_type*`, and
2059
+ - `UP::pointer` is the same type as `UP::element_type*`, and
2060
+ - `UP::element_type(*)[]` is convertible to `element_type(*)[]`, and
2061
+ - `is_assignable_v<D&, E&&>` is `true`.
2062
+
2063
+ [*Note 2*: This replaces the *Constraints:* specification of the
2064
+ primary template. — *end note*]
2065
+
2066
+ ##### Observers <a id="unique.ptr.runtime.observers">[[unique.ptr.runtime.observers]]</a>
2067
+
2068
+ ``` cpp
2069
+ constexpr T& operator[](size_t i) const;
2070
+ ```
2071
+
2072
+ *Preconditions:* `i` < the number of elements in the array to which the
2073
+ stored pointer points.
2074
+
2075
+ *Returns:* `get()[i]`.
2076
+
2077
+ ##### Modifiers <a id="unique.ptr.runtime.modifiers">[[unique.ptr.runtime.modifiers]]</a>
2078
+
2079
+ ``` cpp
2080
+ constexpr void reset(nullptr_t p = nullptr) noexcept;
2081
+ ```
2082
+
2083
+ *Effects:* Equivalent to `reset(pointer())`.
2084
+
2085
+ ``` cpp
2086
+ constexpr template<class U> void reset(U p) noexcept;
2087
+ ```
2088
+
2089
+ This function behaves the same as the `reset` member of the primary
2090
+ template.
2091
+
2092
+ *Constraints:*
2093
+
2094
+ - `U` is the same type as `pointer`, or
2095
+ - `pointer` is the same type as `element_type*`, `U` is a pointer type
2096
+ `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.
2097
+
2098
+ #### Creation <a id="unique.ptr.create">[[unique.ptr.create]]</a>
2099
+
2100
+ ``` cpp
2101
+ template<class T, class... Args> constexpr unique_ptr<T> make_unique(Args&&... args);
2102
+ ```
2103
+
2104
+ *Constraints:* `T` is not an array type.
2105
+
2106
+ *Returns:* `unique_ptr<T>(new T(std::forward<Args>(args)...))`.
2107
+
2108
+ ``` cpp
2109
+ template<class T> constexpr unique_ptr<T> make_unique(size_t n);
2110
+ ```
2111
+
2112
+ *Constraints:* `T` is an array of unknown bound.
2113
+
2114
+ *Returns:* `unique_ptr<T>(new remove_extent_t<T>[n]())`.
2115
+
2116
+ ``` cpp
2117
+ template<class T, class... Args> unspecified make_unique(Args&&...) = delete;
2118
+ ```
2119
+
2120
+ *Constraints:* `T` is an array of known bound.
2121
+
2122
+ ``` cpp
2123
+ template<class T> constexpr unique_ptr<T> make_unique_for_overwrite();
2124
+ ```
2125
+
2126
+ *Constraints:* `T` is not an array type.
2127
+
2128
+ *Returns:* `unique_ptr<T>(new T)`.
2129
+
2130
+ ``` cpp
2131
+ template<class T> constexpr unique_ptr<T> make_unique_for_overwrite(size_t n);
2132
+ ```
2133
+
2134
+ *Constraints:* `T` is an array of unknown bound.
2135
+
2136
+ *Returns:* `unique_ptr<T>(new remove_extent_t<T>[n])`.
2137
+
2138
+ ``` cpp
2139
+ template<class T, class... Args> unspecified make_unique_for_overwrite(Args&&...) = delete;
2140
+ ```
2141
+
2142
+ *Constraints:* `T` is an array of known bound.
2143
+
2144
+ #### Specialized algorithms <a id="unique.ptr.special">[[unique.ptr.special]]</a>
2145
+
2146
+ ``` cpp
2147
+ template<class T, class D> constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
2148
+ ```
2149
+
2150
+ *Constraints:* `is_swappable_v<D>` is `true`.
2151
+
2152
+ *Effects:* Calls `x.swap(y)`.
2153
+
2154
+ ``` cpp
2155
+ template<class T1, class D1, class T2, class D2>
2156
+ constexpr bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2157
+ ```
2158
+
2159
+ *Returns:* `x.get() == y.get()`.
2160
+
2161
+ ``` cpp
2162
+ template<class T1, class D1, class T2, class D2>
2163
+ bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2164
+ ```
2165
+
2166
+ Let `CT` denote
2167
+
2168
+ ``` cpp
2169
+ common_type_t<typename unique_ptr<T1, D1>::pointer,
2170
+ typename unique_ptr<T2, D2>::pointer>
2171
+ ```
2172
+
2173
+ *Mandates:*
2174
+
2175
+ - `unique_ptr<T1, D1>::pointer` is implicitly convertible to `CT` and
2176
+ - `unique_ptr<T2, D2>::pointer` is implicitly convertible to `CT`.
2177
+
2178
+ *Preconditions:* The specialization `less<CT>` is a function object
2179
+ type [[function.objects]] that induces a strict weak
2180
+ ordering [[alg.sorting]] on the pointer values.
2181
+
2182
+ *Returns:* `less<CT>()(x.get(), y.get())`.
2183
+
2184
+ ``` cpp
2185
+ template<class T1, class D1, class T2, class D2>
2186
+ bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2187
+ ```
2188
+
2189
+ *Returns:* `y < x`.
2190
+
2191
+ ``` cpp
2192
+ template<class T1, class D1, class T2, class D2>
2193
+ bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2194
+ ```
2195
+
2196
+ *Returns:* `!(y < x)`.
2197
+
2198
+ ``` cpp
2199
+ template<class T1, class D1, class T2, class D2>
2200
+ bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2201
+ ```
2202
+
2203
+ *Returns:* `!(x < y)`.
2204
+
2205
+ ``` cpp
2206
+ template<class T1, class D1, class T2, class D2>
2207
+ requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
2208
+ typename unique_ptr<T2, D2>::pointer>
2209
+ compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
2210
+ typename unique_ptr<T2, D2>::pointer>
2211
+ operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2212
+ ```
2213
+
2214
+ *Returns:* `compare_three_way()(x.get(), y.get())`.
2215
+
2216
+ ``` cpp
2217
+ template<class T, class D>
2218
+ constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
2219
+ ```
2220
+
2221
+ *Returns:* `!x`.
2222
+
2223
+ ``` cpp
2224
+ template<class T, class D>
2225
+ constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t);
2226
+ template<class T, class D>
2227
+ constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& x);
2228
+ ```
2229
+
2230
+ *Preconditions:* The specialization `less<unique_ptr<T, D>::pointer>` is
2231
+ a function object type [[function.objects]] that induces a strict weak
2232
+ ordering [[alg.sorting]] on the pointer values.
2233
+
2234
+ *Returns:* The first function template returns
2235
+
2236
+ ``` cpp
2237
+ less<unique_ptr<T, D>::pointer>()(x.get(), nullptr)
2238
+ ```
2239
+
2240
+ The second function template returns
2241
+
2242
+ ``` cpp
2243
+ less<unique_ptr<T, D>::pointer>()(nullptr, x.get())
2244
+ ```
2245
+
2246
+ ``` cpp
2247
+ template<class T, class D>
2248
+ constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t);
2249
+ template<class T, class D>
2250
+ constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& x);
2251
+ ```
2252
+
2253
+ *Returns:* The first function template returns `nullptr < x`. The second
2254
+ function template returns `x < nullptr`.
2255
+
2256
+ ``` cpp
2257
+ template<class T, class D>
2258
+ constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
2259
+ template<class T, class D>
2260
+ constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& x);
2261
+ ```
2262
+
2263
+ *Returns:* The first function template returns `!(nullptr < x)`. The
2264
+ second function template returns `!(x < nullptr)`.
2265
+
2266
+ ``` cpp
2267
+ template<class T, class D>
2268
+ constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
2269
+ template<class T, class D>
2270
+ constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& x);
2271
+ ```
2272
+
2273
+ *Returns:* The first function template returns `!(x < nullptr)`. The
2274
+ second function template returns `!(nullptr < x)`.
2275
+
2276
+ ``` cpp
2277
+ template<class T, class D>
2278
+ requires three_way_comparable<typename unique_ptr<T, D>::pointer>
2279
+ constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
2280
+ operator<=>(const unique_ptr<T, D>& x, nullptr_t);
2281
+ ```
2282
+
2283
+ *Returns:*
2284
+
2285
+ ``` cpp
2286
+ compare_three_way()(x.get(), static_cast<typename unique_ptr<T, D>::pointer>(nullptr)).
2287
+ ```
2288
+
2289
+ #### I/O <a id="unique.ptr.io">[[unique.ptr.io]]</a>
2290
+
2291
+ ``` cpp
2292
+ template<class E, class T, class Y, class D>
2293
+ basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const unique_ptr<Y, D>& p);
2294
+ ```
2295
+
2296
+ *Constraints:* `os << p.get()` is a valid expression.
2297
+
2298
+ *Effects:* Equivalent to: `os << p.get();`
2299
+
2300
+ *Returns:* `os`.
2301
+
2302
+ ### Shared-ownership pointers <a id="util.sharedptr">[[util.sharedptr]]</a>
2303
+
2304
+ #### Class `bad_weak_ptr` <a id="util.smartptr.weak.bad">[[util.smartptr.weak.bad]]</a>
2305
+
2306
+ ``` cpp
2307
+ namespace std {
2308
+ class bad_weak_ptr : public exception {
2309
+ public:
2310
+ // see [exception] for the specification of the special member functions
2311
+ const char* what() const noexcept override;
2312
+ };
2313
+ }
2314
+ ```
2315
+
2316
+ An exception of type `bad_weak_ptr` is thrown by the `shared_ptr`
2317
+ constructor taking a `weak_ptr`.
2318
+
2319
+ ``` cpp
2320
+ const char* what() const noexcept override;
2321
+ ```
2322
+
2323
+ *Returns:* An *implementation-defined* NTBS.
2324
+
2325
+ #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
2326
+
2327
+ ##### General <a id="util.smartptr.shared.general">[[util.smartptr.shared.general]]</a>
2328
+
2329
+ The `shared_ptr` class template stores a pointer, usually obtained via
2330
+ `new`. `shared_ptr` implements semantics of shared ownership; the last
2331
+ remaining owner of the pointer is responsible for destroying the object,
2332
+ or otherwise releasing the resources associated with the stored pointer.
2333
+ A `shared_ptr` is said to be empty if it does not own a pointer.
2334
+
2335
+ ``` cpp
2336
+ namespace std {
2337
+ template<class T> class shared_ptr {
2338
+ public:
2339
+ using element_type = remove_extent_t<T>;
2340
+ using weak_type = weak_ptr<T>;
2341
+
2342
+ // [util.smartptr.shared.const], constructors
2343
+ constexpr shared_ptr() noexcept;
2344
+ constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
2345
+ template<class Y>
2346
+ explicit shared_ptr(Y* p);
2347
+ template<class Y, class D>
2348
+ shared_ptr(Y* p, D d);
2349
+ template<class Y, class D, class A>
2350
+ shared_ptr(Y* p, D d, A a);
2351
+ template<class D>
2352
+ shared_ptr(nullptr_t p, D d);
2353
+ template<class D, class A>
2354
+ shared_ptr(nullptr_t p, D d, A a);
2355
+ template<class Y>
2356
+ shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
2357
+ template<class Y>
2358
+ shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
2359
+ shared_ptr(const shared_ptr& r) noexcept;
2360
+ template<class Y>
2361
+ shared_ptr(const shared_ptr<Y>& r) noexcept;
2362
+ shared_ptr(shared_ptr&& r) noexcept;
2363
+ template<class Y>
2364
+ shared_ptr(shared_ptr<Y>&& r) noexcept;
2365
+ template<class Y>
2366
+ explicit shared_ptr(const weak_ptr<Y>& r);
2367
+ template<class Y, class D>
2368
+ shared_ptr(unique_ptr<Y, D>&& r);
2369
+
2370
+ // [util.smartptr.shared.dest], destructor
2371
+ ~shared_ptr();
2372
+
2373
+ // [util.smartptr.shared.assign], assignment
2374
+ shared_ptr& operator=(const shared_ptr& r) noexcept;
2375
+ template<class Y>
2376
+ shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
2377
+ shared_ptr& operator=(shared_ptr&& r) noexcept;
2378
+ template<class Y>
2379
+ shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
2380
+ template<class Y, class D>
2381
+ shared_ptr& operator=(unique_ptr<Y, D>&& r);
2382
+
2383
+ // [util.smartptr.shared.mod], modifiers
2384
+ void swap(shared_ptr& r) noexcept;
2385
+ void reset() noexcept;
2386
+ template<class Y>
2387
+ void reset(Y* p);
2388
+ template<class Y, class D>
2389
+ void reset(Y* p, D d);
2390
+ template<class Y, class D, class A>
2391
+ void reset(Y* p, D d, A a);
2392
+
2393
+ // [util.smartptr.shared.obs], observers
2394
+ element_type* get() const noexcept;
2395
+ T& operator*() const noexcept;
2396
+ T* operator->() const noexcept;
2397
+ element_type& operator[](ptrdiff_t i) const;
2398
+ long use_count() const noexcept;
2399
+ explicit operator bool() const noexcept;
2400
+ template<class U>
2401
+ bool owner_before(const shared_ptr<U>& b) const noexcept;
2402
+ template<class U>
2403
+ bool owner_before(const weak_ptr<U>& b) const noexcept;
2404
+ };
2405
+
2406
+ template<class T>
2407
+ shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
2408
+ template<class T, class D>
2409
+ shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
2410
+ }
2411
+ ```
2412
+
2413
+ Specializations of `shared_ptr` shall be *Cpp17CopyConstructible*,
2414
+ *Cpp17CopyAssignable*, and *Cpp17LessThanComparable*, allowing their use
2415
+ in standard containers. Specializations of `shared_ptr` shall be
2416
+ contextually convertible to `bool`, allowing their use in boolean
2417
+ expressions and declarations in conditions.
2418
+
2419
+ The template parameter `T` of `shared_ptr` may be an incomplete type.
2420
+
2421
+ [*Note 1*: `T` can be a function type. — *end note*]
2422
+
2423
+ [*Example 1*:
2424
+
2425
+ ``` cpp
2426
+ if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {
2427
+ // do something with px
2428
+ }
2429
+ ```
2430
+
2431
+ — *end example*]
2432
+
2433
+ For purposes of determining the presence of a data race, member
2434
+ functions shall access and modify only the `shared_ptr` and `weak_ptr`
2435
+ objects themselves and not objects they refer to. Changes in
2436
+ `use_count()` do not reflect modifications that can introduce data
2437
+ races.
2438
+
2439
+ For the purposes of subclause [[smartptr]], a pointer type `Y*` is said
2440
+ to be *compatible with* a pointer type `T*` when either `Y*` is
2441
+ convertible to `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
2442
+
2443
+ ##### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
2444
+
2445
+ In the constructor definitions below, enables `shared_from_this` with
2446
+ `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
2447
+ unambiguous and accessible base class that is a specialization of
2448
+ `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
2449
+ shall be implicitly convertible to `T*` and the constructor evaluates
2450
+ the statement:
2451
+
2452
+ ``` cpp
2453
+ if (p != nullptr && p->weak_this.expired())
2454
+ p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
2455
+ ```
2456
+
2457
+ The assignment to the `weak_this` member is not atomic and conflicts
2458
+ with any potentially concurrent access to the same object
2459
+ [[intro.multithread]].
2460
+
2461
+ ``` cpp
2462
+ constexpr shared_ptr() noexcept;
2463
+ ```
2464
+
2465
+ *Ensures:* `use_count() == 0 && get() == nullptr`.
2466
+
2467
+ ``` cpp
2468
+ template<class Y> explicit shared_ptr(Y* p);
2469
+ ```
2470
+
2471
+ *Constraints:* When `T` is an array type, the expression `delete[] p` is
2472
+ well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
2473
+ `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
2474
+ not an array type, the expression `delete p` is well-formed and `Y*` is
2475
+ convertible to `T*`.
2476
+
2477
+ *Mandates:* `Y` is a complete type.
2478
+
2479
+ *Preconditions:* The expression `delete[] p`, when `T` is an array type,
2480
+ or `delete p`, when `T` is not an array type, has well-defined behavior,
2481
+ and does not throw exceptions.
2482
+
2483
+ *Effects:* When `T` is not an array type, constructs a `shared_ptr`
2484
+ object that owns the pointer `p`. Otherwise, constructs a `shared_ptr`
2485
+ that owns `p` and a deleter of an unspecified type that calls
2486
+ `delete[] p`. When `T` is not an array type, enables `shared_from_this`
2487
+ with `p`. If an exception is thrown, `delete p` is called when `T` is
2488
+ not an array type, `delete[] p` otherwise.
2489
+
2490
+ *Ensures:* `use_count() == 1 && get() == p`.
2491
+
2492
+ *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
2493
+ resource other than memory cannot be obtained.
2494
+
2495
+ ``` cpp
2496
+ template<class Y, class D> shared_ptr(Y* p, D d);
2497
+ template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
2498
+ template<class D> shared_ptr(nullptr_t p, D d);
2499
+ template<class D, class A> shared_ptr(nullptr_t p, D d, A a);
2500
+ ```
2501
+
2502
+ *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
2503
+ well-formed expression. For the first two overloads:
2504
+
2505
+ - If `T` is an array type, then either `T` is `U[N]` and `Y(*)[N]` is
2506
+ convertible to `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to
2507
+ `T*`.
2508
+ - If `T` is not an array type, then `Y*` is convertible to `T*`.
2509
+
2510
+ *Preconditions:* Construction of `d` and a deleter of type `D`
2511
+ initialized with `std::move(d)` do not throw exceptions. The expression
2512
+ `d(p)` has well-defined behavior and does not throw exceptions. `A`
2513
+ meets the *Cpp17Allocator*
2514
+ requirements [[allocator.requirements.general]].
2515
+
2516
+ *Effects:* Constructs a `shared_ptr` object that owns the object `p` and
2517
+ the deleter `d`. When `T` is not an array type, the first and second
2518
+ constructors enable `shared_from_this` with `p`. The second and fourth
2519
+ constructors shall use a copy of `a` to allocate memory for internal
2520
+ use. If an exception is thrown, `d(p)` is called.
2521
+
2522
+ *Ensures:* `use_count() == 1 && get() == p`.
2523
+
2524
+ *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
2525
+ resource other than memory cannot be obtained.
2526
+
2527
+ ``` cpp
2528
+ template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
2529
+ template<class Y> shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
2530
+ ```
2531
+
2532
+ *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
2533
+ ownership with the initial value of `r`.
2534
+
2535
+ *Ensures:* `get() == p`. For the second overload, `r` is empty and
2536
+ `r.get() == nullptr`.
2537
+
2538
+ [*Note 1*: Use of this constructor leads to a dangling pointer unless
2539
+ `p` remains valid at least until the ownership group of `r` is
2540
+ destroyed. — *end note*]
2541
+
2542
+ [*Note 2*: This constructor allows creation of an empty `shared_ptr`
2543
+ instance with a non-null stored pointer. — *end note*]
2544
+
2545
+ ``` cpp
2546
+ shared_ptr(const shared_ptr& r) noexcept;
2547
+ template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
2548
+ ```
2549
+
2550
+ *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
2551
+
2552
+ *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
2553
+ otherwise, constructs a `shared_ptr` object that shares ownership with
2554
+ `r`.
2555
+
2556
+ *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
2557
+
2558
+ ``` cpp
2559
+ shared_ptr(shared_ptr&& r) noexcept;
2560
+ template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
2561
+ ```
2562
+
2563
+ *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
2564
+
2565
+ *Effects:* Move constructs a `shared_ptr` instance from `r`.
2566
+
2567
+ *Ensures:* `*this` contains the old value of `r`. `r` is empty, and
2568
+ `r.get() == nullptr`.
2569
+
2570
+ ``` cpp
2571
+ template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
2572
+ ```
2573
+
2574
+ *Constraints:* `Y*` is compatible with `T*`.
2575
+
2576
+ *Effects:* Constructs a `shared_ptr` object that shares ownership with
2577
+ `r` and stores a copy of the pointer stored in `r`. If an exception is
2578
+ thrown, the constructor has no effect.
2579
+
2580
+ *Ensures:* `use_count() == r.use_count()`.
2581
+
2582
+ *Throws:* `bad_weak_ptr` when `r.expired()`.
2583
+
2584
+ ``` cpp
2585
+ template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
2586
+ ```
2587
+
2588
+ *Constraints:* `Y*` is compatible with `T*` and
2589
+ `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
2590
+
2591
+ *Effects:* If `r.get() == nullptr`, equivalent to `shared_ptr()`.
2592
+ Otherwise, if `D` is not a reference type, equivalent to
2593
+ `shared_ptr(r.release(), std::move(r.get_deleter()))`. Otherwise,
2594
+ equivalent to `shared_ptr(r.release(), ref(r.get_deleter()))`. If an
2595
+ exception is thrown, the constructor has no effect.
2596
+
2597
+ ##### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
2598
+
2599
+ ``` cpp
2600
+ ~shared_ptr();
2601
+ ```
2602
+
2603
+ *Effects:*
2604
+
2605
+ - If `*this` is empty or shares ownership with another `shared_ptr`
2606
+ instance (`use_count() > 1`), there are no side effects.
2607
+ - Otherwise, if `*this` owns an object `p` and a deleter `d`, `d(p)` is
2608
+ called.
2609
+ - Otherwise, `*this` owns a pointer `p`, and `delete p` is called.
2610
+
2611
+ [*Note 2*: Since the destruction of `*this` decreases the number of
2612
+ instances that share ownership with `*this` by one, after `*this` has
2613
+ been destroyed all `shared_ptr` instances that shared ownership with
2614
+ `*this` will report a `use_count()` that is one less than its previous
2615
+ value. — *end note*]
2616
+
2617
+ ##### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
2618
+
2619
+ ``` cpp
2620
+ shared_ptr& operator=(const shared_ptr& r) noexcept;
2621
+ template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
2622
+ ```
2623
+
2624
+ *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
2625
+
2626
+ *Returns:* `*this`.
2627
+
2628
+ [*Note 3*:
2629
+
2630
+ The use count updates caused by the temporary object construction and
2631
+ destruction are not observable side effects, so the implementation can
2632
+ meet the effects (and the implied guarantees) via different means,
2633
+ without creating a temporary. In particular, in the example:
2634
+
2635
+ ``` cpp
2636
+ shared_ptr<int> p(new int);
2637
+ shared_ptr<void> q(p);
2638
+ p = p;
2639
+ q = p;
2640
+ ```
2641
+
2642
+ both assignments can be no-ops.
2643
+
2644
+ — *end note*]
2645
+
2646
+ ``` cpp
2647
+ shared_ptr& operator=(shared_ptr&& r) noexcept;
2648
+ template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
2649
+ ```
2650
+
2651
+ *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
2652
+
2653
+ *Returns:* `*this`.
2654
+
2655
+ ``` cpp
2656
+ template<class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
2657
+ ```
2658
+
2659
+ *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
2660
+
2661
+ *Returns:* `*this`.
2662
+
2663
+ ##### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
2664
+
2665
+ ``` cpp
2666
+ void swap(shared_ptr& r) noexcept;
2667
+ ```
2668
+
2669
+ *Effects:* Exchanges the contents of `*this` and `r`.
2670
+
2671
+ ``` cpp
2672
+ void reset() noexcept;
2673
+ ```
2674
+
2675
+ *Effects:* Equivalent to `shared_ptr().swap(*this)`.
2676
+
2677
+ ``` cpp
2678
+ template<class Y> void reset(Y* p);
2679
+ ```
2680
+
2681
+ *Effects:* Equivalent to `shared_ptr(p).swap(*this)`.
2682
+
2683
+ ``` cpp
2684
+ template<class Y, class D> void reset(Y* p, D d);
2685
+ ```
2686
+
2687
+ *Effects:* Equivalent to `shared_ptr(p, d).swap(*this)`.
2688
+
2689
+ ``` cpp
2690
+ template<class Y, class D, class A> void reset(Y* p, D d, A a);
2691
+ ```
2692
+
2693
+ *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
2694
+
2695
+ ##### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
2696
+
2697
+ ``` cpp
2698
+ element_type* get() const noexcept;
2699
+ ```
2700
+
2701
+ *Returns:* The stored pointer.
2702
+
2703
+ ``` cpp
2704
+ T& operator*() const noexcept;
2705
+ ```
2706
+
2707
+ *Preconditions:* `get() != nullptr`.
2708
+
2709
+ *Returns:* `*get()`.
2710
+
2711
+ *Remarks:* When `T` is an array type or cv `void`, it is unspecified
2712
+ whether this member function is declared. If it is declared, it is
2713
+ unspecified what its return type is, except that the declaration
2714
+ (although not necessarily the definition) of the function shall be
2715
+ well-formed.
2716
+
2717
+ ``` cpp
2718
+ T* operator->() const noexcept;
2719
+ ```
2720
+
2721
+ *Preconditions:* `get() != nullptr`.
2722
+
2723
+ *Returns:* `get()`.
2724
+
2725
+ *Remarks:* When `T` is an array type, it is unspecified whether this
2726
+ member function is declared. If it is declared, it is unspecified what
2727
+ its return type is, except that the declaration (although not
2728
+ necessarily the definition) of the function shall be well-formed.
2729
+
2730
+ ``` cpp
2731
+ element_type& operator[](ptrdiff_t i) const;
2732
+ ```
2733
+
2734
+ *Preconditions:* `get() != nullptr && i >= 0`. If `T` is `U[N]`,
2735
+ `i < N`.
2736
+
2737
+ *Returns:* `get()[i]`.
2738
+
2739
+ *Throws:* Nothing.
2740
+
2741
+ *Remarks:* When `T` is not an array type, it is unspecified whether this
2742
+ member function is declared. If it is declared, it is unspecified what
2743
+ its return type is, except that the declaration (although not
2744
+ necessarily the definition) of the function shall be well-formed.
2745
+
2746
+ ``` cpp
2747
+ long use_count() const noexcept;
2748
+ ```
2749
+
2750
+ *Synchronization:* None.
2751
+
2752
+ *Returns:* The number of `shared_ptr` objects, `*this` included, that
2753
+ share ownership with `*this`, or `0` when `*this` is empty.
2754
+
2755
+ [*Note 4*: `get() == nullptr` does not imply a specific return value of
2756
+ `use_count()`. — *end note*]
2757
+
2758
+ [*Note 5*: `weak_ptr<T>::lock()` can affect the return value of
2759
+ `use_count()`. — *end note*]
2760
+
2761
+ [*Note 6*: When multiple threads might affect the return value of
2762
+ `use_count()`, the result is approximate. In particular,
2763
+ `use_count() == 1` does not imply that accesses through a previously
2764
+ destroyed `shared_ptr` have in any sense completed. — *end note*]
2765
+
2766
+ ``` cpp
2767
+ explicit operator bool() const noexcept;
2768
+ ```
2769
+
2770
+ *Returns:* `get() != nullptr`.
2771
+
2772
+ ``` cpp
2773
+ template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
2774
+ template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
2775
+ ```
2776
+
2777
+ *Returns:* An unspecified value such that
2778
+
2779
+ - `x.owner_before(y)` defines a strict weak ordering as defined
2780
+ in  [[alg.sorting]];
2781
+ - under the equivalence relation defined by `owner_before`,
2782
+ `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
2783
+ `weak_ptr` instances are equivalent if and only if they share
2784
+ ownership or are both empty.
2785
+
2786
+ ##### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
2787
+
2788
+ The common requirements that apply to all `make_shared`,
2789
+ `allocate_shared`, `make_shared_for_overwrite`, and
2790
+ `allocate_shared_for_overwrite` overloads, unless specified otherwise,
2791
+ are described below.
2792
+
2793
+ ``` cpp
2794
+ template<class T, ...>
2795
+ shared_ptr<T> make_shared(args);
2796
+ template<class T, class A, ...>
2797
+ shared_ptr<T> allocate_shared(const A& a, args);
2798
+ template<class T, ...>
2799
+ shared_ptr<T> make_shared_for_overwrite(args);
2800
+ template<class T, class A, ...>
2801
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
2802
+ ```
2803
+
2804
+ *Preconditions:* `A` meets the *Cpp17Allocator*
2805
+ requirements [[allocator.requirements.general]].
2806
+
2807
+ *Effects:* Allocates memory for an object of type `T` (or `U[N]` when
2808
+ `T` is `U[]`, where `N` is determined from *args* as specified by the
2809
+ concrete overload). The object is initialized from *args* as specified
2810
+ by the concrete overload. The `allocate_shared` and
2811
+ `allocate_shared_for_overwrite` templates use a copy of `a` (rebound for
2812
+ an unspecified `value_type`) to allocate memory. If an exception is
2813
+ thrown, the functions have no effect.
2814
+
2815
+ *Ensures:* `r.get() != nullptr && r.use_count() == 1`, where `r` is the
2816
+ return value.
2817
+
2818
+ *Returns:* A `shared_ptr` instance that stores and owns the address of
2819
+ the newly constructed object.
2820
+
2821
+ *Throws:* `bad_alloc`, or an exception thrown from `allocate` or from
2822
+ the initialization of the object.
2823
+
2824
+ *Remarks:*
2825
+
2826
+ - Implementations should perform no more than one memory allocation.
2827
+ \[*Note 3*: This provides efficiency equivalent to an intrusive smart
2828
+ pointer. — *end note*]
2829
+ - When an object of an array type `U` is specified to have an initial
2830
+ value of `u` (of the same type), this shall be interpreted to mean
2831
+ that each array element of the object has as its initial value the
2832
+ corresponding element from `u`.
2833
+ - When an object of an array type is specified to have a default initial
2834
+ value, this shall be interpreted to mean that each array element of
2835
+ the object has a default initial value.
2836
+ - When a (sub)object of a non-array type `U` is specified to have an
2837
+ initial value of `v`, or `U(l...)`, where `l...` is a list of
2838
+ constructor arguments, `make_shared` shall initialize this (sub)object
2839
+ via the expression `::new(pv) U(v)` or `::new(pv) U(l...)`
2840
+ respectively, where `pv` has type `void*` and points to storage
2841
+ suitable to hold an object of type `U`.
2842
+ - When a (sub)object of a non-array type `U` is specified to have an
2843
+ initial value of `v`, or `U(l...)`, where `l...` is a list of
2844
+ constructor arguments, `allocate_shared` shall initialize this
2845
+ (sub)object via the expression
2846
+ - `allocator_traits<A2>::construct(a2, pv, v)` or
2847
+ - `allocator_traits<A2>::construct(a2, pv, l...)`
2848
+
2849
+ respectively, where `pv` points to storage suitable to hold an object
2850
+ of type `U` and `a2` of type `A2` is a rebound copy of the allocator
2851
+ `a` passed to `allocate_shared` such that its `value_type` is
2852
+ `remove_cv_t<U>`.
2853
+ - When a (sub)object of non-array type `U` is specified to have a
2854
+ default initial value, `make_shared` shall initialize this (sub)object
2855
+ via the expression `::new(pv) U()`, where `pv` has type `void*` and
2856
+ points to storage suitable to hold an object of type `U`.
2857
+ - When a (sub)object of non-array type `U` is specified to have a
2858
+ default initial value, `allocate_shared` shall initialize this
2859
+ (sub)object via the expression
2860
+ `allocator_traits<A2>::construct(a2, pv)`, where `pv` points to
2861
+ storage suitable to hold an object of type `U` and `a2` of type `A2`
2862
+ is a rebound copy of the allocator `a` passed to `allocate_shared`
2863
+ such that its `value_type` is `remove_cv_t<U>`.
2864
+ - When a (sub)object of non-array type `U` is initialized by
2865
+ `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
2866
+ initialized via the expression `::new(pv) U`, where `pv` has type
2867
+ `void*` and points to storage suitable to hold an object of type `U`.
2868
+ - Array elements are initialized in ascending order of their addresses.
2869
+ - When the lifetime of the object managed by the return value ends, or
2870
+ when the initialization of an array element throws an exception, the
2871
+ initialized elements are destroyed in the reverse order of their
2872
+ original construction.
2873
+ - When a (sub)object of non-array type `U` that was initialized by
2874
+ `make_shared` is to be destroyed, it is destroyed via the expression
2875
+ `pv->~U()` where `pv` points to that object of type `U`.
2876
+ - When a (sub)object of non-array type `U` that was initialized by
2877
+ `allocate_shared` is to be destroyed, it is destroyed via the
2878
+ expression `allocator_traits<A2>::destroy(a2, pv)` where `pv` points
2879
+ to that object of type `remove_cv_t<U>` and `a2` of type `A2` is a
2880
+ rebound copy of the allocator `a` passed to `allocate_shared` such
2881
+ that its `value_type` is `remove_cv_t<U>`.
2882
+
2883
+ [*Note 7*: These functions will typically allocate more memory than
2884
+ `sizeof(T)` to allow for internal bookkeeping structures such as
2885
+ reference counts. — *end note*]
2886
+
2887
+ ``` cpp
2888
+ template<class T, class... Args>
2889
+ shared_ptr<T> make_shared(Args&&... args); // T is not array
2890
+ template<class T, class A, class... Args>
2891
+ shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
2892
+ ```
2893
+
2894
+ *Constraints:* `T` is not an array type.
2895
+
2896
+ *Returns:* A `shared_ptr` to an object of type `T` with an initial value
2897
+ `T(std::forward<Args>(args)...)`.
2898
+
2899
+ *Remarks:* The `shared_ptr` constructors called by these functions
2900
+ enable `shared_from_this` with the address of the newly constructed
2901
+ object of type `T`.
2902
+
2903
+ [*Example 1*:
2904
+
2905
+ ``` cpp
2906
+ shared_ptr<int> p = make_shared<int>(); // shared_ptr to int()
2907
+ shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1);
2908
+ // shared_ptr to vector of 16 elements with value 1
2909
+ ```
2910
+
2911
+ — *end example*]
2912
+
2913
+ ``` cpp
2914
+ template<class T> shared_ptr<T>
2915
+ make_shared(size_t N); // T is U[]
2916
+ template<class T, class A>
2917
+ shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
2918
+ ```
2919
+
2920
+ *Constraints:* `T` is of the form `U[]`.
2921
+
2922
+ *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
2923
+ initial value, where `U` is `remove_extent_t<T>`.
2924
+
2925
+ [*Example 2*:
2926
+
2927
+ ``` cpp
2928
+ shared_ptr<double[]> p = make_shared<double[]>(1024);
2929
+ // shared_ptr to a value-initialized double[1024]
2930
+ shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6);
2931
+ // shared_ptr to a value-initialized double[6][2][2]
2932
+ ```
2933
+
2934
+ — *end example*]
2935
+
2936
+ ``` cpp
2937
+ template<class T>
2938
+ shared_ptr<T> make_shared(); // T is U[N]
2939
+ template<class T, class A>
2940
+ shared_ptr<T> allocate_shared(const A& a); // T is U[N]
2941
+ ```
2942
+
2943
+ *Constraints:* `T` is of the form `U[N]`.
2944
+
2945
+ *Returns:* A `shared_ptr` to an object of type `T` with a default
2946
+ initial value.
2947
+
2948
+ [*Example 3*:
2949
+
2950
+ ``` cpp
2951
+ shared_ptr<double[1024]> p = make_shared<double[1024]>();
2952
+ // shared_ptr to a value-initialized double[1024]
2953
+ shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>();
2954
+ // shared_ptr to a value-initialized double[6][2][2]
2955
+ ```
2956
+
2957
+ — *end example*]
2958
+
2959
+ ``` cpp
2960
+ template<class T>
2961
+ shared_ptr<T> make_shared(size_t N,
2962
+ const remove_extent_t<T>& u); // T is U[]
2963
+ template<class T, class A>
2964
+ shared_ptr<T> allocate_shared(const A& a, size_t N,
2965
+ const remove_extent_t<T>& u); // T is U[]
2966
+ ```
2967
+
2968
+ *Constraints:* `T` is of the form `U[]`.
2969
+
2970
+ *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
2971
+ `remove_extent_t<T>` and each array element has an initial value of `u`.
2972
+
2973
+ [*Example 4*:
2974
+
2975
+ ``` cpp
2976
+ shared_ptr<double[]> p = make_shared<double[]>(1024, 1.0);
2977
+ // shared_ptr to a double[1024], where each element is 1.0
2978
+ shared_ptr<double[][2]> q = make_shared<double[][2]>(6, {1.0, 0.0});
2979
+ // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0}
2980
+ shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2});
2981
+ // shared_ptr to a vector<int>[4], where each vector has contents {1, 2}
2982
+ ```
2983
+
2984
+ — *end example*]
2985
+
2986
+ ``` cpp
2987
+ template<class T>
2988
+ shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
2989
+ template<class T, class A>
2990
+ shared_ptr<T> allocate_shared(const A& a,
2991
+ const remove_extent_t<T>& u); // T is U[N]
2992
+ ```
2993
+
2994
+ *Constraints:* `T` is of the form `U[N]`.
2995
+
2996
+ *Returns:* A `shared_ptr` to an object of type `T`, where each array
2997
+ element of type `remove_extent_t<T>` has an initial value of `u`.
2998
+
2999
+ [*Example 5*:
3000
+
3001
+ ``` cpp
3002
+ shared_ptr<double[1024]> p = make_shared<double[1024]>(1.0);
3003
+ // shared_ptr to a double[1024], where each element is 1.0
3004
+ shared_ptr<double[6][2]> q = make_shared<double[6][2]>({1.0, 0.0});
3005
+ // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0}
3006
+ shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2});
3007
+ // shared_ptr to a vector<int>[4], where each vector has contents {1, 2}
3008
+ ```
3009
+
3010
+ — *end example*]
3011
+
3012
+ ``` cpp
3013
+ template<class T>
3014
+ shared_ptr<T> make_shared_for_overwrite();
3015
+ template<class T, class A>
3016
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a);
3017
+ ```
3018
+
3019
+ *Constraints:* `T` is not an array of unknown bound.
3020
+
3021
+ *Returns:* A `shared_ptr` to an object of type `T`.
3022
+
3023
+ [*Example 6*:
3024
+
3025
+ ``` cpp
3026
+ struct X { double data[1024]; };
3027
+ shared_ptr<X> p = make_shared_for_overwrite<X>();
3028
+ // shared_ptr to a default-initialized X, where each element in X::data has an indeterminate value
3029
+
3030
+ shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>();
3031
+ // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value
3032
+ ```
3033
+
3034
+ — *end example*]
3035
+
3036
+ ``` cpp
3037
+ template<class T>
3038
+ shared_ptr<T> make_shared_for_overwrite(size_t N);
3039
+ template<class T, class A>
3040
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
3041
+ ```
3042
+
3043
+ *Constraints:* `T` is an array of unknown bound.
3044
+
3045
+ *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
3046
+ `remove_extent_t<T>`.
3047
+
3048
+ [*Example 7*:
3049
+
3050
+ ``` cpp
3051
+ shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024);
3052
+ // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value
3053
+ ```
3054
+
3055
+ — *end example*]
3056
+
3057
+ ##### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
3058
+
3059
+ ``` cpp
3060
+ template<class T, class U>
3061
+ bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
3062
+ ```
3063
+
3064
+ *Returns:* `a.get() == b.get()`.
3065
+
3066
+ ``` cpp
3067
+ template<class T>
3068
+ bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
3069
+ ```
3070
+
3071
+ *Returns:* `!a`.
3072
+
3073
+ ``` cpp
3074
+ template<class T, class U>
3075
+ strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
3076
+ ```
3077
+
3078
+ *Returns:* `compare_three_way()(a.get(), b.get())`.
3079
+
3080
+ [*Note 8*: Defining a comparison operator function allows `shared_ptr`
3081
+ objects to be used as keys in associative containers. — *end note*]
3082
+
3083
+ ``` cpp
3084
+ template<class T>
3085
+ strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
3086
+ ```
3087
+
3088
+ *Returns:*
3089
+
3090
+ ``` cpp
3091
+ compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr).
3092
+ ```
3093
+
3094
+ ##### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
3095
+
3096
+ ``` cpp
3097
+ template<class T>
3098
+ void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
3099
+ ```
3100
+
3101
+ *Effects:* Equivalent to `a.swap(b)`.
3102
+
3103
+ ##### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
3104
+
3105
+ ``` cpp
3106
+ template<class T, class U>
3107
+ shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
3108
+ template<class T, class U>
3109
+ shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
3110
+ ```
3111
+
3112
+ *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
3113
+ well-formed.
3114
+
3115
+ *Returns:*
3116
+
3117
+ ``` cpp
3118
+ shared_ptr<T>(R, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
3119
+ ```
3120
+
3121
+ where *`R`* is `r` for the first overload, and `std::move(r)` for the
3122
+ second.
3123
+
3124
+ [*Note 9*: The seemingly equivalent expression
3125
+ `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
3126
+ undefined behavior, attempting to delete the same object
3127
+ twice. — *end note*]
3128
+
3129
+ ``` cpp
3130
+ template<class T, class U>
3131
+ shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
3132
+ template<class T, class U>
3133
+ shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
3134
+ ```
3135
+
3136
+ *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
3137
+ well-formed. The expression
3138
+ `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is
3139
+ well-formed.
3140
+
3141
+ *Preconditions:* The expression
3142
+ `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` has
3143
+ well-defined behavior.
3144
+
3145
+ *Returns:*
3146
+
3147
+ - When `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())`
3148
+ returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
3149
+ is `r` for the first overload, and `std::move(r)` for the second.
3150
+ - Otherwise, `shared_ptr<T>()`.
3151
+
3152
+ [*Note 10*: The seemingly equivalent expression
3153
+ `shared_ptr<T>(dynamic_cast<T*>(r.get()))` will eventually result in
3154
+ undefined behavior, attempting to delete the same object
3155
+ twice. — *end note*]
3156
+
3157
+ ``` cpp
3158
+ template<class T, class U>
3159
+ shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
3160
+ template<class T, class U>
3161
+ shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
3162
+ ```
3163
+
3164
+ *Mandates:* The expression `const_cast<T*>((U*)nullptr)` is well-formed.
3165
+
3166
+ *Returns:*
3167
+
3168
+ ``` cpp
3169
+ shared_ptr<T>(R, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
3170
+ ```
3171
+
3172
+ where *`R`* is `r` for the first overload, and `std::move(r)` for the
3173
+ second.
3174
+
3175
+ [*Note 11*: The seemingly equivalent expression
3176
+ `shared_ptr<T>(const_cast<T*>(r.get()))` will eventually result in
3177
+ undefined behavior, attempting to delete the same object
3178
+ twice. — *end note*]
3179
+
3180
+ ``` cpp
3181
+ template<class T, class U>
3182
+ shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
3183
+ template<class T, class U>
3184
+ shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
3185
+ ```
3186
+
3187
+ *Mandates:* The expression `reinterpret_cast<T*>((U*)nullptr)` is
3188
+ well-formed.
3189
+
3190
+ *Returns:*
3191
+
3192
+ ``` cpp
3193
+ shared_ptr<T>(R, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()))
3194
+ ```
3195
+
3196
+ where *`R`* is `r` for the first overload, and `std::move(r)` for the
3197
+ second.
3198
+
3199
+ [*Note 12*: The seemingly equivalent expression
3200
+ `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` will eventually result in
3201
+ undefined behavior, attempting to delete the same object
3202
+ twice. — *end note*]
3203
+
3204
+ ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
3205
+
3206
+ ``` cpp
3207
+ template<class D, class T>
3208
+ D* get_deleter(const shared_ptr<T>& p) noexcept;
3209
+ ```
3210
+
3211
+ *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
3212
+ `addressof(d)`; otherwise returns `nullptr`. The returned pointer
3213
+ remains valid as long as there exists a `shared_ptr` instance that owns
3214
+ `d`.
3215
+
3216
+ [*Note 13*: It is unspecified whether the pointer remains valid longer
3217
+ than that. This can happen if the implementation doesn’t destroy the
3218
+ deleter until all `weak_ptr` instances that share ownership with `p`
3219
+ have been destroyed. — *end note*]
3220
+
3221
+ ##### I/O <a id="util.smartptr.shared.io">[[util.smartptr.shared.io]]</a>
3222
+
3223
+ ``` cpp
3224
+ template<class E, class T, class Y>
3225
+ basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);
3226
+ ```
3227
+
3228
+ *Effects:* As if by: `os << p.get();`
3229
+
3230
+ *Returns:* `os`.
3231
+
3232
+ #### Class template `weak_ptr` <a id="util.smartptr.weak">[[util.smartptr.weak]]</a>
3233
+
3234
+ ##### General <a id="util.smartptr.weak.general">[[util.smartptr.weak.general]]</a>
3235
+
3236
+ The `weak_ptr` class template stores a weak reference to an object that
3237
+ is already managed by a `shared_ptr`. To access the object, a `weak_ptr`
3238
+ can be converted to a `shared_ptr` using the member function `lock`.
3239
+
3240
+ ``` cpp
3241
+ namespace std {
3242
+ template<class T> class weak_ptr {
3243
+ public:
3244
+ using element_type = remove_extent_t<T>;
3245
+
3246
+ // [util.smartptr.weak.const], constructors
3247
+ constexpr weak_ptr() noexcept;
3248
+ template<class Y>
3249
+ weak_ptr(const shared_ptr<Y>& r) noexcept;
3250
+ weak_ptr(const weak_ptr& r) noexcept;
3251
+ template<class Y>
3252
+ weak_ptr(const weak_ptr<Y>& r) noexcept;
3253
+ weak_ptr(weak_ptr&& r) noexcept;
3254
+ template<class Y>
3255
+ weak_ptr(weak_ptr<Y>&& r) noexcept;
3256
+
3257
+ // [util.smartptr.weak.dest], destructor
3258
+ ~weak_ptr();
3259
+
3260
+ // [util.smartptr.weak.assign], assignment
3261
+ weak_ptr& operator=(const weak_ptr& r) noexcept;
3262
+ template<class Y>
3263
+ weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
3264
+ template<class Y>
3265
+ weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
3266
+ weak_ptr& operator=(weak_ptr&& r) noexcept;
3267
+ template<class Y>
3268
+ weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
3269
+
3270
+ // [util.smartptr.weak.mod], modifiers
3271
+ void swap(weak_ptr& r) noexcept;
3272
+ void reset() noexcept;
3273
+
3274
+ // [util.smartptr.weak.obs], observers
3275
+ long use_count() const noexcept;
3276
+ bool expired() const noexcept;
3277
+ shared_ptr<T> lock() const noexcept;
3278
+ template<class U>
3279
+ bool owner_before(const shared_ptr<U>& b) const noexcept;
3280
+ template<class U>
3281
+ bool owner_before(const weak_ptr<U>& b) const noexcept;
3282
+ };
3283
+
3284
+ template<class T>
3285
+ weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
3286
+ }
3287
+ ```
3288
+
3289
+ Specializations of `weak_ptr` shall be *Cpp17CopyConstructible* and
3290
+ *Cpp17CopyAssignable*, allowing their use in standard containers. The
3291
+ template parameter `T` of `weak_ptr` may be an incomplete type.
3292
+
3293
+ ##### Constructors <a id="util.smartptr.weak.const">[[util.smartptr.weak.const]]</a>
3294
+
3295
+ ``` cpp
3296
+ constexpr weak_ptr() noexcept;
3297
+ ```
3298
+
3299
+ *Effects:* Constructs an empty `weak_ptr` object that stores a null
3300
+ pointer value.
3301
+
3302
+ *Ensures:* `use_count() == 0`.
3303
+
3304
+ ``` cpp
3305
+ weak_ptr(const weak_ptr& r) noexcept;
3306
+ template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
3307
+ template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
3308
+ ```
3309
+
3310
+ *Constraints:* For the second and third constructors, `Y*` is compatible
3311
+ with `T*`.
3312
+
3313
+ *Effects:* If `r` is empty, constructs an empty `weak_ptr` object that
3314
+ stores a null pointer value; otherwise, constructs a `weak_ptr` object
3315
+ that shares ownership with `r` and stores a copy of the pointer stored
3316
+ in `r`.
3317
+
3318
+ *Ensures:* `use_count() == r.use_count()`.
3319
+
3320
+ ``` cpp
3321
+ weak_ptr(weak_ptr&& r) noexcept;
3322
+ template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
3323
+ ```
3324
+
3325
+ *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
3326
+
3327
+ *Effects:* Move constructs a `weak_ptr` instance from `r`.
3328
+
3329
+ *Ensures:* `*this` contains the old value of `r`. `r` is empty, stores a
3330
+ null pointer value, and `r.use_count() == 0`.
3331
+
3332
+ ##### Destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
3333
+
3334
+ ``` cpp
3335
+ ~weak_ptr();
3336
+ ```
3337
+
3338
+ *Effects:* Destroys this `weak_ptr` object but has no effect on the
3339
+ object its stored pointer points to.
3340
+
3341
+ ##### Assignment <a id="util.smartptr.weak.assign">[[util.smartptr.weak.assign]]</a>
3342
+
3343
+ ``` cpp
3344
+ weak_ptr& operator=(const weak_ptr& r) noexcept;
3345
+ template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
3346
+ template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
3347
+ ```
3348
+
3349
+ *Effects:* Equivalent to `weak_ptr(r).swap(*this)`.
3350
+
3351
+ *Returns:* `*this`.
3352
+
3353
+ *Remarks:* The implementation may meet the effects (and the implied
3354
+ guarantees) via different means, without creating a temporary object.
3355
+
3356
+ ``` cpp
3357
+ weak_ptr& operator=(weak_ptr&& r) noexcept;
3358
+ template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
3359
+ ```
3360
+
3361
+ *Effects:* Equivalent to `weak_ptr(std::move(r)).swap(*this)`.
3362
+
3363
+ *Returns:* `*this`.
3364
+
3365
+ ##### Modifiers <a id="util.smartptr.weak.mod">[[util.smartptr.weak.mod]]</a>
3366
+
3367
+ ``` cpp
3368
+ void swap(weak_ptr& r) noexcept;
3369
+ ```
3370
+
3371
+ *Effects:* Exchanges the contents of `*this` and `r`.
3372
+
3373
+ ``` cpp
3374
+ void reset() noexcept;
3375
+ ```
3376
+
3377
+ *Effects:* Equivalent to `weak_ptr().swap(*this)`.
3378
+
3379
+ ##### Observers <a id="util.smartptr.weak.obs">[[util.smartptr.weak.obs]]</a>
3380
+
3381
+ ``` cpp
3382
+ long use_count() const noexcept;
3383
+ ```
3384
+
3385
+ *Returns:* `0` if `*this` is empty; otherwise, the number of
3386
+ `shared_ptr` instances that share ownership with `*this`.
3387
+
3388
+ ``` cpp
3389
+ bool expired() const noexcept;
3390
+ ```
3391
+
3392
+ *Returns:* `use_count() == 0`.
3393
+
3394
+ ``` cpp
3395
+ shared_ptr<T> lock() const noexcept;
3396
+ ```
3397
+
3398
+ *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
3399
+ executed atomically.
3400
+
3401
+ ``` cpp
3402
+ template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
3403
+ template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
3404
+ ```
3405
+
3406
+ *Returns:* An unspecified value such that
3407
+
3408
+ - `x.owner_before(y)` defines a strict weak ordering as defined
3409
+ in  [[alg.sorting]];
3410
+ - under the equivalence relation defined by `owner_before`,
3411
+ `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
3412
+ `weak_ptr` instances are equivalent if and only if they share
3413
+ ownership or are both empty.
3414
+
3415
+ ##### Specialized algorithms <a id="util.smartptr.weak.spec">[[util.smartptr.weak.spec]]</a>
3416
+
3417
+ ``` cpp
3418
+ template<class T>
3419
+ void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
3420
+ ```
3421
+
3422
+ *Effects:* Equivalent to `a.swap(b)`.
3423
+
3424
+ #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
3425
+
3426
+ The class template `owner_less` allows ownership-based mixed comparisons
3427
+ of shared and weak pointers.
3428
+
3429
+ ``` cpp
3430
+ namespace std {
3431
+ template<class T = void> struct owner_less;
3432
+
3433
+ template<class T> struct owner_less<shared_ptr<T>> {
3434
+ bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
3435
+ bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
3436
+ bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
3437
+ };
3438
+
3439
+ template<class T> struct owner_less<weak_ptr<T>> {
3440
+ bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
3441
+ bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
3442
+ bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
3443
+ };
3444
+
3445
+ template<> struct owner_less<void> {
3446
+ template<class T, class U>
3447
+ bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
3448
+ template<class T, class U>
3449
+ bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
3450
+ template<class T, class U>
3451
+ bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
3452
+ template<class T, class U>
3453
+ bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
3454
+
3455
+ using is_transparent = unspecified;
3456
+ };
3457
+ }
3458
+ ```
3459
+
3460
+ `operator()(x, y)` returns `x.owner_before(y)`.
3461
+
3462
+ [*Note 1*:
3463
+
3464
+ Note that
3465
+
3466
+ - `operator()` defines a strict weak ordering as defined in 
3467
+ [[alg.sorting]];
3468
+ - two `shared_ptr` or `weak_ptr` instances are equivalent under the
3469
+ equivalence relation defined by `operator()`,
3470
+ `!operator()(a, b) && !operator()(b, a)`, if and only if they share
3471
+ ownership or are both empty.
3472
+
3473
+ — *end note*]
3474
+
3475
+ #### Class template `enable_shared_from_this` <a id="util.smartptr.enab">[[util.smartptr.enab]]</a>
3476
+
3477
+ A class `T` can inherit from `enable_shared_from_this<T>` to inherit the
3478
+ `shared_from_this` member functions that obtain a `shared_ptr` instance
3479
+ pointing to `*this`.
3480
+
3481
+ [*Example 1*:
3482
+
3483
+ ``` cpp
3484
+ struct X: public enable_shared_from_this<X> { };
3485
+
3486
+ int main() {
3487
+ shared_ptr<X> p(new X);
3488
+ shared_ptr<X> q = p->shared_from_this();
3489
+ assert(p == q);
3490
+ assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
3491
+ }
3492
+ ```
3493
+
3494
+ — *end example*]
3495
+
3496
+ ``` cpp
3497
+ namespace std {
3498
+ template<class T> class enable_shared_from_this {
3499
+ protected:
3500
+ constexpr enable_shared_from_this() noexcept;
3501
+ enable_shared_from_this(const enable_shared_from_this&) noexcept;
3502
+ enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
3503
+ ~enable_shared_from_this();
3504
+
3505
+ public:
3506
+ shared_ptr<T> shared_from_this();
3507
+ shared_ptr<T const> shared_from_this() const;
3508
+ weak_ptr<T> weak_from_this() noexcept;
3509
+ weak_ptr<T const> weak_from_this() const noexcept;
3510
+
3511
+ private:
3512
+ mutable weak_ptr<T> weak_this; // exposition only
3513
+ };
3514
+ }
3515
+ ```
3516
+
3517
+ The template parameter `T` of `enable_shared_from_this` may be an
3518
+ incomplete type.
3519
+
3520
+ ``` cpp
3521
+ constexpr enable_shared_from_this() noexcept;
3522
+ enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
3523
+ ```
3524
+
3525
+ *Effects:* Value-initializes `weak_this`.
3526
+
3527
+ ``` cpp
3528
+ enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
3529
+ ```
3530
+
3531
+ *Returns:* `*this`.
3532
+
3533
+ [*Note 1*: `weak_this` is not changed. — *end note*]
3534
+
3535
+ ``` cpp
3536
+ shared_ptr<T> shared_from_this();
3537
+ shared_ptr<T const> shared_from_this() const;
3538
+ ```
3539
+
3540
+ *Returns:* `shared_ptr<T>(weak_this)`.
3541
+
3542
+ ``` cpp
3543
+ weak_ptr<T> weak_from_this() noexcept;
3544
+ weak_ptr<T const> weak_from_this() const noexcept;
3545
+ ```
3546
+
3547
+ *Returns:* `weak_this`.
3548
+
3549
+ ### Smart pointer hash support <a id="util.smartptr.hash">[[util.smartptr.hash]]</a>
3550
+
3551
+ ``` cpp
3552
+ template<class T, class D> struct hash<unique_ptr<T, D>>;
3553
+ ```
3554
+
3555
+ Letting `UP` be `unique_ptr<T, D>`, the specialization `hash<UP>` is
3556
+ enabled [[unord.hash]] if and only if `hash<typename UP::pointer>` is
3557
+ enabled. When enabled, for an object `p` of type `UP`, `hash<UP>()(p)`
3558
+ evaluates to the same value as `hash<typename UP::pointer>()(p.get())`.
3559
+ The member functions are not guaranteed to be `noexcept`.
3560
+
3561
+ ``` cpp
3562
+ template<class T> struct hash<shared_ptr<T>>;
3563
+ ```
3564
+
3565
+ For an object `p` of type `shared_ptr<T>`, `hash<shared_ptr<T>>()(p)`
3566
+ evaluates to the same value as
3567
+ `hash<typename shared_ptr<T>::element_type*>()(p.get())`.
3568
+
3569
+ ### Smart pointer adaptors <a id="smartptr.adapt">[[smartptr.adapt]]</a>
3570
+
3571
+ #### Class template `out_ptr_t` <a id="out.ptr.t">[[out.ptr.t]]</a>
3572
+
3573
+ `out_ptr_t` is a class template used to adapt types such as smart
3574
+ pointers [[smartptr]] for functions that use output pointer parameters.
3575
+
3576
+ [*Example 1*:
3577
+
3578
+ ``` cpp
3579
+ #include <memory>
3580
+ #include <cstdio>
3581
+
3582
+ int fopen_s(std::FILE** f, const char* name, const char* mode);
3583
+
3584
+ struct fclose_deleter {
3585
+ void operator()(std::FILE* f) const noexcept {
3586
+ std::fclose(f);
3587
+ }
3588
+ };
3589
+
3590
+ int main(int, char*[]) {
3591
+ constexpr const char* file_name = "ow.o";
3592
+ std::unique_ptr<std::FILE, fclose_deleter> file_ptr;
3593
+ int err = fopen_s(std::out_ptr<std::FILE*>(file_ptr), file_name, "r+b");
3594
+ if (err != 0)
3595
+ return 1;
3596
+ // *file_ptr is valid
3597
+ return 0;
3598
+ }
3599
+ ```
3600
+
3601
+ `unique_ptr` can be used with `out_ptr` to be passed into an output
3602
+ pointer-style function, without needing to hold onto an intermediate
3603
+ pointer value and manually delete it on error or failure.
3604
+
3605
+ — *end example*]
3606
+
3607
+ ``` cpp
3608
+ namespace std {
3609
+ template<class Smart, class Pointer, class... Args>
3610
+ class out_ptr_t {
3611
+ public:
3612
+ explicit out_ptr_t(Smart&, Args...);
3613
+ out_ptr_t(const out_ptr_t&) = delete;
3614
+
3615
+ ~out_ptr_t();
3616
+
3617
+ operator Pointer*() const noexcept;
3618
+ operator void**() const noexcept;
3619
+
3620
+ private:
3621
+ Smart& s; // exposition only
3622
+ tuple<Args...> a; // exposition only
3623
+ Pointer p; // exposition only
3624
+ };
3625
+ }
3626
+ ```
3627
+
3628
+ `Pointer` shall meet the *Cpp17NullablePointer* requirements. If `Smart`
3629
+ is a specialization of `shared_ptr` and `sizeof...(Args) == 0`, the
3630
+ program is ill-formed.
3631
+
3632
+ [*Note 1*: It is typically a user error to reset a `shared_ptr` without
3633
+ specifying a deleter, as `shared_ptr` will replace a custom deleter upon
3634
+ usage of `reset`, as specified in
3635
+ [[util.smartptr.shared.mod]]. — *end note*]
3636
+
3637
+ Program-defined specializations of `out_ptr_t` that depend on at least
3638
+ one program-defined type need not meet the requirements for the primary
3639
+ template.
3640
+
3641
+ Evaluations of the conversion functions on the same object may conflict
3642
+ [[intro.races]].
3643
+
3644
+ ``` cpp
3645
+ explicit out_ptr_t(Smart& smart, Args... args);
3646
+ ```
3647
+
3648
+ *Effects:* Initializes `s` with `smart`, `a` with
3649
+ `std::forward<Args>(args)...`, and value-initializes `p`. Then,
3650
+ equivalent to:
3651
+
3652
+ - ``` cpp
3653
+ s.reset();
3654
+ ```
3655
+
3656
+ if the expression `s.reset()` is well-formed;
3657
+
3658
+ - otherwise,
3659
+ ``` cpp
3660
+ s = Smart();
3661
+ ```
3662
+
3663
+ if `is_constructible_v<Smart>` is `true`;
3664
+
3665
+ - otherwise, the program is ill-formed.
3666
+
3667
+ [*Note 1*: The constructor is not `noexcept` to allow for a variety of
3668
+ non-terminating and safe implementation strategies. For example, an
3669
+ implementation can allocate a `shared_ptr`’s internal node in the
3670
+ constructor and let implementation-defined exceptions escape safely. The
3671
+ destructor can then move the allocated control block in directly and
3672
+ avoid any other exceptions. — *end note*]
3673
+
3674
+ ``` cpp
3675
+ ~out_ptr_t();
3676
+ ```
3677
+
3678
+ Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
3679
+
3680
+ *Effects:* Equivalent to:
3681
+
3682
+ -
3683
+ ``` cpp
3684
+ if (p) {
3685
+ apply([&](auto&&... args) {
3686
+ s.reset(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
3687
+ }
3688
+ ```
3689
+
3690
+ if the expression
3691
+ `s.reset(static_cast<SP>(p), std::forward<Args>(args)...)` is
3692
+ well-formed;
3693
+ - otherwise,
3694
+ ``` cpp
3695
+ if (p) {
3696
+ apply([&](auto&&... args) {
3697
+ s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
3698
+ }
3699
+ ```
3700
+
3701
+ if `is_constructible_v<Smart, SP, Args...>` is `true`;
3702
+ - otherwise, the program is ill-formed.
3703
+
3704
+ ``` cpp
3705
+ operator Pointer*() const noexcept;
3706
+ ```
3707
+
3708
+ *Preconditions:* `operator void**()` has not been called on `*this`.
3709
+
3710
+ *Returns:* `addressof(const_cast<Pointer&>(p))`.
3711
+
3712
+ ``` cpp
3713
+ operator void**() const noexcept;
3714
+ ```
3715
+
3716
+ *Constraints:* `is_same_v<Pointer, void*>` is `false`.
3717
+
3718
+ *Mandates:* `is_pointer_v<Pointer>` is `true`.
3719
+
3720
+ *Preconditions:* `operator Pointer*()` has not been called on `*this`.
3721
+
3722
+ *Returns:* A pointer value `v` such that:
3723
+
3724
+ - the initial value `*v` is equivalent to `static_cast<void*>(p)` and
3725
+ - any modification of `*v` that is not followed by a subsequent
3726
+ modification of `*this` affects the value of `p` during the
3727
+ destruction of `*this`, such that `static_cast<void*>(p) == *v`.
3728
+
3729
+ *Remarks:* Accessing `*v` outside the lifetime of `*this` has undefined
3730
+ behavior.
3731
+
3732
+ [*Note 2*: `reinterpret_cast<void**>(static_cast<Pointer*>(*this))` can
3733
+ be a viable implementation strategy for some
3734
+ implementations. — *end note*]
3735
+
3736
+ #### Function template `out_ptr` <a id="out.ptr">[[out.ptr]]</a>
3737
+
3738
+ ``` cpp
3739
+ template<class Pointer = void, class Smart, class... Args>
3740
+ auto out_ptr(Smart& s, Args&&... args);
3741
+ ```
3742
+
3743
+ Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
3744
+ *`POINTER_OF`*`(Smart)`.
3745
+
3746
+ *Returns:*
3747
+ `out_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)`
3748
+
3749
+ #### Class template `inout_ptr_t` <a id="inout.ptr.t">[[inout.ptr.t]]</a>
3750
+
3751
+ `inout_ptr_t` is a class template used to adapt types such as smart
3752
+ pointers [[smartptr]] for functions that use output pointer parameters
3753
+ whose dereferenced values may first be deleted before being set to
3754
+ another allocated value.
3755
+
3756
+ [*Example 1*:
3757
+
3758
+ ``` cpp
3759
+ #include <memory>
3760
+
3761
+ struct star_fish* star_fish_alloc();
3762
+ int star_fish_populate(struct star_fish** ps, const char* description);
3763
+
3764
+ struct star_fish_deleter {
3765
+ void operator() (struct star_fish* c) const noexcept;
3766
+ };
3767
+
3768
+ using star_fish_ptr = std::unique_ptr<star_fish, star_fish_deleter>;
3769
+
3770
+ int main(int, char*[]) {
3771
+ star_fish_ptr peach(star_fish_alloc());
3772
+ // ...
3773
+ // used, need to re-make
3774
+ int err = star_fish_populate(std::inout_ptr(peach), "caring clown-fish liker");
3775
+ return err;
3776
+ }
3777
+ ```
3778
+
3779
+ A `unique_ptr` can be used with `inout_ptr` to be passed into an output
3780
+ pointer-style function. The original value will be properly deleted
3781
+ according to the function it is used with and a new value reset in its
3782
+ place.
3783
+
3784
+ — *end example*]
3785
+
3786
+ ``` cpp
3787
+ namespace std {
3788
+ template<class Smart, class Pointer, class... Args>
3789
+ class inout_ptr_t {
3790
+ public:
3791
+ explicit inout_ptr_t(Smart&, Args...);
3792
+ inout_ptr_t(const inout_ptr_t&) = delete;
3793
+
3794
+ ~inout_ptr_t();
3795
+
3796
+ operator Pointer*() const noexcept;
3797
+ operator void**() const noexcept;
3798
+
3799
+ private:
3800
+ Smart& s; // exposition only
3801
+ tuple<Args...> a; // exposition only
3802
+ Pointer p; // exposition only
3803
+ };
3804
+ }
3805
+ ```
3806
+
3807
+ `Pointer` shall meet the *Cpp17NullablePointer* requirements. If `Smart`
3808
+ is a specialization of `shared_ptr`, the program is ill-formed.
3809
+
3810
+ [*Note 1*: It is impossible to properly acquire unique ownership of the
3811
+ managed resource from a `shared_ptr` given its shared ownership
3812
+ model. — *end note*]
3813
+
3814
+ Program-defined specializations of `inout_ptr_t` that depend on at least
3815
+ one program-defined type need not meet the requirements for the primary
3816
+ template.
3817
+
3818
+ Evaluations of the conversion functions on the same object may conflict
3819
+ [[intro.races]].
3820
+
3821
+ ``` cpp
3822
+ explicit inout_ptr_t(Smart& smart, Args... args);
3823
+ ```
3824
+
3825
+ *Effects:* Initializes `s` with `smart`, `a` with
3826
+ `std::forward<Args>(args)...`, and `p` to either
3827
+
3828
+ - `smart` if `is_pointer_v<Smart>` is `true`,
3829
+ - otherwise, `smart.get()`.
3830
+
3831
+ *Remarks:* An implementation can call `s.release()`.
3832
+
3833
+ [*Note 1*: The constructor is not `noexcept` to allow for a variety of
3834
+ non-terminating and safe implementation strategies. For example, an
3835
+ intrusive pointer implementation with a control block can allocate in
3836
+ the constructor and safely fail with an exception. — *end note*]
3837
+
3838
+ ``` cpp
3839
+ ~inout_ptr_t();
3840
+ ```
3841
+
3842
+ Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
3843
+
3844
+ Let *release-statement* be `s.release();` if an implementation does not
3845
+ call `s.release()` in the constructor. Otherwise, it is empty.
3846
+
3847
+ *Effects:* Equivalent to:
3848
+
3849
+ -
3850
+ ``` cpp
3851
+ if (p) {
3852
+ apply([&](auto&&... args) {
3853
+ s = Smart( static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
3854
+ }
3855
+ ```
3856
+
3857
+ if `is_pointer_v<Smart>` is `true`;
3858
+ - otherwise,
3859
+ ``` cpp
3860
+ release-statement;
3861
+ if (p) {
3862
+ apply([&](auto&&... args) {
3863
+ s.reset(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
3864
+ }
3865
+ ```
3866
+
3867
+ if the expression
3868
+ `s.reset(static_cast<SP>(p), std::forward<Args>(args)...)` is well-
3869
+ formed;
3870
+ - otherwise,
3871
+ ``` cpp
3872
+ release-statement;
3873
+ if (p) {
3874
+ apply([&](auto&&... args) {
3875
+ s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
3876
+ }
3877
+ ```
3878
+
3879
+ if `is_constructible_v<Smart, SP, Args...>` is `true`;
3880
+ - otherwise, the program is ill-formed.
3881
+
3882
+ ``` cpp
3883
+ operator Pointer*() const noexcept;
3884
+ ```
3885
+
3886
+ *Preconditions:* `operator void**()` has not been called on `*this`.
3887
+
3888
+ *Returns:* `addressof(const_cast<Pointer&>(p))`.
3889
+
3890
+ ``` cpp
3891
+ operator void**() const noexcept;
3892
+ ```
3893
+
3894
+ *Constraints:* `is_same_v<Pointer, void*>` is `false`.
3895
+
3896
+ *Mandates:* `is_pointer_v<Pointer>` is `true`.
3897
+
3898
+ *Preconditions:* `operator Pointer*()` has not been called on `*this`.
3899
+
3900
+ *Returns:* A pointer value `v` such that:
3901
+
3902
+ - the initial value `*v` is equivalent to `static_cast<void*>(p)` and
3903
+ - any modification of `*v` that is not followed by subsequent
3904
+ modification of `*this` affects the value of `p` during the
3905
+ destruction of `*this`, such that `static_cast<void*>(p) == *v`.
3906
+
3907
+ *Remarks:* Accessing `*v` outside the lifetime of `*this` has undefined
3908
+ behavior.
3909
+
3910
+ [*Note 2*: `reinterpret_cast<void**>(static_cast<Pointer*>(*this))` can
3911
+ be a viable implementation strategy for some
3912
+ implementations. — *end note*]
3913
+
3914
+ #### Function template `inout_ptr` <a id="inout.ptr">[[inout.ptr]]</a>
3915
+
3916
+ ``` cpp
3917
+ template<class Pointer = void, class Smart, class... Args>
3918
+ auto inout_ptr(Smart& s, Args&&... args);
3919
+ ```
3920
+
3921
+ Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
3922
+ *`POINTER_OF`*`(Smart)`.
3923
+
3924
+ *Returns:*
3925
+ `inout_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)`.
3926
+
3927
+ ## Memory resources <a id="mem.res">[[mem.res]]</a>
3928
+
3929
+ ### Header `<memory_resource>` synopsis <a id="mem.res.syn">[[mem.res.syn]]</a>
3930
+
3931
+ ``` cpp
3932
+ namespace std::pmr {
3933
+ // [mem.res.class], class memory_resource
3934
+ class memory_resource;
3935
+
3936
+ bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
3937
+
3938
+ // [mem.poly.allocator.class], class template polymorphic_allocator
3939
+ template<class Tp = byte> class polymorphic_allocator;
3940
+
3941
+ template<class T1, class T2>
3942
+ bool operator==(const polymorphic_allocator<T1>& a,
3943
+ const polymorphic_allocator<T2>& b) noexcept;
3944
+
3945
+ // [mem.res.global], global memory resources
3946
+ memory_resource* new_delete_resource() noexcept;
3947
+ memory_resource* null_memory_resource() noexcept;
3948
+ memory_resource* set_default_resource(memory_resource* r) noexcept;
3949
+ memory_resource* get_default_resource() noexcept;
3950
+
3951
+ // [mem.res.pool], pool resource classes
3952
+ struct pool_options;
3953
+ class synchronized_pool_resource;
3954
+ class unsynchronized_pool_resource;
3955
+ class monotonic_buffer_resource;
3956
+ }
3957
+ ```
3958
+
3959
+ ### Class `memory_resource` <a id="mem.res.class">[[mem.res.class]]</a>
3960
+
3961
+ #### General <a id="mem.res.class.general">[[mem.res.class.general]]</a>
3962
+
3963
+ The `memory_resource` class is an abstract interface to an unbounded set
3964
+ of classes encapsulating memory resources.
3965
+
3966
+ ``` cpp
3967
+ namespace std::pmr {
3968
+ class memory_resource {
3969
+ static constexpr size_t max_align = alignof(max_align_t); // exposition only
3970
+
3971
+ public:
3972
+ memory_resource() = default;
3973
+ memory_resource(const memory_resource&) = default;
3974
+ virtual ~memory_resource();
3975
+
3976
+ memory_resource& operator=(const memory_resource&) = default;
3977
+
3978
+ [[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align);
3979
+ void deallocate(void* p, size_t bytes, size_t alignment = max_align);
3980
+
3981
+ bool is_equal(const memory_resource& other) const noexcept;
3982
+
3983
+ private:
3984
+ virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
3985
+ virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;
3986
+
3987
+ virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
3988
+ };
3989
+ }
3990
+ ```
3991
+
3992
+ #### Public member functions <a id="mem.res.public">[[mem.res.public]]</a>
3993
+
3994
+ ``` cpp
3995
+ ~memory_resource();
3996
+ ```
3997
+
3998
+ *Effects:* Destroys this `memory_resource`.
3999
+
4000
+ ``` cpp
4001
+ [[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align);
4002
+ ```
4003
+
4004
+ *Effects:* Allocates storage by calling `do_allocate(bytes, alignment)`
4005
+ and implicitly creates objects within the allocated region of storage.
4006
+
4007
+ *Returns:* A pointer to a suitable created object [[intro.object]] in
4008
+ the allocated region of storage.
4009
+
4010
+ *Throws:* What and when the call to `do_allocate` throws.
4011
+
4012
+ ``` cpp
4013
+ void deallocate(void* p, size_t bytes, size_t alignment = max_align);
4014
+ ```
4015
+
4016
+ *Effects:* Equivalent to `do_deallocate(p, bytes, alignment)`.
4017
+
4018
+ ``` cpp
4019
+ bool is_equal(const memory_resource& other) const noexcept;
4020
+ ```
4021
+
4022
+ *Effects:* Equivalent to: `return do_is_equal(other);`
4023
+
4024
+ #### Private virtual member functions <a id="mem.res.private">[[mem.res.private]]</a>
4025
+
4026
+ ``` cpp
4027
+ virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
4028
+ ```
4029
+
4030
+ *Preconditions:* `alignment` is a power of two.
4031
+
4032
+ *Returns:* A derived class shall implement this function to return a
4033
+ pointer to allocated storage [[basic.stc.dynamic.allocation]] with a
4034
+ size of at least `bytes`, aligned to the specified `alignment`.
4035
+
4036
+ *Throws:* A derived class implementation shall throw an appropriate
4037
+ exception if it is unable to allocate memory with the requested size and
4038
+ alignment.
4039
+
4040
+ ``` cpp
4041
+ virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;
4042
+ ```
4043
+
4044
+ *Preconditions:* `p` was returned from a prior call to
4045
+ `allocate(bytes, alignment)` on a memory resource equal to `*this`, and
4046
+ the storage at `p` has not yet been deallocated.
4047
+
4048
+ *Effects:* A derived class shall implement this function to dispose of
4049
+ allocated storage.
4050
+
4051
+ *Throws:* Nothing.
4052
+
4053
+ ``` cpp
4054
+ virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
4055
+ ```
4056
+
4057
+ *Returns:* A derived class shall implement this function to return
4058
+ `true` if memory allocated from `this` can be deallocated from `other`
4059
+ and vice-versa, otherwise `false`.
4060
+
4061
+ [*Note 1*: It is possible that the most-derived type of `other` does
4062
+ not match the type of `this`. For a derived class `D`, an implementation
4063
+ of this function can immediately return `false` if
4064
+ `dynamic_cast<const D*>(&other) == nullptr`. — *end note*]
4065
+
4066
+ #### Equality <a id="mem.res.eq">[[mem.res.eq]]</a>
4067
+
4068
+ ``` cpp
4069
+ bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
4070
+ ```
4071
+
4072
+ *Returns:* `&a == &b || a.is_equal(b)`.
4073
+
4074
+ ### Class template `polymorphic_allocator` <a id="mem.poly.allocator.class">[[mem.poly.allocator.class]]</a>
4075
+
4076
+ #### General <a id="mem.poly.allocator.class.general">[[mem.poly.allocator.class.general]]</a>
4077
+
4078
+ A specialization of class template `pmr::polymorphic_allocator` meets
4079
+ the *Cpp17Allocator* requirements [[allocator.requirements.general]] if
4080
+ its template argument is a cv-unqualified object type. Constructed with
4081
+ different memory resources, different instances of the same
4082
+ specialization of `pmr::polymorphic_allocator` can exhibit entirely
4083
+ different allocation behavior. This runtime polymorphism allows objects
4084
+ that use `polymorphic_allocator` to behave as if they used different
4085
+ allocator types at run time even though they use the same static
4086
+ allocator type.
4087
+
4088
+ A specialization of class template `pmr::polymorphic_allocator` meets
4089
+ the allocator completeness requirements
4090
+ [[allocator.requirements.completeness]] if its template argument is a
4091
+ cv-unqualified object type.
4092
+
4093
+ ``` cpp
4094
+ namespace std::pmr {
4095
+ template<class Tp = byte> class polymorphic_allocator {
4096
+ memory_resource* memory_rsrc; // exposition only
4097
+
4098
+ public:
4099
+ using value_type = Tp;
4100
+
4101
+ // [mem.poly.allocator.ctor], constructors
4102
+ polymorphic_allocator() noexcept;
4103
+ polymorphic_allocator(memory_resource* r);
4104
+
4105
+ polymorphic_allocator(const polymorphic_allocator& other) = default;
4106
+
4107
+ template<class U>
4108
+ polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
4109
+
4110
+ polymorphic_allocator& operator=(const polymorphic_allocator&) = delete;
4111
+
4112
+ // [mem.poly.allocator.mem], member functions
4113
+ [[nodiscard]] Tp* allocate(size_t n);
4114
+ void deallocate(Tp* p, size_t n);
4115
+
4116
+ [[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
4117
+ void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
4118
+ template<class T> [[nodiscard]] T* allocate_object(size_t n = 1);
4119
+ template<class T> void deallocate_object(T* p, size_t n = 1);
4120
+ template<class T, class... CtorArgs> [[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
4121
+ template<class T> void delete_object(T* p);
4122
+
4123
+ template<class T, class... Args>
4124
+ void construct(T* p, Args&&... args);
4125
+
4126
+ polymorphic_allocator select_on_container_copy_construction() const;
4127
+
4128
+ memory_resource* resource() const;
4129
+
4130
+ // friends
4131
+ friend bool operator==(const polymorphic_allocator& a,
4132
+ const polymorphic_allocator& b) noexcept {
4133
+ return *a.resource() == *b.resource();
4134
+ }
4135
+ };
4136
+ }
4137
+ ```
4138
+
4139
+ #### Constructors <a id="mem.poly.allocator.ctor">[[mem.poly.allocator.ctor]]</a>
4140
+
4141
+ ``` cpp
4142
+ polymorphic_allocator() noexcept;
4143
+ ```
4144
+
4145
+ *Effects:* Sets `memory_rsrc` to `get_default_resource()`.
4146
+
4147
+ ``` cpp
4148
+ polymorphic_allocator(memory_resource* r);
4149
+ ```
4150
+
4151
+ *Preconditions:* `r` is non-null.
4152
+
4153
+ *Effects:* Sets `memory_rsrc` to `r`.
4154
+
4155
+ *Throws:* Nothing.
4156
+
4157
+ [*Note 1*: This constructor provides an implicit conversion from
4158
+ `memory_resource*`. — *end note*]
4159
+
4160
+ ``` cpp
4161
+ template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
4162
+ ```
4163
+
4164
+ *Effects:* Sets `memory_rsrc` to `other.resource()`.
4165
+
4166
+ #### Member functions <a id="mem.poly.allocator.mem">[[mem.poly.allocator.mem]]</a>
4167
+
4168
+ ``` cpp
4169
+ [[nodiscard]] Tp* allocate(size_t n);
4170
+ ```
4171
+
4172
+ *Effects:* If `numeric_limits<size_t>::max() / sizeof(Tp) < n`, throws
4173
+ `bad_array_new_length`. Otherwise equivalent to:
4174
+
4175
+ ``` cpp
4176
+ return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));
4177
+ ```
4178
+
4179
+ ``` cpp
4180
+ void deallocate(Tp* p, size_t n);
4181
+ ```
4182
+
4183
+ *Preconditions:* `p` was allocated from a memory resource `x`, equal to
4184
+ `*memory_rsrc`, using `x.allocate(n * sizeof(Tp), alignof(Tp))`.
4185
+
4186
+ *Effects:* Equivalent to
4187
+ `memory_rsrc->deallocate(p, n * sizeof(Tp), alignof(Tp))`.
4188
+
4189
+ *Throws:* Nothing.
4190
+
4191
+ ``` cpp
4192
+ [[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
4193
+ ```
4194
+
4195
+ *Effects:* Equivalent to:
4196
+ `return memory_rsrc->allocate(nbytes, alignment);`
4197
+
4198
+ [*Note 1*: The return type is `void*` (rather than, e.g., `byte*`) to
4199
+ support conversion to an arbitrary pointer type `U*` by
4200
+ `static_cast<U*>`, thus facilitating construction of a `U` object in the
4201
+ allocated memory. — *end note*]
4202
+
4203
+ ``` cpp
4204
+ void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
4205
+ ```
4206
+
4207
+ *Effects:* Equivalent to
4208
+ `memory_rsrc->deallocate(p, nbytes, alignment)`.
4209
+
4210
+ ``` cpp
4211
+ template<class T>
4212
+ [[nodiscard]] T* allocate_object(size_t n = 1);
4213
+ ```
4214
+
4215
+ *Effects:* Allocates memory suitable for holding an array of `n` objects
4216
+ of type `T`, as follows:
4217
+
4218
+ - if `numeric_limits<size_t>::max() / sizeof(T) < n`, throws
4219
+ `bad_array_new_length`,
4220
+ - otherwise equivalent to:
4221
+ ``` cpp
4222
+ return static_cast<T*>(allocate_bytes(n*sizeof(T), alignof(T)));
4223
+ ```
4224
+
4225
+ [*Note 2*: `T` is not deduced and must therefore be provided as a
4226
+ template argument. — *end note*]
4227
+
4228
+ ``` cpp
4229
+ template<class T>
4230
+ void deallocate_object(T* p, size_t n = 1);
4231
+ ```
4232
+
4233
+ *Effects:* Equivalent to `deallocate_bytes(p, n*sizeof(T), alignof(T))`.
4234
+
4235
+ ``` cpp
4236
+ template<class T, class... CtorArgs>
4237
+ [[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
4238
+ ```
4239
+
4240
+ *Effects:* Allocates and constructs an object of type `T`, as follows.
4241
+ Equivalent to:
4242
+
4243
+ ``` cpp
4244
+ T* p = allocate_object<T>();
4245
+ try {
4246
+ construct(p, std::forward<CtorArgs>(ctor_args)...);
4247
+ } catch (...) {
4248
+ deallocate_object(p);
4249
+ throw;
4250
+ }
4251
+ return p;
4252
+ ```
4253
+
4254
+ [*Note 3*: `T` is not deduced and must therefore be provided as a
4255
+ template argument. — *end note*]
4256
+
4257
+ ``` cpp
4258
+ template<class T>
4259
+ void delete_object(T* p);
4260
+ ```
4261
+
4262
+ *Effects:* Equivalent to:
4263
+
4264
+ ``` cpp
4265
+ allocator_traits<polymorphic_allocator>::destroy(*this, p);
4266
+ deallocate_object(p);
4267
+ ```
4268
+
4269
+ ``` cpp
4270
+ template<class T, class... Args>
4271
+ void construct(T* p, Args&&... args);
4272
+ ```
4273
+
4274
+ *Mandates:* Uses-allocator construction of `T` with allocator `*this`
4275
+ (see  [[allocator.uses.construction]]) and constructor arguments
4276
+ `std::forward<Args>(args)...` is well-formed.
4277
+
4278
+ *Effects:* Construct a `T` object in the storage whose address is
4279
+ represented by `p` by uses-allocator construction with allocator `*this`
4280
+ and constructor arguments `std::forward<Args>(args)...`.
4281
+
4282
+ *Throws:* Nothing unless the constructor for `T` throws.
4283
+
4284
+ ``` cpp
4285
+ polymorphic_allocator select_on_container_copy_construction() const;
4286
+ ```
4287
+
4288
+ *Returns:* `polymorphic_allocator()`.
4289
+
4290
+ [*Note 4*: The memory resource is not propagated. — *end note*]
4291
+
4292
+ ``` cpp
4293
+ memory_resource* resource() const;
4294
+ ```
4295
+
4296
+ *Returns:* `memory_rsrc`.
4297
+
4298
+ #### Equality <a id="mem.poly.allocator.eq">[[mem.poly.allocator.eq]]</a>
4299
+
4300
+ ``` cpp
4301
+ template<class T1, class T2>
4302
+ bool operator==(const polymorphic_allocator<T1>& a,
4303
+ const polymorphic_allocator<T2>& b) noexcept;
4304
+ ```
4305
+
4306
+ *Returns:* `*a.resource() == *b.resource()`.
4307
+
4308
+ ### Access to program-wide `memory_resource` objects <a id="mem.res.global">[[mem.res.global]]</a>
4309
+
4310
+ ``` cpp
4311
+ memory_resource* new_delete_resource() noexcept;
4312
+ ```
4313
+
4314
+ *Returns:* A pointer to a static-duration object of a type derived from
4315
+ `memory_resource` that can serve as a resource for allocating memory
4316
+ using `::operator new` and `::operator delete`. The same value is
4317
+ returned every time this function is called. For a return value `p` and
4318
+ a memory resource `r`, `p->is_equal(r)` returns `&r == p`.
4319
+
4320
+ ``` cpp
4321
+ memory_resource* null_memory_resource() noexcept;
4322
+ ```
4323
+
4324
+ *Returns:* A pointer to a static-duration object of a type derived from
4325
+ `memory_resource` for which `allocate()` always throws `bad_alloc` and
4326
+ for which `deallocate()` has no effect. The same value is returned every
4327
+ time this function is called. For a return value `p` and a memory
4328
+ resource `r`, `p->is_equal(r)` returns `&r == p`.
4329
+
4330
+ The *default memory resource pointer* is a pointer to a memory resource
4331
+ that is used by certain facilities when an explicit memory resource is
4332
+ not supplied through the interface. Its initial value is the return
4333
+ value of `new_delete_resource()`.
4334
+
4335
+ ``` cpp
4336
+ memory_resource* set_default_resource(memory_resource* r) noexcept;
4337
+ ```
4338
+
4339
+ *Effects:* If `r` is non-null, sets the value of the default memory
4340
+ resource pointer to `r`, otherwise sets the default memory resource
4341
+ pointer to `new_delete_resource()`.
4342
+
4343
+ *Returns:* The previous value of the default memory resource pointer.
4344
+
4345
+ *Remarks:* Calling the `set_default_resource` and `get_default_resource`
4346
+ functions shall not incur a data race. A call to the
4347
+ `set_default_resource` function shall synchronize with subsequent calls
4348
+ to the `set_default_resource` and `get_default_resource` functions.
4349
+
4350
+ ``` cpp
4351
+ memory_resource* get_default_resource() noexcept;
4352
+ ```
4353
+
4354
+ *Returns:* The current value of the default memory resource pointer.
4355
+
4356
+ ### Pool resource classes <a id="mem.res.pool">[[mem.res.pool]]</a>
4357
+
4358
+ #### Classes `synchronized_pool_resource` and `unsynchronized_pool_resource` <a id="mem.res.pool.overview">[[mem.res.pool.overview]]</a>
4359
+
4360
+ The `synchronized_pool_resource` and `unsynchronized_pool_resource`
4361
+ classes (collectively called *pool resource classes*) are
4362
+ general-purpose memory resources having the following qualities:
4363
+
4364
+ - Each resource frees its allocated memory on destruction, even if
4365
+ `deallocate` has not been called for some of the allocated blocks.
4366
+ - A pool resource consists of a collection of *pools*, serving requests
4367
+ for different block sizes. Each individual pool manages a collection
4368
+ of *chunks* that are in turn divided into blocks of uniform size,
4369
+ returned via calls to `do_allocate`. Each call to
4370
+ `do_allocate(size, alignment)` is dispatched to the pool serving the
4371
+ smallest blocks accommodating at least `size` bytes.
4372
+ - When a particular pool is exhausted, allocating a block from that pool
4373
+ results in the allocation of an additional chunk of memory from the
4374
+ *upstream allocator* (supplied at construction), thus replenishing the
4375
+ pool. With each successive replenishment, the chunk size obtained
4376
+ increases geometrically. \[*Note 1*: By allocating memory in chunks,
4377
+ the pooling strategy increases the chance that consecutive allocations
4378
+ will be close together in memory. — *end note*]
4379
+ - Allocation requests that exceed the largest block size of any pool are
4380
+ fulfilled directly from the upstream allocator.
4381
+ - A `pool_options` struct may be passed to the pool resource
4382
+ constructors to tune the largest block size and the maximum chunk
4383
+ size.
4384
+
4385
+ A `synchronized_pool_resource` may be accessed from multiple threads
4386
+ without external synchronization and may have thread-specific pools to
4387
+ reduce synchronization costs. An `unsynchronized_pool_resource` class
4388
+ may not be accessed from multiple threads simultaneously and thus avoids
4389
+ the cost of synchronization entirely in single-threaded applications.
4390
+
4391
+ ``` cpp
4392
+ namespace std::pmr {
4393
+ struct pool_options {
4394
+ size_t max_blocks_per_chunk = 0;
4395
+ size_t largest_required_pool_block = 0;
4396
+ };
4397
+
4398
+ class synchronized_pool_resource : public memory_resource {
4399
+ public:
4400
+ synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
4401
+
4402
+ synchronized_pool_resource()
4403
+ : synchronized_pool_resource(pool_options(), get_default_resource()) {}
4404
+ explicit synchronized_pool_resource(memory_resource* upstream)
4405
+ : synchronized_pool_resource(pool_options(), upstream) {}
4406
+ explicit synchronized_pool_resource(const pool_options& opts)
4407
+ : synchronized_pool_resource(opts, get_default_resource()) {}
4408
+
4409
+ synchronized_pool_resource(const synchronized_pool_resource&) = delete;
4410
+ virtual ~synchronized_pool_resource();
4411
+
4412
+ synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete;
4413
+
4414
+ void release();
4415
+ memory_resource* upstream_resource() const;
4416
+ pool_options options() const;
4417
+
4418
+ protected:
4419
+ void* do_allocate(size_t bytes, size_t alignment) override;
4420
+ void do_deallocate(void* p, size_t bytes, size_t alignment) override;
4421
+
4422
+ bool do_is_equal(const memory_resource& other) const noexcept override;
4423
+ };
4424
+
4425
+ class unsynchronized_pool_resource : public memory_resource {
4426
+ public:
4427
+ unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
4428
+
4429
+ unsynchronized_pool_resource()
4430
+ : unsynchronized_pool_resource(pool_options(), get_default_resource()) {}
4431
+ explicit unsynchronized_pool_resource(memory_resource* upstream)
4432
+ : unsynchronized_pool_resource(pool_options(), upstream) {}
4433
+ explicit unsynchronized_pool_resource(const pool_options& opts)
4434
+ : unsynchronized_pool_resource(opts, get_default_resource()) {}
4435
+
4436
+ unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete;
4437
+ virtual ~unsynchronized_pool_resource();
4438
+
4439
+ unsynchronized_pool_resource& operator=(const unsynchronized_pool_resource&) = delete;
4440
+
4441
+ void release();
4442
+ memory_resource* upstream_resource() const;
4443
+ pool_options options() const;
4444
+
4445
+ protected:
4446
+ void* do_allocate(size_t bytes, size_t alignment) override;
4447
+ void do_deallocate(void* p, size_t bytes, size_t alignment) override;
4448
+
4449
+ bool do_is_equal(const memory_resource& other) const noexcept override;
4450
+ };
4451
+ }
4452
+ ```
4453
+
4454
+ #### `pool_options` data members <a id="mem.res.pool.options">[[mem.res.pool.options]]</a>
4455
+
4456
+ The members of `pool_options` comprise a set of constructor options for
4457
+ pool resources. The effect of each option on the pool resource behavior
4458
+ is described below:
4459
+
4460
+ ``` cpp
4461
+ size_t max_blocks_per_chunk;
4462
+ ```
4463
+
4464
+ The maximum number of blocks that will be allocated at once from the
4465
+ upstream memory resource [[mem.res.monotonic.buffer]] to replenish a
4466
+ pool. If the value of `max_blocks_per_chunk` is zero or is greater than
4467
+ an *implementation-defined* limit, that limit is used instead. The
4468
+ implementation may choose to use a smaller value than is specified in
4469
+ this field and may use different values for different pools.
4470
+
4471
+ ``` cpp
4472
+ size_t largest_required_pool_block;
4473
+ ```
4474
+
4475
+ The largest allocation size that is required to be fulfilled using the
4476
+ pooling mechanism. Attempts to allocate a single block larger than this
4477
+ threshold will be allocated directly from the upstream memory resource.
4478
+ If `largest_required_pool_block` is zero or is greater than an
4479
+ *implementation-defined* limit, that limit is used instead. The
4480
+ implementation may choose a pass-through threshold larger than specified
4481
+ in this field.
4482
+
4483
+ #### Constructors and destructors <a id="mem.res.pool.ctor">[[mem.res.pool.ctor]]</a>
4484
+
4485
+ ``` cpp
4486
+ synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
4487
+ unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
4488
+ ```
4489
+
4490
+ *Preconditions:* `upstream` is the address of a valid memory resource.
4491
+
4492
+ *Effects:* Constructs a pool resource object that will obtain memory
4493
+ from `upstream` whenever the pool resource is unable to satisfy a memory
4494
+ request from its own internal data structures. The resulting object will
4495
+ hold a copy of `upstream`, but will not own the resource to which
4496
+ `upstream` points.
4497
+
4498
+ [*Note 1*: The intention is that calls to `upstream->allocate()` will
4499
+ be substantially fewer than calls to `this->allocate()` in most
4500
+ cases. — *end note*]
4501
+
4502
+ The behavior of the pooling mechanism is tuned according to the value of
4503
+ the `opts` argument.
4504
+
4505
+ *Throws:* Nothing unless `upstream->allocate()` throws. It is
4506
+ unspecified if, or under what conditions, this constructor calls
4507
+ `upstream->allocate()`.
4508
+
4509
+ ``` cpp
4510
+ virtual ~synchronized_pool_resource();
4511
+ virtual ~unsynchronized_pool_resource();
4512
+ ```
4513
+
4514
+ *Effects:* Calls `release()`.
4515
+
4516
+ #### Members <a id="mem.res.pool.mem">[[mem.res.pool.mem]]</a>
4517
+
4518
+ ``` cpp
4519
+ void release();
4520
+ ```
4521
+
4522
+ *Effects:* Calls `upstream_resource()->deallocate()` as necessary to
4523
+ release all allocated memory.
4524
+
4525
+ [*Note 1*: The memory is released back to `upstream_resource()` even if
4526
+ `deallocate` has not been called for some of the allocated
4527
+ blocks. — *end note*]
4528
+
4529
+ ``` cpp
4530
+ memory_resource* upstream_resource() const;
4531
+ ```
4532
+
4533
+ *Returns:* The value of the `upstream` argument provided to the
4534
+ constructor of this object.
4535
+
4536
+ ``` cpp
4537
+ pool_options options() const;
4538
+ ```
4539
+
4540
+ *Returns:* The options that control the pooling behavior of this
4541
+ resource. The values in the returned struct may differ from those
4542
+ supplied to the pool resource constructor in that values of zero will be
4543
+ replaced with *implementation-defined* defaults, and sizes may be
4544
+ rounded to unspecified granularity.
4545
+
4546
+ ``` cpp
4547
+ void* do_allocate(size_t bytes, size_t alignment) override;
4548
+ ```
4549
+
4550
+ *Effects:* If the pool selected for a block of size `bytes` is unable to
4551
+ satisfy the memory request from its own internal data structures, it
4552
+ will call `upstream_resource()->allocate()` to obtain more memory. If
4553
+ `bytes` is larger than that which the largest pool can handle, then
4554
+ memory will be allocated using `upstream_resource()->allocate()`.
4555
+
4556
+ *Returns:* A pointer to allocated
4557
+ storage [[basic.stc.dynamic.allocation]] with a size of at least
4558
+ `bytes`. The size and alignment of the allocated memory shall meet the
4559
+ requirements for a class derived from `memory_resource`
4560
+ [[mem.res.class]].
4561
+
4562
+ *Throws:* Nothing unless `upstream_resource()->allocate()` throws.
4563
+
4564
+ ``` cpp
4565
+ void do_deallocate(void* p, size_t bytes, size_t alignment) override;
4566
+ ```
4567
+
4568
+ *Effects:* Returns the memory at `p` to the pool. It is unspecified if,
4569
+ or under what circumstances, this operation will result in a call to
4570
+ `upstream_resource()->deallocate()`.
4571
+
4572
+ *Throws:* Nothing.
4573
+
4574
+ ``` cpp
4575
+ bool do_is_equal(const memory_resource& other) const noexcept override;
4576
+ ```
4577
+
4578
+ *Returns:* `this == &other`.
4579
+
4580
+ ### Class `monotonic_buffer_resource` <a id="mem.res.monotonic.buffer">[[mem.res.monotonic.buffer]]</a>
4581
+
4582
+ #### General <a id="mem.res.monotonic.buffer.general">[[mem.res.monotonic.buffer.general]]</a>
4583
+
4584
+ A `monotonic_buffer_resource` is a special-purpose memory resource
4585
+ intended for very fast memory allocations in situations where memory is
4586
+ used to build up a few objects and then is released all at once when the
4587
+ memory resource object is destroyed.
4588
+
4589
+ ``` cpp
4590
+ namespace std::pmr {
4591
+ class monotonic_buffer_resource : public memory_resource {
4592
+ memory_resource* upstream_rsrc; // exposition only
4593
+ void* current_buffer; // exposition only
4594
+ size_t next_buffer_size; // exposition only
4595
+
4596
+ public:
4597
+ explicit monotonic_buffer_resource(memory_resource* upstream);
4598
+ monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
4599
+ monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);
4600
+
4601
+ monotonic_buffer_resource()
4602
+ : monotonic_buffer_resource(get_default_resource()) {}
4603
+ explicit monotonic_buffer_resource(size_t initial_size)
4604
+ : monotonic_buffer_resource(initial_size, get_default_resource()) {}
4605
+ monotonic_buffer_resource(void* buffer, size_t buffer_size)
4606
+ : monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {}
4607
+
4608
+ monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
4609
+
4610
+ virtual ~monotonic_buffer_resource();
4611
+
4612
+ monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete;
4613
+
4614
+ void release();
4615
+ memory_resource* upstream_resource() const;
4616
+
4617
+ protected:
4618
+ void* do_allocate(size_t bytes, size_t alignment) override;
4619
+ void do_deallocate(void* p, size_t bytes, size_t alignment) override;
4620
+
4621
+ bool do_is_equal(const memory_resource& other) const noexcept override;
4622
+ };
4623
+ }
4624
+ ```
4625
+
4626
+ #### Constructors and destructor <a id="mem.res.monotonic.buffer.ctor">[[mem.res.monotonic.buffer.ctor]]</a>
4627
+
4628
+ ``` cpp
4629
+ explicit monotonic_buffer_resource(memory_resource* upstream);
4630
+ monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
4631
+ ```
4632
+
4633
+ *Preconditions:* `upstream` is the address of a valid memory resource.
4634
+ `initial_size`, if specified, is greater than zero.
4635
+
4636
+ *Effects:* Sets `upstream_rsrc` to `upstream` and `current_buffer` to
4637
+ `nullptr`. If `initial_size` is specified, sets `next_buffer_size` to at
4638
+ least `initial_size`; otherwise sets `next_buffer_size` to an
4639
+ *implementation-defined* size.
4640
+
4641
+ ``` cpp
4642
+ monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);
4643
+ ```
4644
+
4645
+ *Preconditions:* `upstream` is the address of a valid memory resource.
4646
+ `buffer_size` is no larger than the number of bytes in `buffer`.
4647
+
4648
+ *Effects:* Sets `upstream_rsrc` to `upstream`, `current_buffer` to
4649
+ `buffer`, and `next_buffer_size` to `buffer_size` (but not less than 1),
4650
+ then increases `next_buffer_size` by an *implementation-defined* growth
4651
+ factor (which need not be integral).
4652
+
4653
+ ``` cpp
4654
+ ~monotonic_buffer_resource();
4655
+ ```
4656
+
4657
+ *Effects:* Calls `release()`.
4658
+
4659
+ #### Members <a id="mem.res.monotonic.buffer.mem">[[mem.res.monotonic.buffer.mem]]</a>
4660
+
4661
+ ``` cpp
4662
+ void release();
4663
+ ```
4664
+
4665
+ *Effects:* Calls `upstream_rsrc->deallocate()` as necessary to release
4666
+ all allocated memory. Resets `current_buffer` and `next_buffer_size` to
4667
+ their initial values at construction.
4668
+
4669
+ [*Note 1*: The memory is released back to `upstream_rsrc` even if some
4670
+ blocks that were allocated from `this` have not been deallocated from
4671
+ `this`. — *end note*]
4672
+
4673
+ ``` cpp
4674
+ memory_resource* upstream_resource() const;
4675
+ ```
4676
+
4677
+ *Returns:* The value of `upstream_rsrc`.
4678
+
4679
+ ``` cpp
4680
+ void* do_allocate(size_t bytes, size_t alignment) override;
4681
+ ```
4682
+
4683
+ *Effects:* If the unused space in `current_buffer` can fit a block with
4684
+ the specified `bytes` and `alignment`, then allocate the return block
4685
+ from `current_buffer`; otherwise set `current_buffer` to
4686
+ `upstream_rsrc->allocate(n, m)`, where `n` is not less than
4687
+ `max(bytes, next_buffer_size)` and `m` is not less than `alignment`, and
4688
+ increase `next_buffer_size` by an *implementation-defined* growth factor
4689
+ (which need not be integral), then allocate the return block from the
4690
+ newly-allocated `current_buffer`.
4691
+
4692
+ *Returns:* A pointer to allocated
4693
+ storage [[basic.stc.dynamic.allocation]] with a size of at least
4694
+ `bytes`. The size and alignment of the allocated memory shall meet the
4695
+ requirements for a class derived from `memory_resource`
4696
+ [[mem.res.class]].
4697
+
4698
+ *Throws:* Nothing unless `upstream_rsrc->allocate()` throws.
4699
+
4700
+ ``` cpp
4701
+ void do_deallocate(void* p, size_t bytes, size_t alignment) override;
4702
+ ```
4703
+
4704
+ *Effects:* None.
4705
+
4706
+ *Throws:* Nothing.
4707
+
4708
+ *Remarks:* Memory used by this resource increases monotonically until
4709
+ its destruction.
4710
+
4711
+ ``` cpp
4712
+ bool do_is_equal(const memory_resource& other) const noexcept override;
4713
+ ```
4714
+
4715
+ *Returns:* `this == &other`.
4716
+
4717
+ ## Class template `scoped_allocator_adaptor` <a id="allocator.adaptor">[[allocator.adaptor]]</a>
4718
+
4719
+ ### Header `<scoped_allocator>` synopsis <a id="allocator.adaptor.syn">[[allocator.adaptor.syn]]</a>
4720
+
4721
+ ``` cpp
4722
+ namespace std {
4723
+ // class template scoped_allocator_adaptor
4724
+ template<class OuterAlloc, class... InnerAlloc>
4725
+ class scoped_allocator_adaptor;
4726
+
4727
+ // [scoped.adaptor.operators], scoped allocator operators
4728
+ template<class OuterA1, class OuterA2, class... InnerAllocs>
4729
+ bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
4730
+ const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
4731
+ }
4732
+ ```
4733
+
4734
+ The class template `scoped_allocator_adaptor` is an allocator template
4735
+ that specifies an allocator resource (the outer allocator) to be used by
4736
+ a container (as any other allocator does) and also specifies an inner
4737
+ allocator resource to be passed to the constructor of every element
4738
+ within the container. This adaptor is instantiated with one outer and
4739
+ zero or more inner allocator types. If instantiated with only one
4740
+ allocator type, the inner allocator becomes the
4741
+ `scoped_allocator_adaptor` itself, thus using the same allocator
4742
+ resource for the container and every element within the container and,
4743
+ if the elements themselves are containers, each of their elements
4744
+ recursively. If instantiated with more than one allocator, the first
4745
+ allocator is the outer allocator for use by the container, the second
4746
+ allocator is passed to the constructors of the container’s elements,
4747
+ and, if the elements themselves are containers, the third allocator is
4748
+ passed to the elements’ elements, and so on. If containers are nested to
4749
+ a depth greater than the number of allocators, the last allocator is
4750
+ used repeatedly, as in the single-allocator case, for any remaining
4751
+ recursions.
4752
+
4753
+ [*Note 1*: The `scoped_allocator_adaptor` is derived from the outer
4754
+ allocator type so it can be substituted for the outer allocator type in
4755
+ most expressions. — *end note*]
4756
+
4757
+ ``` cpp
4758
+ namespace std {
4759
+ template<class OuterAlloc, class... InnerAllocs>
4760
+ class scoped_allocator_adaptor : public OuterAlloc {
4761
+ private:
4762
+ using OuterTraits = allocator_traits<OuterAlloc>; // exposition only
4763
+ scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only
4764
+
4765
+ public:
4766
+ using outer_allocator_type = OuterAlloc;
4767
+ using inner_allocator_type = see below;
4768
+
4769
+ using value_type = typename OuterTraits::value_type;
4770
+ using size_type = typename OuterTraits::size_type;
4771
+ using difference_type = typename OuterTraits::difference_type;
4772
+ using pointer = typename OuterTraits::pointer;
4773
+ using const_pointer = typename OuterTraits::const_pointer;
4774
+ using void_pointer = typename OuterTraits::void_pointer;
4775
+ using const_void_pointer = typename OuterTraits::const_void_pointer;
4776
+
4777
+ using propagate_on_container_copy_assignment = see below;
4778
+ using propagate_on_container_move_assignment = see below;
4779
+ using propagate_on_container_swap = see below;
4780
+ using is_always_equal = see below;
4781
+
4782
+ template<class Tp> struct rebind {
4783
+ using other = scoped_allocator_adaptor<
4784
+ OuterTraits::template rebind_alloc<Tp>, InnerAllocs...>;
4785
+ };
4786
+
4787
+ scoped_allocator_adaptor();
4788
+ template<class OuterA2>
4789
+ scoped_allocator_adaptor(OuterA2&& outerAlloc,
4790
+ const InnerAllocs&... innerAllocs) noexcept;
4791
+
4792
+ scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
4793
+ scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
4794
+
4795
+ template<class OuterA2>
4796
+ scoped_allocator_adaptor(
4797
+ const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
4798
+ template<class OuterA2>
4799
+ scoped_allocator_adaptor(
4800
+ scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
4801
+
4802
+ scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
4803
+ scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
4804
+
4805
+ ~scoped_allocator_adaptor();
4806
+
4807
+ inner_allocator_type& inner_allocator() noexcept;
4808
+ const inner_allocator_type& inner_allocator() const noexcept;
4809
+ outer_allocator_type& outer_allocator() noexcept;
4810
+ const outer_allocator_type& outer_allocator() const noexcept;
4811
+
4812
+ [[nodiscard]] pointer allocate(size_type n);
4813
+ [[nodiscard]] pointer allocate(size_type n, const_void_pointer hint);
4814
+ void deallocate(pointer p, size_type n);
4815
+ size_type max_size() const;
4816
+
4817
+ template<class T, class... Args>
4818
+ void construct(T* p, Args&&... args);
4819
+
4820
+ template<class T>
4821
+ void destroy(T* p);
4822
+
4823
+ scoped_allocator_adaptor select_on_container_copy_construction() const;
4824
+ };
4825
+
4826
+ template<class OuterAlloc, class... InnerAllocs>
4827
+ scoped_allocator_adaptor(OuterAlloc, InnerAllocs...)
4828
+ -> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
4829
+ }
4830
+ ```
4831
+
4832
+ ### Member types <a id="allocator.adaptor.types">[[allocator.adaptor.types]]</a>
4833
+
4834
+ ``` cpp
4835
+ using inner_allocator_type = see below;
4836
+ ```
4837
+
4838
+ *Type:* `scoped_allocator_adaptor<OuterAlloc>` if
4839
+ `sizeof...(InnerAllocs)` is zero; otherwise,
4840
+ `scoped_allocator_adaptor<InnerAllocs...>`.
4841
+
4842
+ ``` cpp
4843
+ using propagate_on_container_copy_assignment = see below;
4844
+ ```
4845
+
4846
+ *Type:* `true_type` if
4847
+ `allocator_traits<A>::propagate_on_container_copy_assignment::value` is
4848
+ `true` for any `A` in the set of `OuterAlloc` and `InnerAllocs...`;
4849
+ otherwise, `false_type`.
4850
+
4851
+ ``` cpp
4852
+ using propagate_on_container_move_assignment = see below;
4853
+ ```
4854
+
4855
+ *Type:* `true_type` if
4856
+ `allocator_traits<A>::propagate_on_container_move_assignment::value` is
4857
+ `true` for any `A` in the set of `OuterAlloc` and `InnerAllocs...`;
4858
+ otherwise, `false_type`.
4859
+
4860
+ ``` cpp
4861
+ using propagate_on_container_swap = see below;
4862
+ ```
4863
+
4864
+ *Type:* `true_type` if
4865
+ `allocator_traits<A>::propagate_on_container_swap::value` is `true` for
4866
+ any `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise,
4867
+ `false_type`.
4868
+
4869
+ ``` cpp
4870
+ using is_always_equal = see below;
4871
+ ```
4872
+
4873
+ *Type:* `true_type` if `allocator_traits<A>::is_always_equal::value` is
4874
+ `true` for every `A` in the set of `OuterAlloc` and `InnerAllocs...`;
4875
+ otherwise, `false_type`.
4876
+
4877
+ ### Constructors <a id="allocator.adaptor.cnstr">[[allocator.adaptor.cnstr]]</a>
4878
+
4879
+ ``` cpp
4880
+ scoped_allocator_adaptor();
4881
+ ```
4882
+
4883
+ *Effects:* Value-initializes the `OuterAlloc` base class and the `inner`
4884
+ allocator object.
4885
+
4886
+ ``` cpp
4887
+ template<class OuterA2>
4888
+ scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept;
4889
+ ```
4890
+
4891
+ *Constraints:* `is_constructible_v<OuterAlloc, OuterA2>` is `true`.
4892
+
4893
+ *Effects:* Initializes the `OuterAlloc` base class with
4894
+ `std::forward<OuterA2>(outerAlloc)` and `inner` with `innerAllocs...`
4895
+ (hence recursively initializing each allocator within the adaptor with
4896
+ the corresponding allocator from the argument list).
4897
+
4898
+ ``` cpp
4899
+ scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
4900
+ ```
4901
+
4902
+ *Effects:* Initializes each allocator within the adaptor with the
4903
+ corresponding allocator from `other`.
4904
+
4905
+ ``` cpp
4906
+ scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
4907
+ ```
4908
+
4909
+ *Effects:* Move constructs each allocator within the adaptor with the
4910
+ corresponding allocator from `other`.
4911
+
4912
+ ``` cpp
4913
+ template<class OuterA2>
4914
+ scoped_allocator_adaptor(
4915
+ const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
4916
+ ```
4917
+
4918
+ *Constraints:* `is_constructible_v<OuterAlloc, const OuterA2&>` is
4919
+ `true`.
4920
+
4921
+ *Effects:* Initializes each allocator within the adaptor with the
4922
+ corresponding allocator from `other`.
4923
+
4924
+ ``` cpp
4925
+ template<class OuterA2>
4926
+ scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
4927
+ ```
4928
+
4929
+ *Constraints:* `is_constructible_v<OuterAlloc, OuterA2>` is `true`.
4930
+
4931
+ *Effects:* Initializes each allocator within the adaptor with the
4932
+ corresponding allocator rvalue from `other`.
4933
+
4934
+ ### Members <a id="allocator.adaptor.members">[[allocator.adaptor.members]]</a>
4935
+
4936
+ In the `construct` member functions, `OUTERMOST(x)` is
4937
+ `OUTERMOST(x.outer_allocator())` if the expression `x.outer_allocator()`
4938
+ is valid  [[temp.deduct]] and `x` otherwise; `OUTERMOST_ALLOC_TRAITS(x)`
4939
+ is `allocator_traits<remove_reference_t<decltype(OUTERMOST(x))>>`.
4940
+
4941
+ [*Note 1*: `OUTERMOST(x)` and `OUTERMOST_ALLOC_TRAITS(x)` are recursive
4942
+ operations. It is incumbent upon the definition of `outer_allocator()`
4943
+ to ensure that the recursion terminates. It will terminate for all
4944
+ instantiations of `scoped_allocator_adaptor`. — *end note*]
4945
+
4946
+ ``` cpp
4947
+ inner_allocator_type& inner_allocator() noexcept;
4948
+ const inner_allocator_type& inner_allocator() const noexcept;
4949
+ ```
4950
+
4951
+ *Returns:* `*this` if `sizeof...(InnerAllocs)` is zero; otherwise,
4952
+ `inner`.
4953
+
4954
+ ``` cpp
4955
+ outer_allocator_type& outer_allocator() noexcept;
4956
+ ```
4957
+
4958
+ *Returns:* `static_cast<OuterAlloc&>(*this)`.
4959
+
4960
+ ``` cpp
4961
+ const outer_allocator_type& outer_allocator() const noexcept;
4962
+ ```
4963
+
4964
+ *Returns:* `static_cast<const OuterAlloc&>(*this)`.
4965
+
4966
+ ``` cpp
4967
+ [[nodiscard]] pointer allocate(size_type n);
4968
+ ```
4969
+
4970
+ *Returns:*
4971
+ `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)`.
4972
+
4973
+ ``` cpp
4974
+ [[nodiscard]] pointer allocate(size_type n, const_void_pointer hint);
4975
+ ```
4976
+
4977
+ *Returns:*
4978
+ `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)`.
4979
+
4980
+ ``` cpp
4981
+ void deallocate(pointer p, size_type n) noexcept;
4982
+ ```
4983
+
4984
+ *Effects:* As if by:
4985
+ `allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n);`
4986
+
4987
+ ``` cpp
4988
+ size_type max_size() const;
4989
+ ```
4990
+
4991
+ *Returns:* `allocator_traits<OuterAlloc>::max_size(outer_allocator())`.
4992
+
4993
+ ``` cpp
4994
+ template<class T, class... Args>
4995
+ void construct(T* p, Args&&... args);
4996
+ ```
4997
+
4998
+ *Effects:* Equivalent to:
4999
+
5000
+ ``` cpp
5001
+ apply([p, this](auto&&... newargs) {
5002
+ OUTERMOST_ALLOC_TRAITS(*this)::construct(
5003
+ OUTERMOST(*this), p,
5004
+ std::forward<decltype(newargs)>(newargs)...);
5005
+ },
5006
+ uses_allocator_construction_args<T>(inner_allocator(),
5007
+ std::forward<Args>(args)...));
5008
+ ```
5009
+
5010
+ ``` cpp
5011
+ template<class T>
5012
+ void destroy(T* p);
5013
+ ```
5014
+
5015
+ *Effects:* Calls
5016
+ *OUTERMOST_ALLOC_TRAITS*(\*this)::destroy(*OUTERMOST*(\*this), p).
5017
+
5018
+ ``` cpp
5019
+ scoped_allocator_adaptor select_on_container_copy_construction() const;
5020
+ ```
5021
+
5022
+ *Returns:* A new `scoped_allocator_adaptor` object where each allocator
5023
+ `a1` within the adaptor is initialized with
5024
+ `allocator_traits<A1>::select_on_container_copy_construction(a2)`, where
5025
+ `A1` is the type of `a1` and `a2` is the corresponding allocator in
5026
+ `*this`.
5027
+
5028
+ ### Operators <a id="scoped.adaptor.operators">[[scoped.adaptor.operators]]</a>
5029
+
5030
+ ``` cpp
5031
+ template<class OuterA1, class OuterA2, class... InnerAllocs>
5032
+ bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
5033
+ const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
5034
+ ```
5035
+
5036
+ *Returns:* If `sizeof...(InnerAllocs)` is zero,
5037
+
5038
+ ``` cpp
5039
+ a.outer_allocator() == b.outer_allocator()
5040
+ ```
5041
+
5042
+ otherwise
5043
+
5044
+ ``` cpp
5045
+ a.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_allocator()
5046
+ ```
5047
+
5048
+ <!-- Link reference definitions -->
5049
+ [alg.sorting]: algorithms.md#alg.sorting
5050
+ [allocator.adaptor]: #allocator.adaptor
5051
+ [allocator.adaptor.cnstr]: #allocator.adaptor.cnstr
5052
+ [allocator.adaptor.members]: #allocator.adaptor.members
5053
+ [allocator.adaptor.syn]: #allocator.adaptor.syn
5054
+ [allocator.adaptor.types]: #allocator.adaptor.types
5055
+ [allocator.globals]: #allocator.globals
5056
+ [allocator.members]: #allocator.members
5057
+ [allocator.requirements.completeness]: library.md#allocator.requirements.completeness
5058
+ [allocator.requirements.general]: library.md#allocator.requirements.general
5059
+ [allocator.tag]: #allocator.tag
5060
+ [allocator.traits]: #allocator.traits
5061
+ [allocator.traits.general]: #allocator.traits.general
5062
+ [allocator.traits.members]: #allocator.traits.members
5063
+ [allocator.traits.other]: #allocator.traits.other
5064
+ [allocator.traits.types]: #allocator.traits.types
5065
+ [allocator.uses]: #allocator.uses
5066
+ [allocator.uses.construction]: #allocator.uses.construction
5067
+ [allocator.uses.trait]: #allocator.uses.trait
5068
+ [basic.align]: basic.md#basic.align
5069
+ [basic.compound]: basic.md#basic.compound
5070
+ [basic.stc.dynamic.allocation]: basic.md#basic.stc.dynamic.allocation
5071
+ [basic.types.general]: basic.md#basic.types.general
5072
+ [bit.cast]: utilities.md#bit.cast
5073
+ [c.malloc]: #c.malloc
5074
+ [conv.qual]: expr.md#conv.qual
5075
+ [cpp17.defaultconstructible]: #cpp17.defaultconstructible
5076
+ [cpp17.destructible]: #cpp17.destructible
5077
+ [cpp17.moveassignable]: #cpp17.moveassignable
5078
+ [cpp17.moveconstructible]: #cpp17.moveconstructible
5079
+ [cpp17.nullablepointer]: #cpp17.nullablepointer
5080
+ [default.allocator]: #default.allocator
5081
+ [default.allocator.general]: #default.allocator.general
5082
+ [defns.const.subexpr]: intro.md#defns.const.subexpr
5083
+ [expr.eq]: expr.md#expr.eq
5084
+ [function.objects]: utilities.md#function.objects
5085
+ [inout.ptr]: #inout.ptr
5086
+ [inout.ptr.t]: #inout.ptr.t
5087
+ [intro.multithread]: basic.md#intro.multithread
5088
+ [intro.object]: basic.md#intro.object
5089
+ [intro.races]: basic.md#intro.races
5090
+ [mem]: #mem
5091
+ [mem.general]: #mem.general
5092
+ [mem.poly.allocator.class]: #mem.poly.allocator.class
5093
+ [mem.poly.allocator.class.general]: #mem.poly.allocator.class.general
5094
+ [mem.poly.allocator.ctor]: #mem.poly.allocator.ctor
5095
+ [mem.poly.allocator.eq]: #mem.poly.allocator.eq
5096
+ [mem.poly.allocator.mem]: #mem.poly.allocator.mem
5097
+ [mem.res]: #mem.res
5098
+ [mem.res.class]: #mem.res.class
5099
+ [mem.res.class.general]: #mem.res.class.general
5100
+ [mem.res.eq]: #mem.res.eq
5101
+ [mem.res.global]: #mem.res.global
5102
+ [mem.res.monotonic.buffer]: #mem.res.monotonic.buffer
5103
+ [mem.res.monotonic.buffer.ctor]: #mem.res.monotonic.buffer.ctor
5104
+ [mem.res.monotonic.buffer.general]: #mem.res.monotonic.buffer.general
5105
+ [mem.res.monotonic.buffer.mem]: #mem.res.monotonic.buffer.mem
5106
+ [mem.res.pool]: #mem.res.pool
5107
+ [mem.res.pool.ctor]: #mem.res.pool.ctor
5108
+ [mem.res.pool.mem]: #mem.res.pool.mem
5109
+ [mem.res.pool.options]: #mem.res.pool.options
5110
+ [mem.res.pool.overview]: #mem.res.pool.overview
5111
+ [mem.res.private]: #mem.res.private
5112
+ [mem.res.public]: #mem.res.public
5113
+ [mem.res.syn]: #mem.res.syn
5114
+ [mem.summary]: #mem.summary
5115
+ [memory]: #memory
5116
+ [memory.general]: #memory.general
5117
+ [memory.syn]: #memory.syn
5118
+ [meta.rqmts]: meta.md#meta.rqmts
5119
+ [new.delete]: support.md#new.delete
5120
+ [obj.lifetime]: #obj.lifetime
5121
+ [out.ptr]: #out.ptr
5122
+ [out.ptr.t]: #out.ptr.t
5123
+ [pointer.conversion]: #pointer.conversion
5124
+ [pointer.traits]: #pointer.traits
5125
+ [pointer.traits.functions]: #pointer.traits.functions
5126
+ [pointer.traits.general]: #pointer.traits.general
5127
+ [pointer.traits.optmem]: #pointer.traits.optmem
5128
+ [pointer.traits.types]: #pointer.traits.types
5129
+ [ptr.align]: #ptr.align
5130
+ [scoped.adaptor.operators]: #scoped.adaptor.operators
5131
+ [smartptr]: #smartptr
5132
+ [smartptr.adapt]: #smartptr.adapt
5133
+ [specialized.addressof]: #specialized.addressof
5134
+ [specialized.algorithms]: algorithms.md#specialized.algorithms
5135
+ [stmt.dcl]: stmt.md#stmt.dcl
5136
+ [swappable.requirements]: library.md#swappable.requirements
5137
+ [temp.deduct]: temp.md#temp.deduct
5138
+ [term.incomplete.type]: basic.md#term.incomplete.type
5139
+ [tuple]: utilities.md#tuple
5140
+ [unique.ptr]: #unique.ptr
5141
+ [unique.ptr.create]: #unique.ptr.create
5142
+ [unique.ptr.dltr]: #unique.ptr.dltr
5143
+ [unique.ptr.dltr.dflt]: #unique.ptr.dltr.dflt
5144
+ [unique.ptr.dltr.dflt1]: #unique.ptr.dltr.dflt1
5145
+ [unique.ptr.dltr.general]: #unique.ptr.dltr.general
5146
+ [unique.ptr.general]: #unique.ptr.general
5147
+ [unique.ptr.io]: #unique.ptr.io
5148
+ [unique.ptr.runtime]: #unique.ptr.runtime
5149
+ [unique.ptr.runtime.asgn]: #unique.ptr.runtime.asgn
5150
+ [unique.ptr.runtime.ctor]: #unique.ptr.runtime.ctor
5151
+ [unique.ptr.runtime.general]: #unique.ptr.runtime.general
5152
+ [unique.ptr.runtime.modifiers]: #unique.ptr.runtime.modifiers
5153
+ [unique.ptr.runtime.observers]: #unique.ptr.runtime.observers
5154
+ [unique.ptr.single]: #unique.ptr.single
5155
+ [unique.ptr.single.asgn]: #unique.ptr.single.asgn
5156
+ [unique.ptr.single.ctor]: #unique.ptr.single.ctor
5157
+ [unique.ptr.single.dtor]: #unique.ptr.single.dtor
5158
+ [unique.ptr.single.general]: #unique.ptr.single.general
5159
+ [unique.ptr.single.modifiers]: #unique.ptr.single.modifiers
5160
+ [unique.ptr.single.observers]: #unique.ptr.single.observers
5161
+ [unique.ptr.special]: #unique.ptr.special
5162
+ [unord.hash]: utilities.md#unord.hash
5163
+ [util.sharedptr]: #util.sharedptr
5164
+ [util.smartptr.enab]: #util.smartptr.enab
5165
+ [util.smartptr.getdeleter]: #util.smartptr.getdeleter
5166
+ [util.smartptr.hash]: #util.smartptr.hash
5167
+ [util.smartptr.ownerless]: #util.smartptr.ownerless
5168
+ [util.smartptr.shared]: #util.smartptr.shared
5169
+ [util.smartptr.shared.assign]: #util.smartptr.shared.assign
5170
+ [util.smartptr.shared.cast]: #util.smartptr.shared.cast
5171
+ [util.smartptr.shared.cmp]: #util.smartptr.shared.cmp
5172
+ [util.smartptr.shared.const]: #util.smartptr.shared.const
5173
+ [util.smartptr.shared.create]: #util.smartptr.shared.create
5174
+ [util.smartptr.shared.dest]: #util.smartptr.shared.dest
5175
+ [util.smartptr.shared.general]: #util.smartptr.shared.general
5176
+ [util.smartptr.shared.io]: #util.smartptr.shared.io
5177
+ [util.smartptr.shared.mod]: #util.smartptr.shared.mod
5178
+ [util.smartptr.shared.obs]: #util.smartptr.shared.obs
5179
+ [util.smartptr.shared.spec]: #util.smartptr.shared.spec
5180
+ [util.smartptr.weak]: #util.smartptr.weak
5181
+ [util.smartptr.weak.assign]: #util.smartptr.weak.assign
5182
+ [util.smartptr.weak.bad]: #util.smartptr.weak.bad
5183
+ [util.smartptr.weak.const]: #util.smartptr.weak.const
5184
+ [util.smartptr.weak.dest]: #util.smartptr.weak.dest
5185
+ [util.smartptr.weak.general]: #util.smartptr.weak.general
5186
+ [util.smartptr.weak.mod]: #util.smartptr.weak.mod
5187
+ [util.smartptr.weak.obs]: #util.smartptr.weak.obs
5188
+ [util.smartptr.weak.spec]: #util.smartptr.weak.spec