<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P2596R0: Improve std::hive::reshape</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in § N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *     -> ins/del.c### for candidate and proposed changes (amendments)
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *   - .correction for "candidate corrections"       (div, aside, details, section)
 *   - .addition   for "candidate additions"         (div, aside, details, section)
 *   - .correction.proposed for "proposed corrections" (div, aside, details, section)
 *   - .addition.proposed   for "proposed additions"   (div, aside, details, section)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Outdated warning for old specs
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/* color variables included separately for reliability */

/******************************************************************************/
/*                                    Body                                    */
/******************************************************************************/

	html {
	}

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;			  /* limit line length to 50em for readability   */
		margin: 0 auto;				/* center text within page                    */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag    */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		color: black;
		color: var(--text);
		background: white top left fixed no-repeat;
		background: var(--bg) top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em; }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border: solid var(--logo-bg);
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		background: var(--logo-bg);
		color: white;
		color: var(--logo-text);
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		background: var(--logo-active-bg);
		border-color: #c00;
		border-color: var(--logo-active-bg);
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small; }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 3;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;

			color: #707070;
			color: var(--tocnav-normal-text);
			background: white;
			background: var(--tocnav-normal-bg);
		}
		#toc-nav > a:hover,
		#toc-nav > a:focus {
			color: black;
			color: var(--tocnav-hover-text);
			background: #f8f8f8;
			background: var(--tocnav-hover-bg);
		}
		#toc-nav > a:active {
			color: #c00;
			color: var(--tocnav-active-text);
			background: white;
			background: var(--tocnav-active-bg);
		}

		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;	/* Inherit the font family. */
		line-height: 1.2;		/* Keep wrapped headings compact */
		hyphens: manual;		/* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		color: var(--heading-text);
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#profile-and-date {
		/* #profile-and-date is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > :not(.head) + hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		color: black;
		color: var(--hr-text);
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	border-left: 0.5em solid #DEF;
	border-left: 0.5em solid var(--algo-border);
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	 padding: .5em;
	 border: thin solid #ddd;
	 border: thin solid var(--algo-border);
	 border-radius: .5em;
	 margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	 margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	 margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	margin-left: -2em;
	}
	dl.switch {
	padding-left: 2em;
	}
	dl.switch > dt {
	text-indent: -1.5em;
	margin-top: 1em;
	}
	dl.switch > dt + dt {
	margin-top: 0;
	}
	dl.switch > dt::before {
	content: '\21AA';
	padding: 0 0.5em 0 0;
	display: inline-block;
	width: 1em;
	text-align: right;
	line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: inherit;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del {
		color: #aa0000;
		color: var(--del-text);
		background: transparent;
		background: var(--del-bg);
		text-decoration: line-through;
	}
	ins {
		color: #006100;
		color: var(--ins-text);
		background: transparent;
		background: var(--ins-bg);
		text-decoration: underline;
	}

	/* for amendments (candidate/proposed changes) */

	.amendment ins, .correction ins, .addition ins,
	ins[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment del, .correction del, .addition del,
	del[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment.proposed ins, .correction.proposed ins, .addition.proposed ins,
	ins[class^=c].proposed {
		text-decoration-style: double;
	}
	.amendment.proposed del, .correction.proposed del, .addition.proposed del,
	del[class^=c].proposed {
		text-decoration-style: double;
	}

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		hyphens: none;
		text-transform: none;
		text-align: left;
		text-align: start;
		font-variant: normal;
		orphans: 3;
		widows: 3;
		page-break-before: avoid;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

	/* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		color: var(--a-normal-text);
		text-decoration: underline #707070;
		text-decoration: underline var(--a-normal-underline);
		text-decoration-skip-ink: none;
	}
	a:visited {
		color: #034575;
		color: var(--a-visited-text);
		text-decoration-color: #bbb;
		text-decoration-color: var(--a-visited-underline);
	}

	/* Indicate interaction with the link */
	a[href]:focus,
	a[href]:hover {
		text-decoration-thickness: 2px;
	}
	a[href]:active {
		color: #c00;
		color: var(--a-active-text);
		text-decoration-color: #c00;
		text-decoration-color: var(--a-active-underline);
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	img, svg {
		/* Intentionally not color-scheme aware. */
		background: white;
	}

	/* For autogen numbers, add
	  .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,	.sidefigure img,	figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
		height: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em;
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em; }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote,
	.amendment, .correction, .addition {
		margin: 1em auto;
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	blockquote > :first-child,
	.note  > p:first-child,
	.issue > p:first-child,
	.amendment > p:first-child,
	.correction > p:first-child,
	.addition > p:first-child {
		margin-top: 0;
	}
	blockquote > :last-child,
	.note  > p:last-child,
	.issue > p:last-child,
	.amendment > p:last-child,
	.correction > p:last-child,
	.addition > p:last-child {
		margin-bottom: 0;
	}


	.issue::before, .issue > .marker,
	.example::before, .example > .marker,
	.note::before, .note > .marker,
	details.note > summary > .marker,
	.amendment::before, .amendment > .marker,
	details.amendment > summary > .marker,
	.addition::before, .addition > .marker,
	addition.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	correction.amendment > summary > .marker
	{
		text-transform: uppercase;
		padding-right: 1em;
	}

	.example::before, .example > .marker {
		display: block;
		padding-right: 0em;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
		border-color: var(--blockquote-border);
		background: transparent;
		background: var(--blockquote-bg);
		color: currentcolor;
		color: var(--blockquote-text);
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #e05252;
		border-color: var(--issue-border);
		background: #fbe9e9;
		background: var(--issue-bg);
		color: black;
		color: var(--issue-text);
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		color: #831616;
		color: var(--issueheading-text);
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	  or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #e0cb52;
		border-color: var(--example-border);
		background: #fcfaee;
		background: var(--example-bg);
		color: black;
		color: var(--example-text);
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		color: #574b0f;
		color: var(--exampleheading-text);
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	  or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52e052;
		border-color: var(--note-border);
		background: #e9fbe9;
		background: var(--note-bg);
		color: black;
		color: var(--note-text);
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary {
		color: hsl(120, 70%, 30%);
		color: var(--noteheading-text);
	}
	/* Add .note::before { content: "Note "; } for autogen label,
	  or use class="marker" to mark up the label in source. */

	details.note[open] > summary {
		border-bottom: 1px silver solid;
		border-bottom: 1px var(--notesummary-underline) solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		border-color: var(--assertion-border);
		background: #EEE;
		background: var(--assertion-bg);
		color: black;
		color: var(--assertion-text);
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-color: var(--advisement-border);
		border-style: none solid;
		background: #fec;
		background: var(--advisement-bg);
		color: black;
		color: var(--advisement-text);
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement::before, .advisement > .marker {
		color: #b35f00;
		color: var(--advisementheading-text);
	}

/** Amendment Box *************************************************************/

	.amendment, .correction, .addition {
		border-color: #330099;
		border-color: var(--amendment-border);
		background: #F5F0FF;
		background: var(--amendment-bg);
		color: black;
		color: var(--amendment-text);
	}
	.amendment.proposed, .correction.proposed, .addition.proposed {
		border-style: solid;
		border-block-width: 0.25em;
	}
	.amendment::before, .amendment > .marker,
	details.amendment > summary::before, details.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	details.correction > summary::before, details.correction > summary > .marker,
	.addition::before, .addition > .marker,
	details.addition > summary::before, details.addition > summary > .marker {
		color: #220066;
		color: var(--amendmentheading-text);
	}
	.amendment.proposed::before, .amendment.proposed > .marker,
	details.amendment.proposed > summary::before, details.amendment.proposed > summary > .marker,
	.correction.proposed::before, .correction.proposed > .marker,
	details.correction.proposed > summary::before, details.correction.proposed > summary > .marker,
	.addition.proposed::before, .addition.proposed > .marker,
	details.addition.proposed > summary::before, details.addition.proposed > summary > .marker {
		font-weight: bold;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: hsla(40,100%,50%,0.95);
		background: var(--warning-bg);
		color: black;
		color: var(--warning-text);
		padding: .75em 1em;
		border: red;
		border: var(--warning-border);
		border-style: solid none;
		box-shadow: 0 2px 8px black;
		text-align: center;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 2em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #def;
		background: var(--def-bg);
		margin: 1.2em 0;
		border-left: 0.5em solid #8ccbf2;
		border-left: 0.5em solid var(--def-border);
		color: black;
		color: var(--def-text);
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
		border-bottom: 1px solid var(--defrow-border);
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def td.footnote {
		padding-top: 0.6em;
	}
	table.def td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		<table class="data"> highlights structural relationships in a table
		when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		Use class="complex data" for particularly complicated tables --
		(This will draw more lines: busier, but clearer.)

		Use class="long" on table cells with paragraph-like contents
		(This will adjust text alignment accordingly.)
		Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-color: var(--datacell-border);
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		border-top: 1px solid var(--datacell-border);
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		border: 1px solid var(--datacell-border);
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
		vertical-align: baseline;
		text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding: 0.1rem 1px 0;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Switch to using border-bottom for underlines */
		text-decoration: none;
		border-bottom: 1px solid;
		/* Reverse color scheme */
		color: black;
		color: var(--toclink-text);
		border-color: #3980b5;
		border-color: var(--toclink-underline);
	}
	.toc a:visited {
		color: black;
		color: var(--toclink-visited-text);
		border-color: #054572;
		border-color: var(--toclink-visited-underline);
	}
	.toc a:focus,
	.toc a:hover {
		background: rgba(75%, 75%, 75%, .25);
		background: var(--a-hover-bg);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
	}
	.toc {
		line-height: 1.1em;
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li			{ font-weight: bold;   }
	.toc > li li		 { font-weight: normal; }
	.toc > li li li	  { font-size:   95%;	}
	.toc > li li li li	{ font-size:   90%;	}
	.toc > li li li li li { font-size:   85%;	}

	/* @supports not (display:grid) { */
		.toc > li			{ margin: 1.5rem 0;	}
		.toc > li li		 { margin: 0.3rem 0;	}
		.toc > li li li	  { margin-left: 2rem;   }

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}
		.toc > li li li li .secno { font-size: 85%; }
		.toc > li li li li li .secno { font-size: 100%; }

		.toc li {
			clear: both;
		}

		:not(li) > .toc			 { margin-left:  5rem; }
		.toc .secno				 { margin-left: -5rem; }
		.toc > li li li .secno	  { margin-left: -7rem; }
		.toc > li li li li .secno	{ margin-left: -9rem; }
		.toc > li li li li li .secno { margin-left: -11rem; }

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc			 { margin-left:  4rem; }
			.toc .secno				 { margin-left: -4rem; }
			.toc > li li li			 { margin-left:  1rem; }
			.toc > li li li .secno	  { margin-left: -5rem; }
			.toc > li li li li .secno	{ margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
		/* Loosen it on wide screens */
		@media screen and (min-width: 78em) {
			body:not(.toc-inline) :not(li) > .toc			 { margin-left:  4rem; }
			body:not(.toc-inline) .toc .secno				 { margin-left: -4rem; }
			body:not(.toc-inline) .toc > li li li			 { margin-left:  1rem; }
			body:not(.toc-inline) .toc > li li li .secno	  { margin-left: -5rem; }
			body:not(.toc-inline) .toc > li li li li .secno	{ margin-left: -6rem; }
			body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	/* } */

	@supports (display:grid) and (display:contents) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			  comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
		}
		#toc .content:hover,
		#toc .content:focus {
			background: rgba(75%, 75%, 75%, .25);
			background: var(--a-hover-bg);
			border-bottom: 3px solid #054572;
			border-bottom: 3px solid var(--toclink-underline);
			margin-bottom: -3px;
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index	  { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li	{ margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em; }
	ul.index dl	{ margin-top: 0; }
	ul.index dt	{ margin: .2em 0 .2em 20px;}
	ul.index dd	{ margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li a + span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
			color: var(--indexinfo-text);
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		color: black;
		color: var(--indextable-hover-text);
		background: #f7f8f9;
		background: var(--indextable-hover-bg);
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/** Outdated warning **********************************************************/

.outdated-spec {
	color: black;
	color: var(--outdatedspec-text);
	background-color: rgba(0,0,0,0.5);
	background-color: var(--outdatedspec-bg);
}

.outdated-warning {
	position: fixed;
	bottom: 50%;
	left: 0;
	right: 0;
	margin: 0 auto;
	width: 50%;
	background: maroon;
	background: var(--outdated-bg);
	color: white;
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	position: absolute;
	top: 0;
	right:0;
	margin: 0;
	border: 0;
	padding: 0.25em 0.5em;
	background: transparent;
	color: white;
	color: var(--outdated-text);
	font:1em sans-serif;
	text-align:center;
}

.outdated-warning span {
	display: block;
}

.outdated-collapsed {
	bottom: 0;
	border-radius: 0;
	width: 100%;
	padding: 0;
}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}

		.outdated-warning {
			position: absolute;
			border-style: solid;
			border-color: red;
		}

		.outdated-warning input {
			display: none;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge {
		/* Magic to create good item positioning:
		  "content column" is 50ems wide at max; less on smaller screens.
		  Extra space (after ToC + content) is empty on the right.

		  1. When item < content column, centers item in column.
		  2. When content < item < available, left-aligns.
		  3. When item > available, fills available + scroll bar.
		*/
		display: grid;
		grid-template-columns: minmax(0, 50em);
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			* http://lea.verou.me/2012/04/background-attachment-local/
			*
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
						top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
						top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style>
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }

    del { background: #fcc; color: #000; text-decoration: line-through; }
    ins { background: #cfc; color: #000; }
    blockquote .highlight:not(.idl) { background: initial; margin: initial; padding: 0.5em }
    blockquote ul { background: inherit; }
    blockquote code.highlight:not(.idl) { padding: initial; }
    blockquote c-[a] { color: inherit; } /* Keyword.Declaration */
    blockquote c-[b] { color: inherit; } /* Keyword.Type */
    blockquote c-[c] { color: inherit; } /* Comment */
    blockquote c-[d] { color: inherit; } /* Comment.Multiline */
    blockquote c-[e] { color: inherit; } /* Name.Attribute */
    blockquote c-[f] { color: inherit; } /* Name.Tag */
    blockquote c-[g] { color: inherit; } /* Name.Variable */
    blockquote c-[k] { color: inherit; } /* Keyword */
    blockquote c-[l] { color: inherit; } /* Literal */
    blockquote c-[m] { color: inherit; } /* Literal.Number */
    blockquote c-[n] { color: inherit; } /* Name */
    blockquote c-[o] { color: inherit; } /* Operator */
    blockquote c-[p] { color: inherit; } /* Punctuation */
    blockquote c-[s] { color: inherit; } /* Literal.String */
    blockquote c-[t] { color: inherit; } /* Literal.String.Single */
    blockquote c-[u] { color: inherit; } /* Literal.String.Double */
    blockquote c-[cp] { color: inherit; } /* Comment.Preproc */
    blockquote c-[c1] { color: inherit; } /* Comment.Single */
    blockquote c-[cs] { color: inherit; } /* Comment.Special */
    blockquote c-[kc] { color: inherit; } /* Keyword.Constant */
    blockquote c-[kn] { color: inherit; } /* Keyword.Namespace */
    blockquote c-[kp] { color: inherit; } /* Keyword.Pseudo */
    blockquote c-[kr] { color: inherit; } /* Keyword.Reserved */
    blockquote c-[ld] { color: inherit; } /* Literal.Date */
    blockquote c-[nc] { color: inherit; } /* Name.Class */
    blockquote c-[no] { color: inherit; } /* Name.Constant */
    blockquote c-[nd] { color: inherit; } /* Name.Decorator */
    blockquote c-[ni] { color: inherit; } /* Name.Entity */
    blockquote c-[ne] { color: inherit; } /* Name.Exception */
    blockquote c-[nf] { color: inherit; } /* Name.Function */
    blockquote c-[nl] { color: inherit; } /* Name.Label */
    blockquote c-[nn] { color: inherit; } /* Name.Namespace */
    blockquote c-[py] { color: inherit; } /* Name.Property */
    blockquote c-[ow] { color: inherit; } /* Operator.Word */
    blockquote c-[mb] { color: inherit; } /* Literal.Number.Bin */
    blockquote c-[mf] { color: inherit; } /* Literal.Number.Float */
    blockquote c-[mh] { color: inherit; } /* Literal.Number.Hex */
    blockquote c-[mi] { color: inherit; } /* Literal.Number.Integer */
    blockquote c-[mo] { color: inherit; } /* Literal.Number.Oct */
    blockquote c-[sb] { color: inherit; } /* Literal.String.Backtick */
    blockquote c-[sc] { color: inherit; } /* Literal.String.Char */
    blockquote c-[sd] { color: inherit; } /* Literal.String.Doc */
    blockquote c-[se] { color: inherit; } /* Literal.String.Escape */
    blockquote c-[sh] { color: inherit; } /* Literal.String.Heredoc */
    blockquote c-[si] { color: inherit; } /* Literal.String.Interpol */
    blockquote c-[sx] { color: inherit; } /* Literal.String.Other */
    blockquote c-[sr] { color: inherit; } /* Literal.String.Regex */
    blockquote c-[ss] { color: inherit; } /* Literal.String.Symbol */
    blockquote c-[vc] { color: inherit; } /* Name.Variable.Class */
    blockquote c-[vg] { color: inherit; } /* Name.Variable.Global */
    blockquote c-[vi] { color: inherit; } /* Name.Variable.Instance */
    blockquote c-[il] { color: inherit; } /* Literal.Number.Integer.Long */
  </style>
  <meta content="Bikeshed version 511ccb7, updated Mon Jun 6 13:31:59 2022 -0700" name="generator">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
<style>
ins  {background-color: #CCFFCC; text-decoration: underline;}
del  {background-color: #FFCACA; text-decoration: line-through;}
</style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: var(--a-normal-text);
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}</style>
<style>/* style-colors */

/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
:root {
    color-scheme: light dark;

    --text: black;
    --bg: white;

    --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark);

    --logo-bg: #1a5e9a;
    --logo-active-bg: #c00;
    --logo-text: white;

    --tocnav-normal-text: #707070;
    --tocnav-normal-bg: var(--bg);
    --tocnav-hover-text: var(--tocnav-normal-text);
    --tocnav-hover-bg: #f8f8f8;
    --tocnav-active-text: #c00;
    --tocnav-active-bg: var(--tocnav-normal-bg);

    --tocsidebar-text: var(--text);
    --tocsidebar-bg: #f7f8f9;
    --tocsidebar-shadow: rgba(0,0,0,.1);
    --tocsidebar-heading-text: hsla(203,20%,40%,.7);

    --toclink-text: var(--text);
    --toclink-underline: #3980b5;
    --toclink-visited-text: var(--toclink-text);
    --toclink-visited-underline: #054572;

    --heading-text: #005a9c;

    --hr-text: var(--text);

    --algo-border: #def;

    --del-text: red;
    --del-bg: transparent;
    --ins-text: #080;
    --ins-bg: transparent;

    --a-normal-text: #034575;
    --a-normal-underline: #bbb;
    --a-visited-text: var(--a-normal-text);
    --a-visited-underline: #707070;
    --a-hover-bg: rgba(75%, 75%, 75%, .25);
    --a-active-text: #c00;
    --a-active-underline: #c00;

    --blockquote-border: silver;
    --blockquote-bg: transparent;
    --blockquote-text: currentcolor;

    --issue-border: #e05252;
    --issue-bg: #fbe9e9;
    --issue-text: var(--text);
    --issueheading-text: #831616;

    --example-border: #e0cb52;
    --example-bg: #fcfaee;
    --example-text: var(--text);
    --exampleheading-text: #574b0f;

    --note-border: #52e052;
    --note-bg: #e9fbe9;
    --note-text: var(--text);
    --noteheading-text: hsl(120, 70%, 30%);
    --notesummary-underline: silver;

    --assertion-border: #aaa;
    --assertion-bg: #eee;
    --assertion-text: black;

    --advisement-border: orange;
    --advisement-bg: #fec;
    --advisement-text: var(--text);
    --advisementheading-text: #b35f00;

    --warning-border: red;
    --warning-bg: hsla(40,100%,50%,0.95);
    --warning-text: var(--text);

    --amendment-border: #330099;
    --amendment-bg: #F5F0FF;
    --amendment-text: var(--text);
    --amendmentheading-text: #220066;

    --def-border: #8ccbf2;
    --def-bg: #def;
    --def-text: var(--text);
    --defrow-border: #bbd7e9;

    --datacell-border: silver;

    --indexinfo-text: #707070;

    --indextable-hover-text: black;
    --indextable-hover-bg: #f7f8f9;

    --outdatedspec-bg: rgba(0, 0, 0, .5);
    --outdatedspec-text: black;
    --outdated-bg: maroon;
    --outdated-text: white;
    --outdated-shadow: red;

    --editedrec-bg: darkorange;
}</style>
<style>/* style-counters */

body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}</style>
<style>/* style-issues */

a[href].issue-return {
    float: right;
    float: inline-end;
    color: var(--issueheading-text);
    font-weight: bold;
    text-decoration: none;
}
</style>
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-selflinks */

:root {
    --selflink-text: white;
    --selflink-bg: gray;
    --selflink-hover-text: black;
}
.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }
</style>
<style>/* style-syntax-highlighting */

code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }

.highlight:not(.idl) { background: rgba(0, 0, 0, .03); }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */
</style>
<style>/* style-darkmode */

@media (prefers-color-scheme: dark) {
    :root {
        --text: #ddd;
        --bg: black;

        --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E");

        --logo-bg: #1a5e9a;
        --logo-active-bg: #c00;
        --logo-text: white;

        --tocnav-normal-text: #999;
        --tocnav-normal-bg: var(--bg);
        --tocnav-hover-text: var(--tocnav-normal-text);
        --tocnav-hover-bg: #080808;
        --tocnav-active-text: #f44;
        --tocnav-active-bg: var(--tocnav-normal-bg);

        --tocsidebar-text: var(--text);
        --tocsidebar-bg: #080808;
        --tocsidebar-shadow: rgba(255,255,255,.1);
        --tocsidebar-heading-text: hsla(203,20%,40%,.7);

        --toclink-text: var(--text);
        --toclink-underline: #6af;
        --toclink-visited-text: var(--toclink-text);
        --toclink-visited-underline: #054572;

        --heading-text: #8af;

        --hr-text: var(--text);

        --algo-border: #456;

        --del-text: #f44;
        --del-bg: transparent;
        --ins-text: #4a4;
        --ins-bg: transparent;

        --a-normal-text: #6af;
        --a-normal-underline: #555;
        --a-visited-text: var(--a-normal-text);
        --a-visited-underline: var(--a-normal-underline);
        --a-hover-bg: rgba(25%, 25%, 25%, .2);
        --a-active-text: #f44;
        --a-active-underline: var(--a-active-text);

        --borderedblock-bg: rgba(255, 255, 255, .05);

        --blockquote-border: silver;
        --blockquote-bg: var(--borderedblock-bg);
        --blockquote-text: currentcolor;

        --issue-border: #e05252;
        --issue-bg: var(--borderedblock-bg);
        --issue-text: var(--text);
        --issueheading-text: hsl(0deg, 70%, 70%);

        --example-border: hsl(50deg, 90%, 60%);
        --example-bg: var(--borderedblock-bg);
        --example-text: var(--text);
        --exampleheading-text: hsl(50deg, 70%, 70%);

        --note-border: hsl(120deg, 100%, 35%);
        --note-bg: var(--borderedblock-bg);
        --note-text: var(--text);
        --noteheading-text: hsl(120, 70%, 70%);
        --notesummary-underline: silver;

        --assertion-border: #444;
        --assertion-bg: var(--borderedblock-bg);
        --assertion-text: var(--text);

        --advisement-border: orange;
        --advisement-bg: #222218;
        --advisement-text: var(--text);
        --advisementheading-text: #f84;

        --warning-border: red;
        --warning-bg: hsla(40,100%,20%,0.95);
        --warning-text: var(--text);

        --amendment-border: #330099;
        --amendment-bg: #080010;
        --amendment-text: var(--text);
        --amendmentheading-text: #cc00ff;

        --def-border: #8ccbf2;
        --def-bg: #080818;
        --def-text: var(--text);
        --defrow-border: #136;

        --datacell-border: silver;

        --indexinfo-text: #aaa;

        --indextable-hover-text: var(--text);
        --indextable-hover-bg: #181818;

        --outdatedspec-bg: rgba(255, 255, 255, .5);
        --outdatedspec-text: black;
        --outdated-bg: maroon;
        --outdated-text: white;
        --outdated-shadow: red;

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}
@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}

@media (prefers-color-scheme: dark) {
    .highlight:not(.idl) { background: rgba(255, 255, 255, .05); }

    c-[a] { color: #d33682 } /* Keyword.Declaration */
    c-[b] { color: #d33682 } /* Keyword.Type */
    c-[c] { color: #2aa198 } /* Comment */
    c-[d] { color: #2aa198 } /* Comment.Multiline */
    c-[e] { color: #268bd2 } /* Name.Attribute */
    c-[f] { color: #b58900 } /* Name.Tag */
    c-[g] { color: #cb4b16 } /* Name.Variable */
    c-[k] { color: #d33682 } /* Keyword */
    c-[l] { color: #657b83 } /* Literal */
    c-[m] { color: #657b83 } /* Literal.Number */
    c-[n] { color: #268bd2 } /* Name */
    c-[o] { color: #657b83 } /* Operator */
    c-[p] { color: #657b83 } /* Punctuation */
    c-[s] { color: #6c71c4 } /* Literal.String */
    c-[t] { color: #6c71c4 } /* Literal.String.Single */
    c-[u] { color: #6c71c4 } /* Literal.String.Double */
    c-[ch] { color: #2aa198 } /* Comment.Hashbang */
    c-[cp] { color: #2aa198 } /* Comment.Preproc */
    c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */
    c-[c1] { color: #2aa198 } /* Comment.Single */
    c-[cs] { color: #2aa198 } /* Comment.Special */
    c-[kc] { color: #d33682 } /* Keyword.Constant */
    c-[kn] { color: #d33682 } /* Keyword.Namespace */
    c-[kp] { color: #d33682 } /* Keyword.Pseudo */
    c-[kr] { color: #d33682 } /* Keyword.Reserved */
    c-[ld] { color: #657b83 } /* Literal.Date */
    c-[nc] { color: #268bd2 } /* Name.Class */
    c-[no] { color: #268bd2 } /* Name.Constant */
    c-[nd] { color: #268bd2 } /* Name.Decorator */
    c-[ni] { color: #268bd2 } /* Name.Entity */
    c-[ne] { color: #268bd2 } /* Name.Exception */
    c-[nf] { color: #268bd2 } /* Name.Function */
    c-[nl] { color: #268bd2 } /* Name.Label */
    c-[nn] { color: #268bd2 } /* Name.Namespace */
    c-[py] { color: #268bd2 } /* Name.Property */
    c-[ow] { color: #657b83 } /* Operator.Word */
    c-[mb] { color: #657b83 } /* Literal.Number.Bin */
    c-[mf] { color: #657b83 } /* Literal.Number.Float */
    c-[mh] { color: #657b83 } /* Literal.Number.Hex */
    c-[mi] { color: #657b83 } /* Literal.Number.Integer */
    c-[mo] { color: #657b83 } /* Literal.Number.Oct */
    c-[sa] { color: #6c71c4 } /* Literal.String.Affix */
    c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */
    c-[sc] { color: #6c71c4 } /* Literal.String.Char */
    c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */
    c-[sd] { color: #6c71c4 } /* Literal.String.Doc */
    c-[se] { color: #6c71c4 } /* Literal.String.Escape */
    c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */
    c-[si] { color: #6c71c4 } /* Literal.String.Interpol */
    c-[sx] { color: #6c71c4 } /* Literal.String.Other */
    c-[sr] { color: #6c71c4 } /* Literal.String.Regex */
    c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */
    c-[fm] { color: #268bd2 } /* Name.Function.Magic */
    c-[vc] { color: #cb4b16 } /* Name.Variable.Class */
    c-[vg] { color: #cb4b16 } /* Name.Variable.Global */
    c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */
    c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */
    c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */
}
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P2596R0<br>Improve std::hive::reshape</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="profile-and-date"><span class="content">Published Proposal, <time class="dt-updated" datetime="2022-06-10">2022-06-10</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt class="editor">Author:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:arthur.j.odwyer@gmail.com">Arthur O'Dwyer</a>
     <dt>Audience:
     <dd>LEWG, LWG
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
     <dt>Draft Revision:
     <dd>8
     <dt>Current Source:
     <dd><a href="https://github.com/Quuxplusone/draft/blob/gh-pages/d2596-improve-hive-reshape.bs">github.com/Quuxplusone/draft/blob/gh-pages/d2596-improve-hive-reshape.bs</a>
     <dt>Current:
     <dd><a href="https://rawgit.com/Quuxplusone/draft/gh-pages/d2596-improve-hive-reshape.html">rawgit.com/Quuxplusone/draft/gh-pages/d2596-improve-hive-reshape.html</a>
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>P0447R20 <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-></code> proposes a complicated capacity model involving

  the library identifiers <code class="highlight"><c- n>hive_limits</c-></code>, <code class="highlight"><c- n>block_capacity_limits</c-></code>, <code class="highlight"><c- n>block_capacity_hard_limits</c-></code>, <code class="highlight"><c- n>reshape</c-></code>, in addition to <code class="highlight"><c- n>capacity</c-></code>, <code class="highlight"><c- n>reserve</c-></code>, <code class="highlight"><c- n>shrink_to_fit</c-></code>, and <code class="highlight"><c- n>trim_capacity</c-></code>. P0447R20’s model permits the user to specify a
  max block size; this causes "secret quadratic behavior" on some common operations.
  P0447R20’s model requires the container to track its min and max block sizes as
  part of its (non-salient) state.</p>
   <p>We propose a simpler model that involves the library identifiers <code class="highlight"><c- n>max_block_size</c-></code> and <code class="highlight"><c- n>reshape</c-></code>, in addition to <code class="highlight"><c- n>capacity</c-></code>, <code class="highlight"><c- n>reserve</c-></code>, <code class="highlight"><c- n>shrink_to_fit</c-></code>, and <code class="highlight"><c- n>trim_capacity</c-></code>. This model does not permit the user to specify
  a max block size, so "secret quadratic behavior" is less common. This model
  does not require the container to track anything; the new `reshape` is
  a simple mutating operation analogous to `reserve` or `sort`.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li><a href="#changelog"><span class="secno">1</span> <span class="content">Changelog</span></a>
    <li><a href="#intro"><span class="secno">2</span> <span class="content">Introduction: P0447R20’s model</span></a>
    <li>
     <a href="#motivation"><span class="secno">3</span> <span class="content">Criticisms of P0447R20’s model</span></a>
     <ol class="toc">
      <li><a href="#motivation-useless"><span class="secno">3.1</span> <span class="content">Max block size is not useful in practice</span></a>
      <li>
       <a href="#motivation-bigo"><span class="secno">3.2</span> <span class="content">Max block size causes O(n) behavior</span></a>
       <ol class="toc">
        <li><a href="#motivation-bigo-1"><span class="secno">3.2.1</span> <span class="content">Example 1</span></a>
        <li><a href="#motivation-bigo-2"><span class="secno">3.2.2</span> <span class="content">Example 2</span></a>
       </ol>
      <li><a href="#motivation-pmr-analogy"><span class="secno">3.3</span> <span class="content">Move semantics are arguably unintuitive</span></a>
      <li><a href="#motivation-splice"><span class="secno">3.4</span> <span class="content"><code class="highlight"><c- n>splice</c-></code> is O(n), and can throw</span></a>
      <li><a href="#motivation-bloat"><span class="secno">3.5</span> <span class="content"><code class="highlight"><c- n>hive_limits</c-></code> causes constructor overload set bloat</span></a>
      <li><a href="#motivation-ub"><span class="secno">3.6</span> <span class="content"><code class="highlight"><c- n>hive_limits</c-></code> introduces unnecessary UB</span></a>
      <li><a href="#motivation-batches"><span class="secno">3.7</span> <span class="content">Un-criticism: Batches of input/output</span></a>
     </ol>
    <li><a href="#new-model"><span class="secno">4</span> <span class="content">New model</span></a>
    <li>
     <a href="#wording"><span class="secno">5</span> <span class="content">Proposed wording relative to P0447R20</span></a>
     <ol class="toc">
      <li><a href="#wording-hive-overview"><span class="secno">5.1</span> <span class="content">[hive.overview]</span></a>
      <li><a href="#wording-hive-cons"><span class="secno">5.2</span> <span class="content">[hive.cons]</span></a>
      <li>
       <a href="#wording-hive-capacity"><span class="secno">5.3</span> <span class="content">[hive.capacity]</span></a>
       <ol class="toc">
        <li><a href="#max_block_size"><span class="secno">5.3.1</span> <span class="content">max_block_size</span></a>
        <li><a href="#capacity"><span class="secno">5.3.2</span> <span class="content">capacity</span></a>
        <li><a href="#reserve"><span class="secno">5.3.3</span> <span class="content">reserve</span></a>
        <li><a href="#shrink_to_fit"><span class="secno">5.3.4</span> <span class="content">shrink_to_fit</span></a>
        <li><a href="#trim_capacity"><span class="secno">5.3.5</span> <span class="content">trim_capacity</span></a>
       </ol>
      <li>
       <a href="#wording-hive-operations"><span class="secno">5.4</span> <span class="content">[hive.operations]</span></a>
       <ol class="toc">
        <li><a href="#splice"><span class="secno">5.4.1</span> <span class="content">splice</span></a>
        <li><a href="#block_capacity_limits"><span class="secno">5.4.2</span> <span class="content">block_capacity_limits</span></a>
        <li><a href="#block_capacity_hard_limits"><span class="secno">5.4.3</span> <span class="content">block_capacity_hard_limits</span></a>
        <li><a href="#reshape"><span class="secno">5.4.4</span> <span class="content">reshape</span></a>
       </ol>
     </ol>
    <li><a href="#acknowledgements"><span class="secno">6</span> <span class="content">Acknowledgements</span></a>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="changelog"><span class="secno">1. </span><span class="content">Changelog</span><a class="self-link" href="#changelog"></a></h2>
   <ul>
    <li data-md>
     <p>R0:</p>
     <ul>
      <li data-md>
       <p>Initial release.</p>
     </ul>
   </ul>
   <h2 class="heading settled" data-level="2" id="intro"><span class="secno">2. </span><span class="content">Introduction: P0447R20’s model</span><a class="self-link" href="#intro"></a></h2>
   <p>P0447R20 <code class="highlight"><c- n>hive</c-></code> is a bidirectional container, basically a "rope with holes." Compare it to the
existing STL sequence containers:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>vector</c-></code> is a single block with spare capacity only on the end. Only one block ever exists at a time.</p>
    <li data-md>
     <p><code class="highlight"><c- n>list</c-></code> is a linked list of equal-sized blocks, each with capacity 1; unused blocks are immediately deallocated.</p>
    <li data-md>
     <p><code class="highlight"><c- n>deque</c-></code> is a vector of equal-sized blocks, each with capacity N;
spare capacity exists at the end of the last block <em>and</em> at the beginning of the first block, but nowhere
else.</p>
    <li data-md>
     <p><code class="highlight"><c- n>hive</c-></code> is a linked list of variably-sized blocks;
spare capacity ("holes") can appear anywhere in any block, and the container keeps track of
where the "holes" are.</p>
   </ul>
   <p>The blocks of a <code class="highlight"><c- n>hive</c-></code> are variably sized. The intent is that as you insert into a hive, it will allocate
new blocks of progressively larger sizes — just like <code class="highlight"><c- n>vector</c-></code>'s geometric resizing, but without relocating
any existing elements. This improves cache locality when iterating.</p>
   <p>We can represent a vector, list, or hive diagrammatically, using <code class="highlight"><c- p>[</c-><c- n>square</c-> <c- n>brackets</c-><c- p>]</c-></code> to bracket the elements
belonging to a single block, and <code class="highlight"><c- n>_</c-></code> to represent spare capacity ("holes"). There’s a lot of bookkeeping detail
not captured by this representation; that’s okay for our purposes.</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>v</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>};</c-> <c- c1>// [1 2 3 4 5 6 _ _]</c->
<c- n>std</c-><c- o>::</c-><c- n>list</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c->   <c- n>l</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>};</c-> <c- c1>// [1] [2] [3] [4] [5] [6]</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c->   <c- n>h</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>};</c-> <c- c1>// [1 2 3 4 5 6]</c->
</pre>
   <p>Erasing from a vector shifts the later elements down. Erasing from a list or hive never needs to shift elements.</p>
<pre class="highlight"><c- n>v</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>next</c-><c- p>(</c-><c- n>v</c-><c- p>.</c-><c- n>begin</c-><c- p>()));</c->  <c- c1>// [1 3 4 5 6 _ _ _]</c->
<c- n>l</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>next</c-><c- p>(</c-><c- n>l</c-><c- p>.</c-><c- n>begin</c-><c- p>()));</c->  <c- c1>// [1] [3] [4] [5] [6]</c->
<c- n>h</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>next</c-><c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>begin</c-><c- p>()));</c->  <c- c1>// [1 _ 3 4 5 6]</c->
</pre>
   <p>Reserving in a vector may invalidate iterators, because there’s no way to strictly "add" capacity.
Reserving in a hive never invalidates iterators (except for <code class="highlight"><c- n>end</c-><c- p>()</c-></code>), because we can just add new
blocks right onto the back of the container. (In practice, <code class="highlight"><c- n>hive</c-></code> tracks unused blocks in a
separate list so that iteration doesn’t have to traverse them; this diagrammatic representation
doesn’t capture that detail.)</p>
<pre class="highlight"><c- n>v</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- mi>10</c-><c- p>);</c->  <c- c1>// [1 3 4 5 6 _ _ _ _ _]</c->
<c- n>h</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- mi>10</c-><c- p>);</c->  <c- c1>// [1 _ 3 4 5 6] [_ _ _ _]</c->
</pre>
   <p>P0447R20 allows the programmer to specify <code class="highlight"><c- n>min</c-></code> and <code class="highlight"><c- n>max</c-></code> block capacities,
via the <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive_limits</c-></code> mechanism. No block in the hive is ever permitted to be
smaller than <code class="highlight"><c- n>min</c-></code> elements in capacity, nor greater than <code class="highlight"><c- n>max</c-></code> elements in capacity.
For example, we can construct a hive in which no block’s capacity will ever be smaller than 4
or greater than 5.</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>},</c-> <c- n>std</c-><c- o>::</c-><c- n>hive_limits</c-><c- p>(</c-><c- mi>4</c-><c- p>,</c-> <c- mi>5</c-><c- p>));</c->
               <c- c1>// [1 2 3 4 5] [6 _ _ _]</c->
<c- n>h</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- mi>10</c-><c- p>);</c-> <c- c1>// [1 2 3 4 5] [6 _ _ _] [_ _ _ _]</c->
</pre>
   <p>A hive can also be "reshaped" on the fly, after construction.
In the following example, after creating a hive with one size-5 block,
we <code class="highlight"><c- n>reshape</c-></code> the hive to include only blocks of sizes between 3 and 4
inclusive. This means that the size-5 block is now "illegal"; its
elements are redistributed to other blocks, and then it is deallocated,
because this hive is no longer allowed to hold blocks of that size.</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>},</c-> <c- n>std</c-><c- o>::</c-><c- n>hive_limits</c-><c- p>(</c-><c- mi>4</c-><c- p>,</c-> <c- mi>5</c-><c- p>));</c->
               <c- c1>// [1 2 3 4 5] [6 _ _ _]</c->
<c- n>h</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- mi>10</c-><c- p>);</c-> <c- c1>// [1 2 3 4 5] [6 _ _ _] [_ _ _ _]</c->
<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>hive_limits</c-><c- p>(</c-><c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- p>));</c->
               <c- c1>// [6 1 2 3] [4 5 _ _]</c->
</pre>
   <p>Notice that <code class="highlight"><c- n>reshape</c-></code> invalidates iterators (to element <code class="highlight"><c- mi>1</c-></code>,
for example), and can also undo the effects of <code class="highlight"><c- n>reserve</c-></code> by reducing
the overall capacity of the hive. (Before the reshape operation, <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>capacity</c-><c- p>()</c-></code> was 13; afterward it is only 8.)
Programmers are advised to "<code class="highlight"><c- n>reshape</c-></code> first, <code class="highlight"><c- n>reserve</c-></code> second."</p>
   <h2 class="heading settled" data-level="3" id="motivation"><span class="secno">3. </span><span class="content">Criticisms of P0447R20’s model</span><a class="self-link" href="#motivation"></a></h2>
   <h3 class="heading settled" data-level="3.1" id="motivation-useless"><span class="secno">3.1. </span><span class="content">Max block size is not useful in practice</span><a class="self-link" href="#motivation-useless"></a></h3>
   <p>One of the primary motivations for <code class="highlight"><c- n>hive</c-></code> is to be usable in embedded/low-latency situations, where the programmer
might want fine control over the memory allocation scheme. So at first glance it makes sense that the programmer
should be able to specify min and max block capacities via <code class="highlight"><c- n>hive_limits</c-></code>. However:</p>
   <ul>
    <li data-md>
     <p>A programmer is likely to care about <em>min</em> block capacity (for cache locality),
but not so much <em>max</em> capacity. The more contiguity the better! Why would I want to put a cap on it?</p>
    <li data-md>
     <p>If the embedded programmer cares about max capacity, it’s likely because they’re using a slab allocator
that hands out blocks of some fixed size (say, 1024 bytes). But that doesn’t correspond to <code class="highlight"><c- n>hive_limits</c-><c- p>(</c-><c- mi>0</c-><c- p>,</c-> <c- mi>1024</c-><c- p>)</c-></code>.
The min and max values in <code class="highlight"><c- n>hive_limits</c-></code> are <em>counts of elements</em>, not the size of the actual allocation.
So you might try dividing by <code class="highlight"><c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code>; but that still won’t help, for two reasons:</p>
     <ul>
      <li data-md>
       <p>Just like with <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>set</c-></code>, the size of the allocation is not the same as <code class="highlight"><c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code>. In the reference
implementation, a block with capacity <code class="highlight"><c- n>n</c-></code> typically asks the allocator for <code class="highlight"><c- n>n</c-><c- o>*</c-><c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-> <c- o>+</c-> <c- n>n</c-> <c- o>+</c-> <c- mi>1</c-></code> bytes
of storage, to account for the skipfield structure. In my own implementation, I do a <code class="highlight"><c- n>make_shared</c-></code>-like
optimization that asks the allocator for <code class="highlight"><c- k>sizeof</c-><c- p>(</c-><c- n>GroupHeader</c-><c- p>)</c-> <c- o>+</c-> <c- n>n</c-><c- o>*</c-><c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-> <c- o>+</c-> <c- n>n</c-> <c- o>+</c-> <c- mi>1</c-></code> bytes.</p>
      <li data-md>
       <p>The reference implementation doesn’t store <code class="highlight"><c- n>T</c-></code> objects contiguously, when <code class="highlight"><c- n>T</c-></code> is small.
When <code class="highlight"><c- n>plf</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>char</c-><c- o>></c-></code> allocates a block of capacity <code class="highlight"><c- n>n</c-></code>, it actually asks for <code class="highlight"><c- n>n</c-><c- o>*</c-><c- mi>2</c-> <c- o>+</c-> <c- n>n</c-> <c- o>+</c-> <c- mi>1</c-></code> bytes
instead of <code class="highlight"><c- n>n</c-><c- o>*</c-><c- k>sizeof</c-><c- p>(</c-><c- b>char</c-><c- p>)</c-> <c- o>+</c-> <c- n>n</c-> <c- o>+</c-> <c- mi>1</c-></code> bytes.</p>
     </ul>
   </ul>
   <p>It’s kind of fun that you’re allowed to set a very small maximum block size,
and thus a hive can be used to simulate a traditional "rope" of fixed-capacity blocks:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>hive_limits</c-><c- p>(</c-><c- mi>3</c-><c- p>,</c-> <c- mi>3</c-><c- p>));</c->
<c- n>h</c-><c- p>.</c-><c- n>assign</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>,</c-><c- mi>7</c-><c- p>,</c-><c- mi>8</c-><c- p>});</c->  <c- c1>// [1 2 3] [4 5 6] [7 8 _]</c->
</pre>
   <p>It’s kind of fun; but I claim that it is not <em>useful enough</em> to justify its cost, in brain cells nor in CPU time.</p>
   <p>Imagine if <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-></code> provided this max-block-capacity API!</p>
<pre class="highlight"><c- c1>// If vector provided hive’s API...</c->
<c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>v</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>};</c->  <c- c1>// [1 2]</c->
<c- n>v</c-><c- p>.</c-><c- n>reshape</c-><c- p>({</c-><c- mi>5</c-><c- p>,</c-> <c- mi>8</c-><c- p>});</c->           <c- c1>// [1 2 _ _ _]</c->
<c- n>v</c-><c- p>.</c-><c- n>assign</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>});</c->       <c- c1>// [1 2 3 4 5]</c->
<c- n>v</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>6</c-><c- p>);</c->              <c- c1>// [1 2 3 4 5 6 _ _]</c->
<c- n>v</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>7</c-><c- p>);</c->              <c- c1>// [1 2 3 4 5 6 7 _]</c->
<c- n>v</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>8</c-><c- p>);</c->              <c- c1>// [1 2 3 4 5 6 7 8]</c->
<c- n>v</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>9</c-><c- p>);</c->              <c- c1>// throws length_error, since allocating a larger block isn’t allowed</c->
</pre>
   <p>No, the real-world <code class="highlight"><c- n>vector</c-></code> sensibly says that it should just keep geometrically resizing until the underlying allocator
conks out. In my opinion, <code class="highlight"><c- n>hive</c-></code> should behave the same way. Let the <em>allocator</em> decide how many bytes
is too much to allocate at once. Don’t make it the container’s problem.</p>
   <p class="note" role="note"><span>Note:</span> Discussion in SG14 (2022-06-08) suggested that maybe <code class="highlight"><c- n>hive_limits</c-><c- p>(</c-><c- mi>16</c-><c- p>,</c-> <c- mi>16</c-><c- p>)</c-></code> would be useful for SIMD processing;
but that doesn’t hold up well under scrutiny. The reference implementation doesn’t store <code class="highlight"><c- n>T</c-></code> objects contiguously.
And even if <code class="highlight"><c- n>hive_limits</c-><c- p>(</c-><c- mi>16</c-><c- p>,</c-> <c- mi>16</c-><c- p>)</c-></code> were useful (which it’s not), that rationale wouldn’t apply to <code class="highlight"><c- n>hive_limits</c-><c- p>(</c-><c- mi>23</c-><c- p>,</c-> <c- mi>29</c-><c- p>)</c-></code> and so on.</p>
   <h3 class="heading settled" data-level="3.2" id="motivation-bigo"><span class="secno">3.2. </span><span class="content">Max block size causes O(n) behavior</span><a class="self-link" href="#motivation-bigo"></a></h3>
   <h4 class="heading settled" data-level="3.2.1" id="motivation-bigo-1"><span class="secno">3.2.1. </span><span class="content">Example 1</span><a class="self-link" href="#motivation-bigo-1"></a></h4>
   <p class="note" role="note"><span>Note:</span> The quadratic behavior shown below was <i>previously</i> present in Matt Bentley’s reference implementation
(as late as <a href="https://github.com/mattreecebentley/plf_hive/blob/94862621b2466735989c88dec5b7b23a6e04e757/plf_hive.h">git commit 9486262</a>),
but was fixed in <a href="https://github.com/mattreecebentley/plf_hive/commit/7ac1f03abd9aebfae242ba7fe3c22ab1115550e9">git commit 7ac1f03</a> by renumbering the blocks less often.</p>
   <p>Consider this program parameterized on <code class="highlight"><c- n>N</c-></code>:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>hive_limits</c-><c- p>(</c-><c- mi>3</c-><c- p>,</c-> <c- mi>3</c-><c- p>));</c->
<c- n>h</c-><c- p>.</c-><c- n>assign</c-><c- p>(</c-><c- n>N</c-><c- p>,</c-> <c- mi>1</c-><c- p>);</c-> <c- c1>// [1 1 1] [1 1 1] [1 1 1] [...</c->
<c- k>while</c-> <c- p>(</c-><c- o>!</c-><c- n>h</c-><c- p>.</c-><c- n>empty</c-><c- p>())</c-> <c- p>{</c->
    <c- n>h</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>begin</c-><c- p>());</c->
<c- p>}</c->
</pre>
   <p>This loop takes O(<code class="highlight"><c- n>N</c-></code><sup>2</sup>) time to run! The reason is that <code class="highlight"><c- n>hive</c-></code>'s
active blocks are stored in a linked list, but also <em>numbered</em> in sequential
order starting from 1; those "serial numbers" are required by <code class="highlight"><c- n>hive</c-><c- o>::</c-><c- n>iterator</c-></code>'s <code class="highlight"><c- k>operator</c-><c- o>&lt;</c-></code>. (Aside: I don’t think <code class="highlight"><c- k>operator</c-><c- o>&lt;</c-></code> should exist either, but
my understanding is that that’s already been litigated.)</p>
   <p>Every time you <code class="highlight"><c- n>erase</c-></code> the last element from a block (changing <code class="highlight"><c- p>[</c-><c- n>_</c-> <c- n>_</c-> <c- mi>1</c-><c- p>]</c-></code> into <code class="highlight"><c- p>[</c-><c- n>_</c-> <c- n>_</c-> <c- n>_</c-><c- p>]</c-></code>), you need to move the
newly unused block from the active block list to the unused block list.
And then you need to renumber all the subsequent blocks. Quoting P0447R20’s
specification of <code class="highlight"><c- n>erase</c-></code>:</p>
   <blockquote> <i>Complexity:</i> Constant if the active block within which <code class="highlight"><c- n>position</c-></code> is located
does not become empty as a result of this function call. If it does become empty,
at worst linear in the number of subsequent blocks in the iterative sequence. </blockquote>
   <p>Since this program sets the max block capacity to 3, it will hit the linear-time
case once for every three erasures. Result: quadratic running time.</p>
   <h4 class="heading settled" data-level="3.2.2" id="motivation-bigo-2"><span class="secno">3.2.2. </span><span class="content">Example 2</span><a class="self-link" href="#motivation-bigo-2"></a></h4>
   <p class="note" role="note"><span>Note:</span> The quadratic behavior shown below is <i>currently</i> present in Matt Bentley’s reference implementation,
as of <a href="https://github.com/mattreecebentley/plf_hive/blob/ef9bad9c83919c9728a7ce99b98992ce60af0438/plf_hive.h">git commit ef9bad9</a>.</p>
   <p>Consider this program parameterized on <code class="highlight"><c- n>N</c-></code>:</p>
<pre class="highlight"><c- n>plf</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>;</c->
<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>({</c-><c- mi>4</c-><c- p>,</c-> <c- mi>4</c-><c- p>});</c->
<c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-><c- o>=</c-><c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>N</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>h</c-><c- p>.</c-><c- n>insert</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c->
    <c- n>h</c-><c- p>.</c-><c- n>insert</c-><c- p>(</c-><c- mi>2</c-><c- p>);</c->
<c- p>}</c->
<c- n>erase</c-><c- p>(</c-><c- n>h</c-><c- p>,</c-> <c- mi>1</c-><c- p>);</c-> <c- c1>// [_ 2 _ 2] [_ 2 _ 2] [_ 2 _ 2] [...</c->
<c- k>while</c-> <c- p>(</c-><c- o>!</c-><c- n>h</c-><c- p>.</c-><c- n>empty</c-><c- p>())</c-> <c- p>{</c->
    <c- n>h</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>begin</c-><c- p>());</c->
<c- p>}</c->
</pre>
   <p>The final loop takes O(<code class="highlight"><c- n>N</c-></code><sup>2</sup>) time to run! The reason is that in the
reference implementation, <code class="highlight"><c- n>hive</c-></code>'s list of blocks-with-erasures is singly linked.
Every time you <code class="highlight"><c- n>erase</c-></code> the last element from a block
(changing <code class="highlight"><c- p>[</c-><c- n>_</c-> <c- n>_</c-> <c- n>_</c-> <c- mi>2</c-><c- p>]</c-></code> into <code class="highlight"><c- p>[</c-><c- n>_</c-> <c- n>_</c-> <c- n>_</c-> <c- n>_</c-><c- p>]</c-></code>), you need to unlink the
newly empty block from the list of blocks with erasures; and thanks to how we
set up this snippet, the current block will always happen to be at the end of
that list! So each <code class="highlight"><c- n>erase</c-></code> takes O(<code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>size</c-><c- p>()</c-></code>) time, and the overall program
takes O(<code class="highlight"><c- n>N</c-></code><sup>2</sup>) time.</p>
   <p>Such "secret quadratic behavior" is caused <em>primarily</em> by how <code class="highlight"><c- n>hive</c-></code> permits
the programmer to set a max block size. If we get rid of the max block size,
then the implementation is free to allocate larger blocks, and so we’ll hit
the linear-time cases geometrically less often — we’ll get amortized O(<code class="highlight"><c- n>N</c-></code>)
instead of O(<code class="highlight"><c- n>N</c-></code><sup>2</sup>).</p>
   <div class="note" role="note">
     Using my proposed <code class="highlight"><c- n>hive</c-></code>, it will still be possible to simulate a rope of fixed-size blocks;
but the programmer will have to go pretty far out of their way.
There will be no footgun analogous to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>},</c-> <c- p>{</c-><c- mi>3</c-><c- p>,</c-><c- mi>3</c-><c- p>})</c-></code>. 
<pre class="highlight"><c- k>auto</c-> <c- n>make_block</c-> <c- o>=</c-> <c- p>[]()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>;</c->
    <c- n>h</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- mi>3</c-><c- p>);</c->
    <c- k>return</c-> <c- n>h</c-><c- p>;</c->
<c- p>};</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>;</c->
<c- n>h</c-><c- p>.</c-><c- n>splice</c-><c- p>(</c-><c- n>make_block</c-><c- p>());</c-> <c- c1>// [_ _ _]</c->
<c- n>h</c-><c- p>.</c-><c- n>splice</c-><c- p>(</c-><c- n>make_block</c-><c- p>());</c-> <c- c1>// [_ _ _] [_ _ _]</c->
<c- n>h</c-><c- p>.</c-><c- n>splice</c-><c- p>(</c-><c- n>make_block</c-><c- p>());</c-> <c- c1>// [_ _ _] [_ _ _] [_ _ _]</c->
<c- c1>// ...</c->
</pre>
   </div>
   <h3 class="heading settled" data-level="3.3" id="motivation-pmr-analogy"><span class="secno">3.3. </span><span class="content">Move semantics are arguably unintuitive</span><a class="self-link" href="#motivation-pmr-analogy"></a></h3>
   <p>Suppose we’ve constructed a hive with min and max block capacities, and then
we assign into it from another sequence in various ways.</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>hive_limits</c-><c- p>(</c-><c- mi>3</c-><c- p>,</c-> <c- mi>3</c-><c- p>));</c->  <c- c1>// empty</c->

<c- n>h</c-><c- p>.</c-><c- n>assign</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>});</c->                <c- c1>// [1 2 3] [4 5 _]</c->
<c- n>h</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>};</c->                      <c- c1>// [1 2 3] [4 5 _]</c->
<c- n>h</c-><c- p>.</c-><c- n>assign_range</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>});</c-> <c- c1>// [1 2 3] [4 5 _]</c->

<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>d</c-> <c- o>=</c-> <c- n>h</c-><c- p>;</c->                 <c- c1>// [1 2 3] [4 5 _]</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>d</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>move</c-><c- p>(</c-><c- n>h</c-><c- p>);</c->      <c- c1>// [1 2 3] [4 5 _]</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>d</c-><c- p>(</c-><c- n>h</c-><c- p>,</c-> <c- n>Alloc</c-><c- p>());</c->            <c- c1>// [1 2 3] [4 5 _]</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>d</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>move</c-><c- p>(</c-><c- n>h</c-><c- p>),</c-> <c- n>Alloc</c-><c- p>());</c-> <c- c1>// [1 2 3] [4 5 _]</c->

<c- c1>// BUT:</c->

<c- n>h</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>};</c-> <c- c1>// [1 2 3 4 5]</c->
<c- c1>// OR</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h2</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>};</c->
<c- n>h</c-> <c- o>=</c-> <c- n>h2</c-><c- p>;</c->                   <c- c1>// [1 2 3 4 5]</c->
<c- c1>// OR</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h2</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>};</c->
<c- n>std</c-><c- o>::</c-><c- n>swap</c-><c- p>(</c-><c- n>h</c-><c- p>,</c-> <c- n>h2</c-><c- p>);</c->         <c- c1>// [1 2 3 4 5]</c->

<c- c1>// BUT AGAIN:</c->

<c- n>h</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>hive_limits</c-><c- p>(</c-><c- mi>3</c-><c- p>,</c-> <c- mi>3</c-><c- p>));</c->
<c- n>h</c-><c- p>.</c-><c- n>splice</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>});</c->  <c- c1>// throws length_error</c->
</pre>
   <p>The <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i> of a hive are not part of its "value," yet they still
affect its behavior in critical ways. Worse, the capacity limits are
"sticky" in a way that reminds me of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>pmr</c-></code> allocators: <em>most</em> modifying
operations don’t affect a hive’s limits (resp. a <code class="highlight"><c- n>pmr</c-></code> container’s allocator),
but <em>some</em> operations do.</p>
   <p>The distinction between these two overloads of <code class="highlight"><c- k>operator</c-><c- o>=</c-></code> is particularly awkward:</p>
<pre class="highlight"><c- n>h</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>};</c->           <c- c1>// does NOT affect h’s limits</c->
<c- n>h</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>};</c->  <c- c1>// DOES affect h’s limits</c->
</pre>
   <h3 class="heading settled" data-level="3.4" id="motivation-splice"><span class="secno">3.4. </span><span class="content"><code class="highlight"><c- n>splice</c-></code> is O(n), and can throw</span><a class="self-link" href="#motivation-splice"></a></h3>
   <p>In P0447R20, <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>splice</c-><c- p>(</c-><c- n>h2</c-><c- p>)</c-></code> is a "sticky" operation: it does not change <code class="highlight"><c- n>h</c-></code>'s limits.
This means that if <code class="highlight"><c- n>h2</c-></code> contains any active blocks larger than <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>block_capacity_limits</c-><c- p>().</c-><c- n>max</c-></code>,
then <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>splice</c-><c- p>(</c-><c- n>h2</c-><c- p>)</c-></code> will fail and throw <code class="highlight"><c- n>length_error</c-></code>! This is a problem on three levels:</p>
   <ul>
    <li data-md>
     <p>Specification speedbump: Should we say something about the state of <code class="highlight"><c- n>h2</c-></code> after the throw? for example, should we guarantee that any too-large blocks not
transferred out of <code class="highlight"><c- n>h2</c-></code> will remain in <code class="highlight"><c- n>h2</c-></code>, kind of like what happens in <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>set</c-><c- o>::</c-><c- n>merge</c-></code>? Or should we leave it unspecified?</p>
    <li data-md>
     <p>Correctness pitfall: <code class="highlight"><c- n>splice</c-></code> "should" just twiddle a few pointers. The idea
that it might actually <em>fail</em> is not likely to occur to the working programmer.</p>
    <li data-md>
     <p>Performance pessimization: Again, <code class="highlight"><c- n>splice</c-></code> "should" just twiddle a few pointers.
But P0447R20’s specification requires us to traverse <code class="highlight"><c- n>h2</c-></code> looking for too-large
active blocks. This adds an O(n) step that doesn’t "need" to be there.</p>
   </ul>
   <p>If my proposal is adopted, <code class="highlight"><c- n>hive</c-><c- o>::</c-><c- n>splice</c-></code> will be "Throws: Nothing," just
like <code class="highlight"><c- n>list</c-><c- o>::</c-><c- n>splice</c-></code>.</p>
   <p class="note" role="note"><span>Note:</span> I would expect that both <code class="highlight"><c- n>hive</c-><c- o>::</c-><c- n>splice</c-></code> and <code class="highlight"><c- n>list</c-><c- o>::</c-><c- n>splice</c-></code> <em>ought</em> to throw <code class="highlight"><c- n>length_error</c-></code> if the resulting container would exceed <code class="highlight"><c- n>max_size</c-><c- p>()</c-></code> in size; but I guess that’s
intended to be impossible in practice.</p>
   <h3 class="heading settled" data-level="3.5" id="motivation-bloat"><span class="secno">3.5. </span><span class="content"><code class="highlight"><c- n>hive_limits</c-></code> causes constructor overload set bloat</span><a class="self-link" href="#motivation-bloat"></a></h3>
   <p>Every STL container’s constructor overload set is "twice as big as necessary"
because of the duplication between <code class="highlight"><c- n>container</c-><c- p>(</c-><c- n>Args</c-><c- p>...)</c-></code> and <code class="highlight"><c- n>container</c-><c- p>(</c-><c- n>Args</c-><c- p>...,</c-> <c- n>Alloc</c-><c- p>)</c-></code>. <code class="highlight"><c- n>hive</c-></code>'s constructor overload set is "four times as big as necessary" because
of the duplication between <code class="highlight"><c- n>container</c-><c- p>(</c-><c- n>Args</c-><c- p>...)</c-></code> and <code class="highlight"><c- n>container</c-><c- p>(</c-><c- n>Args</c-><c- p>...,</c-> <c- n>hive_limits</c-><c- p>)</c-></code>.</p>
   <p>P0447R20 <code class="highlight"><c- n>hive</c-></code> has 18 constructor overloads. My proposal removes 7 of them.
(Of course, we could always eliminate these same 7 constructor overloads
without doing anything else to P0447R20. If this were the <em>only</em> complaint,
my proposal would be undermotivated.)</p>
   <p>Analogously: Today there is no constructor overload for <code class="highlight"><c- n>vector</c-></code> that sets the capacity in one step;
it’s a multi-step process. Even for P0447R20 <code class="highlight"><c- n>hive</c-></code>, there’s no constructor overload
that sets the overall capacity in one step — even though overall capacity is
more important to the average programmer than min and max block capacities!</p>
<pre class="highlight"><c- c1>// Today’s multi-step process for vector</c->
<c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>v</c-><c- p>;</c->
<c- n>v</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- mi>12</c-><c- p>);</c->            <c- c1>// [_ _ _ _ _ _ _ _ _ _ _ _]</c->
<c- n>v</c-><c- p>.</c-><c- n>assign</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>});</c->  <c- c1>// [1 2 3 4 5 6 _ _ _ _ _ _]</c->

<c- c1>// Today’s multi-step process for hive</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>;</c->
<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>hive_limits</c-><c- p>(</c-><c- mi>12</c-><c- p>,</c-> <c- n>h</c-><c- p>.</c-><c- n>block_capacity_hard_limits</c-><c- p>().</c-><c- n>max</c-><c- p>));</c->
<c- n>h</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- mi>12</c-><c- p>);</c->            <c- c1>// [_ _ _ _ _ _ _ _ _ _ _ _ _]</c->
<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>block_capacity_hard_limits</c-><c- p>());</c->
<c- n>h</c-><c- p>.</c-><c- n>assign</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>});</c->  <c- c1>// [1 2 3 4 5 6 _ _ _ _ _ _ _]</c->

<c- c1>// Today’s (insufficient) single-step process for hive</c->
<c- c1>// fails to provide a setting for overall capacity</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>},</c-> <c- p>{</c-><c- mi>3</c-><c- p>,</c-> <c- mi>5</c-><c- p>});</c->
                          <c- c1>// [1 2 3 4 5] [6 _ _]</c->
</pre>
   <p>If my proposal is adopted, the analogous multi-step process will be:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>;</c->
<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>(</c-><c- mi>12</c-><c- p>,</c-> <c- mi>12</c-><c- p>);</c->      <c- c1>// [_ _ _ _ _ _ _ _ _ _ _ _]</c->
<c- n>h</c-><c- p>.</c-><c- n>assign</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>,</c-><c- mi>6</c-><c- p>};</c-> <c- c1>// [1 2 3 4 5 6 _ _ _ _ _ _]</c->
</pre>
   <h3 class="heading settled" data-level="3.6" id="motivation-ub"><span class="secno">3.6. </span><span class="content"><code class="highlight"><c- n>hive_limits</c-></code> introduces unnecessary UB</span><a class="self-link" href="#motivation-ub"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-d0447r20">[D0447R20]</a> currently says ([hive.overview]/5):</p>
   <blockquote> If user-specified limits are supplied to a function which are not within an implementation’s <i>hard limits</i>,
or if the user-specified minimum is larger than the user-specified maximum capacity, the behaviour is undefined. </blockquote>
   <p>In Matt Bentley’s reference implementation, this program will manifest its UB by throwing <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>length_error</c-></code>.</p>
   <p>The following program’s behavior is always undefined:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>;</c->
<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>({</c-><c- mi>0</c-><c- p>,</c-> <c- n>SIZE_MAX</c-><c- p>});</c-> <c- c1>// UB! Throws.</c->
</pre>
   <p>Worse, the following program’s definedness hinges on whether the user-provided max <code class="highlight"><c- mi>1000</c-></code> is greater than the implementation-defined <code class="highlight"><c- n>hive</c-><c- o>&lt;</c-><c- b>char</c-><c- o>>::</c-><c- n>block_capacity_hard_limits</c-><c- p>().</c-><c- n>max</c-></code>. The reference implementation’s <code class="highlight"><c- n>hive</c-><c- o>&lt;</c-><c- b>char</c-><c- o>>::</c-><c- n>block_capacity_hard_limits</c-><c- p>().</c-><c- n>max</c-></code> is <code class="highlight"><c- mi>255</c-></code>, so this program has undefined behavior (<a href="https://godbolt.org/z/naT7GqEMo">Godbolt</a>):</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>char</c-><c- o>></c-> <c- n>h</c-><c- p>;</c->
<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>({</c-><c- mi>10</c-><c- p>,</c-> <c- mi>1000</c-><c- p>});</c-> <c- c1>// UB! Throws.</c->
</pre>
   <p>There are two problems here. The first is trivial to solve: P0447R20 adds to the set of unnecessary library UB.
We could fix that by simply saying that the implementation must <em>clamp the provided limits</em> to the hard limits; this will
make <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>({</c-><c- mi>0</c-><c- p>,</c-> <c- n>SIZE_MAX</c-><c- p>})</c-></code> well-defined, and make <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>({</c-><c- mi>10</c-><c- p>,</c-> <c- mi>1000</c-><c- p>})</c-></code> UB only in the unlikely case that
the implementation doesn’t support <em>any</em> block sizes in the range [10, 1000]. We could even mandate that the implementation <em>must</em> throw <code class="highlight"><c- n>length_error</c-></code>, instead of having UB.</p>
   <p>The second problem is bigger: <code class="highlight"><c- n>hive_limits</c-></code> vastly increases the "specification surface area" of <code class="highlight"><c- n>hive</c-></code>'s API.</p>
   <ul>
    <li data-md>
     <p>Every constructor needs to specify (or UB) what happens when the supplied <code class="highlight"><c- n>hive_limits</c-></code> are invalid.</p>
    <li data-md>
     <p><code class="highlight"><c- n>reshape</c-></code> needs to specify (or UB) what happens when the supplied <code class="highlight"><c- n>hive_limits</c-></code> are invalid.</p>
    <li data-md>
     <p><code class="highlight"><c- n>splice</c-></code> needs to specify what happens when the two hives' <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i> are incompatible.</p>
    <li data-md>
     <p>The special members — <code class="highlight"><c- n>hive</c-><c- p>(</c-><c- k>const</c-> <c- n>hive</c-><c- o>&amp;</c-><c- p>)</c-></code>, <code class="highlight"><c- n>hive</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;&amp;</c-><c- p>)</c-></code>, <code class="highlight"><c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>hive</c-><c- o>&amp;</c-><c- p>)</c-></code>, <code class="highlight"><c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;&amp;</c-><c- p>)</c-></code>, <code class="highlight"><c- n>swap</c-></code> — need to specify
their effect on each operand’s <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i>. For example, is <code class="highlight"><c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>hive</c-><c- o>&amp;</c-><c- p>)</c-></code> permitted to preserve its
left-hand side’s <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i>, in the same way that <code class="highlight"><c- n>vector</c-><c- o>::</c-><c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>vector</c-><c- o>&amp;</c-><c- p>)</c-></code> is permitted to preserve
the left-hand side’s capacity? The Standard needs to specify this.</p>
    <li data-md>
     <p><code class="highlight"><c- n>reshape</c-></code> needs to think about how to restore the hive’s invariants if an exception is thrown. (See below.)</p>
   </ul>
   <p>All this extra specification effort is costly, for LWG and for vendors.
My "Proposed Wording" is mostly deletions.</p>
   <p>When I say "<code class="highlight"><c- n>reshape</c-></code> needs to think about how to restore the hive’s invariants," I’m talking about this example:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- n>W</c-><c- o>></c-> <c- n>h</c-><c- p>({</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>,</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>},</c-> <c- p>{</c-><c- mi>4</c-><c- p>,</c-><c- mi>4</c-><c- p>});</c-> <c- c1>// [1 2 3 4] [5 _ _ _]</c->
<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>({</c-><c- mi>5</c-><c- p>,</c-><c- mi>5</c-><c- p>});</c->  <c- c1>// suppose W(W&amp;&amp;) can throw</c->
</pre>
   <p>Suppose <code class="highlight"><c- n>W</c-></code>'s move constructor is throwing (and for the sake of simplicity, assume <code class="highlight"><c- n>W</c-></code> is move-only, although
the same problem exists for copyable types too). The hive needs to get from <code class="highlight"><c- p>[</c-><c- mi>1</c-> <c- mi>2</c-> <c- mi>3</c-> <c- mi>4</c-><c- p>]</c-> <c- p>[</c-><c- mi>5</c-> <c- n>_</c-> <c- n>_</c-> <c- n>_</c-><c- p>]</c-></code> to <code class="highlight"><c- p>[</c-><c- mi>1</c-> <c- mi>2</c-> <c- mi>3</c-> <c- mi>4</c-> <c- mi>5</c-><c- p>]</c-></code>.
We can start by allocating a block <code class="highlight"><c- p>[</c-><c- n>_</c-> <c- n>_</c-> <c- n>_</c-> <c- n>_</c-> <c- n>_</c-><c- p>]</c-></code> and then moving the first element over: <code class="highlight"><c- p>[</c-><c- mi>1</c-> <c- mi>2</c-> <c- mi>3</c-> <c- mi>4</c-><c- p>]</c-> <c- p>[</c-><c- mi>5</c-> <c- n>_</c-> <c- n>_</c-> <c- n>_</c-> <c- n>_</c-><c- p>]</c-></code>.
Then we move over the next element, intending to get to <code class="highlight"><c- p>[</c-><c- mi>1</c-> <c- mi>2</c-> <c- mi>3</c-> <c- n>_</c-><c- p>]</c-> <c- p>[</c-><c- mi>5</c-> <c- mi>4</c-> <c- n>_</c-> <c- n>_</c-> <c- n>_</c-><c- p>]</c-></code>; but that move construction might
throw. If it does, then we have no good options. If we do as <code class="highlight"><c- n>vector</c-></code> does, and simply deallocate the new buffer,
then we’ll lose data (namely element <code class="highlight"><c- mi>5</c-></code>). If we keep the new buffer, then we must update the hive’s <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i> because a hive with limits <code class="highlight"><c- p>{</c-><c- mi>4</c-><c- p>,</c-><c- mi>4</c-><c- p>}</c-></code> cannot hold a block of capacity 5. But a hive with the new user-provided limits <code class="highlight"><c- p>{</c-><c- mi>5</c-><c- p>,</c-><c- mi>5</c-><c- p>}</c-></code> cannot hold a block of capacity 4! So we must either lose data, or replace <code class="highlight"><c- n>h</c-></code>'s <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i> with
something "consistent but novel" such as <code class="highlight"><c- p>{</c-><c- mi>4</c-><c- p>,</c-><c- mi>5</c-><c- p>}</c-></code> or <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>block_capacity_hard_limits</c-><c- p>()</c-></code>. In short: May a failed operation leave
the hive with an "out-of-thin-air" <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i>? Implementors must grapple with this kind of question
in many places.</p>
   <h3 class="heading settled" data-level="3.7" id="motivation-batches"><span class="secno">3.7. </span><span class="content">Un-criticism: Batches of input/output</span><a class="self-link" href="#motivation-batches"></a></h3>
   <p>The <code class="highlight"><c- n>reshape</c-></code> and <code class="highlight"><c- n>hive_limits</c-></code> features are not mentioned in any user-submitted issues on <a data-link-type="biblio" href="#biblio-plfcolony">[PlfColony]</a>,
but there is one relevant user-submitted issue on <a data-link-type="biblio" href="#biblio-plfstack">[PlfStack]</a>:</p>
   <blockquote>
    <p>If you know that your data is coming in groups of let’s say 100, and then another 100,
and then 100 again etc but you don’t know when it is gonna stop. Having the size of the group
set at 100 would allow to allocate the right amount of memory each time.</p>
   </blockquote>
   <p>In other words, this programmer wants to do something like this:</p>
<pre class="highlight"><c- c1>// OldSmart</c->
<c- b>int</c-> <c- n>fake_input</c-><c- p>[</c-><c- mi>100</c-><c- p>]</c-> <c- o>=</c-> <c- p>{};</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>;</c->
<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>(</c-><c- mi>100</c-><c- p>,</c-> <c- mi>100</c-><c- p>);</c->  <c- c1>// blocks of size exactly 100</c->
<c- k>while</c-> <c- p>(</c->true<c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>rand</c-><c- p>()</c-> <c- o>%</c-> <c- mi>2</c-><c- p>)</c-> <c- p>{</c->
        <c- n>h</c-><c- p>.</c-><c- n>insert</c-><c- p>(</c-><c- n>fake_input</c-><c- p>,</c-> <c- n>fake_input</c-><c- o>+</c-><c- mi>100</c-><c- p>);</c->  <c- c1>// read a whole block</c->
    <c- p>}</c-> <c- k>else</c-> <c- p>{</c->
        <c- n>h</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>begin</c-><c- p>(),</c-> <c- n>std</c-><c- o>::</c-><c- n>next</c-><c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>begin</c-><c- p>(),</c-> <c- mi>100</c-><c- p>));</c->  <c- c1>// erase and "unuse" a whole block</c->
    <c- p>}</c->
<c- p>}</c->
</pre>
   <p>If the programmer doesn’t call <code class="highlight"><c- n>reshape</c-></code>, we’ll end up with <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>capacity</c-><c- p>()</c-> <c- o>==</c-> <c- mi>2</c-><c- o>*</c-><c- n>h</c-><c- p>.</c-><c- n>size</c-><c- p>()</c-></code> in the worst case, and a single big block
being used roughly like a circular buffer. This is actually not bad.</p>
   <p>A programmer who desperately wants the exactly-100 behavior can still get it,
after this patch, by working only a tiny bit harder:</p>
<pre class="highlight"><c- c1>// NewSmart</c->
<c- b>int</c-> <c- n>fake_input</c-><c- p>[</c-><c- mi>100</c-><c- p>]</c-> <c- o>=</c-> <c- p>{};</c->
<c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-><c- p>;</c->
<c- k>while</c-> <c- p>(</c->true<c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>rand</c-><c- p>()</c-> <c- o>%</c-> <c- mi>2</c-><c- p>)</c-> <c- p>{</c->
        <c- k>if</c-> <c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>capacity</c-><c- p>()</c-> <c- o>==</c-> <c- n>h</c-><c- p>.</c-><c- n>size</c-><c- p>())</c-> <c- p>{</c->
            <c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>temp</c-><c- p>;</c->
            <c- n>temp</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- mi>100</c-><c- p>);</c->
            <c- n>h</c-><c- p>.</c-><c- n>splice</c-><c- p>(</c-><c- n>temp</c-><c- p>);</c->
        <c- p>}</c->
        <c- n>h</c-><c- p>.</c-><c- n>insert</c-><c- p>(</c-><c- n>fake_input</c-><c- p>,</c-> <c- n>fake_input</c-><c- o>+</c-><c- mi>100</c-><c- p>);</c->  <c- c1>// read a whole block</c->
    <c- p>}</c-> <c- k>else</c-> <c- p>{</c->
        <c- n>h</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>begin</c-><c- p>(),</c-> <c- n>std</c-><c- o>::</c-><c- n>next</c-><c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>begin</c-><c- p>(),</c-> <c- mi>100</c-><c- p>));</c->  <c- c1>// erase and "unuse" a whole block</c->
    <c- p>}</c->
<c- p>}</c->
</pre>
   <p>I have benchmarked these options (<a data-link-type="biblio" href="#biblio-bench">[Bench]</a>) and see the following results.
(<code class="highlight"><c- n>Matt</c-></code> is Matthew Bentley’s original <code class="highlight"><c- n>plf</c-><c- o>::</c-><c- n>hive</c-></code>, <code class="highlight"><c- n>Old</c-></code> is my implementation of P0447, <code class="highlight"><c- n>New</c-></code> is my implementation of P2596; <code class="highlight"><c- n>Naive</c-></code> simply omits the call to <code class="highlight"><c- n>reshape</c-></code>, <code class="highlight"><c- n>Smart</c-></code> ensures all blocks are size-<code class="highlight"><c- n>N</c-></code> using the corresponding approach above.)
With N=100, no significant difference between the <code class="highlight"><c- n>Smart</c-></code> and <code class="highlight"><c- n>Naive</c-></code> versions:</p>
<pre class="highlight"><c- n>$</c-> <c- n>bin</c-><c- o>/</c-><c- n>ubench</c-> <c- o>--</c-><c- n>benchmark_display_aggregates_only</c-><c- o>=</c->true <c- o>--</c-><c- n>benchmark_repetitions</c-><c- o>=</c-><c- mi>5</c-> <c- o>|</c-> <c- n>grep</c-> <c- n>mean</c->
<c- mi>2022</c-><c- mo>-06</c-><c- mi>-10</c-><c- n>T00</c-><c- o>:</c-><c- mi>32</c-><c- o>:</c-><c- mi>11</c-><c- mo>-04</c-><c- o>:</c-><c- mo>00</c->
<c- n>Running</c-> <c- n>bin</c-><c- o>/</c-><c- n>ubench</c->
<c- n>Run</c-> <c- n>on</c-> <c- p>(</c-><c- mi>8</c-> <c- n>X</c-> <c- mi>2200</c-> <c- n>MHz</c-> <c- n>CPU</c-> <c- n>s</c-><c- p>)</c->
<c- n>CPU</c-> <c- n>Caches</c-><c- o>:</c->
  <c- n>L1</c-> <c- n>Data</c-> <c- mi>32</c-> <c- n>KiB</c-> <c- p>(</c-><c- n>x4</c-><c- p>)</c->
  <c- n>L1</c-> <c- n>Instruction</c-> <c- mi>32</c-> <c- n>KiB</c-> <c- p>(</c-><c- n>x4</c-><c- p>)</c->
  <c- n>L2</c-> <c- n>Unified</c-> <c- mi>256</c-> <c- n>KiB</c-> <c- p>(</c-><c- n>x4</c-><c- p>)</c->
  <c- n>L3</c-> <c- n>Unified</c-> <c- mi>6144</c-> <c- n>KiB</c-> <c- p>(</c-><c- n>x1</c-><c- p>)</c->
<c- n>Load</c-> <c- n>Average</c-><c- o>:</c-> <c- mf>2.28</c-><c- p>,</c-> <c- mf>2.14</c-><c- p>,</c-> <c- mf>2.06</c->
<c- n>BM_PlfStackIssue1_MattSmart_mean</c->        <c- mi>93298</c-> <c- n>ns</c->        <c- mi>93173</c-> <c- n>ns</c->            <c- mi>5</c->
<c- n>BM_PlfStackIssue1_MattNaive_mean</c->        <c- mi>93623</c-> <c- n>ns</c->        <c- mi>93511</c-> <c- n>ns</c->            <c- mi>5</c->
<c- n>BM_PlfStackIssue1_OldSmart_mean</c->        <c- mi>114478</c-> <c- n>ns</c->       <c- mi>114282</c-> <c- n>ns</c->            <c- mi>5</c->
<c- n>BM_PlfStackIssue1_OldNaive_mean</c->        <c- mi>113285</c-> <c- n>ns</c->       <c- mi>113124</c-> <c- n>ns</c->            <c- mi>5</c->
<c- n>BM_PlfStackIssue1_NewSmart_mean</c->        <c- mi>128535</c-> <c- n>ns</c->       <c- mi>128330</c-> <c- n>ns</c->            <c- mi>5</c->
<c- n>BM_PlfStackIssue1_NewNaive_mean</c->        <c- mi>116530</c-> <c- n>ns</c->       <c- mi>116380</c-> <c- n>ns</c->            <c- mi>5</c->
</pre>
   <p>With N=1000 (<code class="highlight"><c- n>Matt</c-></code> can’t handle this because <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>block_capacity_hard_limits</c-><c- p>().</c-><c- n>max</c-> <c- o>&lt;</c-> <c- mi>1000</c-></code>),
again no significant difference:</p>
<pre class="nohighlight highlight"><c- n>$</c-> <c- n>bin</c-><c- o>/</c-><c- n>ubench</c-> <c- o>--</c-><c- n>benchmark_display_aggregates_only</c-><c- o>=</c->true <c- o>--</c-><c- n>benchmark_repetitions</c-><c- o>=</c-><c- mi>5</c-> <c- o>|</c-> <c- n>grep</c-> <c- n>mean</c->
<c- mi>2022</c-><c- mo>-06</c-><c- mi>-10</c-><c- n>T00</c-><c- o>:</c-><c- mi>33</c-><c- o>:</c-><c- mi>12</c-><c- mo>-04</c-><c- o>:</c-><c- mo>00</c->
<c- n>Running</c-> <c- n>bin</c-><c- o>/</c-><c- n>ubench</c->
<c- n>Run</c-> <c- n>on</c-> <c- p>(</c-><c- mi>8</c-> <c- n>X</c-> <c- mi>2200</c-> <c- n>MHz</c-> <c- n>CPU</c-> <c- n>s</c-><c- p>)</c->
<c- n>CPU</c-> <c- n>Caches</c-><c- o>:</c->
  <c- n>L1</c-> <c- n>Data</c-> <c- mi>32</c-> <c- n>KiB</c-> <c- p>(</c-><c- n>x4</c-><c- p>)</c->
  <c- n>L1</c-> <c- n>Instruction</c-> <c- mi>32</c-> <c- n>KiB</c-> <c- p>(</c-><c- n>x4</c-><c- p>)</c->
  <c- n>L2</c-> <c- n>Unified</c-> <c- mi>256</c-> <c- n>KiB</c-> <c- p>(</c-><c- n>x4</c-><c- p>)</c->
  <c- n>L3</c-> <c- n>Unified</c-> <c- mi>6144</c-> <c- n>KiB</c-> <c- p>(</c-><c- n>x1</c-><c- p>)</c->
<c- n>Load</c-> <c- n>Average</c-><c- o>:</c-> <c- mf>2.13</c-><c- p>,</c-> <c- mf>2.17</c-><c- p>,</c-> <c- mf>2.08</c->
<c- n>BM_PlfStackIssue1_OldSmart_mean</c->       <c- mi>973149</c-> <c- n>ns</c->       <c- mi>972004</c-> <c- n>ns</c->            <c- mi>5</c->
<c- n>BM_PlfStackIssue1_OldNaive_mean</c->       <c- mi>970737</c-> <c- n>ns</c->       <c- mi>969565</c-> <c- n>ns</c->            <c- mi>5</c->
<c- n>BM_PlfStackIssue1_NewSmart_mean</c->      <c- mi>1032303</c-> <c- n>ns</c->      <c- mi>1031035</c-> <c- n>ns</c->            <c- mi>5</c->
<c- n>BM_PlfStackIssue1_NewNaive_mean</c->      <c- mi>1011931</c-> <c- n>ns</c->      <c- mi>1010680</c-> <c- n>ns</c->            <c- mi>5</c->
</pre>
   <h2 class="heading settled" data-level="4" id="new-model"><span class="secno">4. </span><span class="content">New model</span><a class="self-link" href="#new-model"></a></h2>
   <p>In my proposed new capacity model, <code class="highlight"><c- n>hive_limits</c-></code> is gone. Shape becomes an ephemeral property of a <code class="highlight"><c- n>hive</c-></code> object,
just like capacity is an ephemeral property of a <code class="highlight"><c- n>vector</c-></code> or <code class="highlight"><c- n>deque</c-></code>. Other ephemeral properties of <code class="highlight"><c- n>hive</c-></code> include
capacity and sortedness:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>h</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- mi>2</c-><c- p>,</c-><c- mi>3</c-><c- p>};</c->
<c- n>h</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- n>h</c-><c- p>.</c-><c- n>begin</c-><c- p>());</c->  <c- c1>// [_ 2 3]</c->
<c- n>h</c-><c- p>.</c-><c- n>sort</c-><c- p>();</c->            <c- c1>// [_ 2 3]</c->
<c- n>h</c-><c- p>.</c-><c- n>insert</c-><c- p>(</c-><c- mi>4</c-><c- p>);</c->         <c- c1>// [4 2 3], no longer sorted</c->

<c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>(</c-><c- mi>4</c-><c- p>,</c-> <c- mi>8</c-><c- p>);</c->     <c- c1>// [4 2 3 _] [_ _ _ _]</c->
<c- k>auto</c-> <c- n>h2</c-> <c- o>=</c-> <c- n>h</c-><c- p>;</c->         <c- c1>// [4 2 3], no longer capacious</c->
</pre>
   <p>I propose the interface <code class="highlight"><c- b>bool</c-> <c- n>reshape</c-><c- p>(</c-><c- b>size_t</c-> <c- n>min</c-><c- p>,</c-> <c- b>size_t</c-> <c- n>n</c-><c- o>=</c-><c- mi>0</c-><c- p>)</c-></code>, where <code class="highlight"><c- n>min</c-></code> is the new minimum block size (that is,
the new hive’s elements are guaranteed at least <em>x</em> degree of cache-friendliness) and <code class="highlight"><c- n>n</c-></code> is the new capacity (that is,
you’re guaranteed to be able to insert <em>x</em> more elements before touching the allocator again). Note that <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>(</c-><c- mi>0</c-><c- p>,</c-> <c- n>n</c-><c- p>)</c-></code> means the same thing as <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- n>n</c-><c- p>)</c-></code> except that <code class="highlight"><c- n>reshape</c-></code> is allowed to invalidate iterators.</p>
   <ul>
    <li data-md>
     <p>The <code class="highlight"><c- b>bool</c-></code> return value tells the programmer whether iterator invalidation occurred.
I think this is likely to be useful information; if it is not provided, then the programmer <em>must always assume</em> that iterator invalidation has taken place.</p>
    <li data-md>
     <p><code class="highlight"><c- n>min</c-></code> is the argument that affects the hive’s shape (so it is non-optional); <code class="highlight"><c- n>n</c-></code> has a sensible default.
If you call <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>(</c-><c- n>min</c-><c- p>)</c-></code> without providing a new capacity <code class="highlight"><c- n>n</c-></code>, then you’re saying you don’t care about
the capacity of the hive. One-argument <code class="highlight"><c- n>reshape</c-></code> is very much like <code class="highlight"><c- n>shrink_to_fit</c-></code>.</p>
    <li data-md>
     <p>Taking two adjacent <code class="highlight"><c- b>size_t</c-></code> arguments is unfortunate. But notice that they are in the "correct" order: if you
flipped them around, like <code class="highlight"><c- n>reshape</c-><c- p>(</c-><c- n>n</c-><c- p>,</c-> <c- n>min</c-><c- o>=</c-><c- mi>0</c-><c- p>)</c-></code>, then <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>reshape</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code> would do exactly the same thing as <code class="highlight"><c- n>h</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code>,
and that would be silly. So we have a good mnemonic for why the <code class="highlight"><c- n>min</c-></code> argument should come first.</p>
    <li data-md>
     <p>There is no longer any way to force a max block size. If the implementation wants to make your elements
"more contiguous," you can’t stop it (fixing <a href="#motivation-bigo">§ 3.2 Max block size causes O(n) behavior</a>).</p>
    <li data-md>
     <p>Block sizes are ephemeral, not "sticky"; they needn’t be stored in data members (fixing <a href="#motivation-pmr-analogy">§ 3.3 Move semantics are arguably unintuitive</a>).</p>
   </ul>
   <p>This new model has been implemented in a fork of Matt Bentley’s implementation; see <a data-link-type="biblio" href="#biblio-impl">[Impl]</a>.
Compile with <code class="highlight"><c- o>-</c-><c- n>DPLF_HIVE_P2596</c-><c- o>=</c-><c- mi>0</c-></code> for P0447R20, or <code class="highlight"><c- o>-</c-><c- n>DPLF_HIVE_P2596</c-><c- o>=</c-><c- mi>1</c-></code> for
this new model.</p>
   <h2 class="heading settled" data-level="5" id="wording"><span class="secno">5. </span><span class="content">Proposed wording relative to P0447R20</span><a class="self-link" href="#wording"></a></h2>
   <p>The wording in this section is relative to <a data-link-type="biblio" href="#biblio-d0447r20">[D0447R20]</a> as it stands today.</p>
   <div class="note" role="note">
     In addition to these changes, every reference in P0447 to
"reserved blocks" should be changed to "unused blocks" for clarity. The
vast majority of those references can simply be deleted, because my proposal largely
eliminates the normative distinction between "active" and "unused" blocks.
For example, P0447R20’s specification for <code class="highlight"><c- n>erase</c-></code> currently says 
    <blockquote> If the active block which <code class="highlight"><c- n>position</c-></code> is located within becomes empty [...] as a result of the function call,
that active block is either deallocated or transformed into a reserved block. </blockquote>
    <p>After my proposal, that sentence can be removed, because it doesn’t carry normative weight
anymore: sure, the container will still behave exactly that way, but we no longer need to
normatively <em>specify</em> that the empty block is non-active, because we no longer need to
normatively prevent it from interfering with a <code class="highlight"><c- n>splice</c-></code>. (After this patch, <code class="highlight"><c- n>splice</c-></code> can
never fail to transfer a block for any reason, so it doesn’t need to go out of its way to
avoid transferring unused blocks, so we don’t need to normatively describe the tracking of
unused blocks anymore. The separate unused-block list remains the intended implementation
technique, for performance; but it will no longer be directly observable by the programmer.)</p>
   </div>
   <h3 class="heading settled" data-level="5.1" id="wording-hive-overview"><span class="secno">5.1. </span><span class="content">[hive.overview]</span><a class="self-link" href="#wording-hive-overview"></a></h3>
   <ol>
    <li data-md>
     <p>A hive is a sequence container that allows constant-time insert and erase operations.
Insertion position is not specified, but will in most implementations typically be the back
of the container when no erasures have occurred, or when erasures have occurred it will reuse
existing erased element memory locations. Storage management is handled automatically and is
specifically organized in multiple blocks of sequential elements.</p>
    <li data-md>
     <p>Erasures use unspecified techniques to mark erased elements as skippable, as opposed to
relocating subsequent elements during erasure as is expected in a vector or deque. These
elements are subsequently skipped during iteration. If a memory block becomes empty of
unskipped elements as the result of an erasure, that memory block is removed from the
iterative sequence. The same, or different unspecified techniques may be used to record
the locations of erased elements, such that those locations may be reused later during
insertions.</p>
    <li data-md>
     <p>Operations pertaining to the updating of any data associated with the erased-element
skipping mechanism or erased-element location-recording mechanism are not factored into
individual function time complexity. The time complexity of these unspecified techniques
is implementation-defined and may be constant, linear or otherwise defined.</p>
    <li data-md>
     <p>Memory block element capacities have an unspecified growth factor greater than 1,
for example a new block’s capacity could be equal to the summed capacities of the existing blocks.</p>
    <li data-md>
     <del>Limits can be placed on the minimum and maximum element capacities of memory blocks,
both by a user and by an implementation. In neither case shall minimum capacity be greater
than maximum capacity. When limits are not specified by a user, the implementation’s default
limits are used. The default limits of an implementation are not guaranteed to be the same
as the minimum and maximum possible values for an implementation’s limits. The latter are
defined as hard limits. If user-specified limits are supplied to a function which are not
within an implementation’s hard limits, or if the user-specified minimum is larger than
the user-specified maximum capacity, behaviour is undefined.</del>
    <li data-md>
     <p>Memory blocks can be removed from the iterative sequence [Example: by <code class="highlight"><c- n>erase</c-></code> or <code class="highlight"><c- n>clear</c-></code> —end example]
without being deallocated. Other memory blocks can be allocated without becoming part of the iterative
sequence [Example: by <code class="highlight"><c- n>reserve</c-></code> —end example]. These are both referred to as <i>reserved blocks.</i> Blocks which form part of the iterative sequence of the container are referred to as <i>active blocks.</i></p>
    <li data-md>
     <p>A hive conforms to the requirements for Containers, with the exception of operators <code class="highlight"><c- o>==</c-></code>, <code class="highlight"><c- o>!=</c-></code>, and <code class="highlight"><c- o>&lt;=></c-></code>.
A hive also meets the requirements of a reversible container, of an allocator-aware container,
and some of the requirements of a sequence container, including several of the optional sequence
container requirements. Descriptions are provided here only for operations on <code class="highlight"><c- n>hive</c-></code> that are
not described in that table or for operations where there is additional semantic information.</p>
    <li data-md>
     <p>Hive iterators meet the Cpp17BidirectionalIterator requirements but also provide relational
operators <code class="highlight"><c- o>&lt;</c-></code>, <code class="highlight"><c- o>&lt;=</c-></code>, <code class="highlight"><c- o>></c-></code>, <code class="highlight"><c- o>>=</c-></code>, and <code class="highlight"><c- o>&lt;=></c-></code>, which compare the relative ordering of two iterators
in the sequence of a hive instance.</p>
   </ol>
<pre class="highlight"><c- k>namespace</c-> <c- nn>std</c-> <c- p>{</c->

<del><c- k>struct</c-> <c- nc>hive_limits</c-> <c- p>{</c-></del>
  <del><c- b>size_t</c-> <c- n>min</c-><c- p>;</c-></del>
  <del><c- b>size_t</c-> <c- n>max</c-><c- p>;</c-></del>
  <del><c- k>constexpr</c-> <c- n>hive_limits</c-><c- p>(</c-><c- b>size_t</c-> <c- n>minimum</c-><c- p>,</c-> <c- b>size_t</c-> <c- n>maximum</c-><c- p>)</c-> <c- k>noexcept</c-> <c- o>:</c-> <c- n>min</c-><c- p>(</c-><c- n>minimum</c-><c- p>),</c-> <c- n>max</c-><c- p>(</c-><c- n>maximum</c-><c- p>)</c-> <c- p>{}</c-></del>
<del><c- p>};</c-></del>

<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Allocator</c-> <c- o>=</c-> <c- n>allocator</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>></c->
<c- k>class</c-> <c- nc>hive</c-> <c- p>{</c->
<del><c- k>private</c-><c- o>:</c-></del>
  <del><c- n>hive_limits</c-> <c- n>current</c-><c- o>-</c-><c- n>limits</c-> <c- o>=</c-> <c- n>implementation</c-><c- o>-</c-><c- n>defined</c-><c- p>;</c-> <c- c1>// exposition only</c-></del>
<c- k>public</c-><c- o>:</c->
  <c- c1>// types</c->
  <c- k>using</c-> <c- n>value_type</c-> <c- o>=</c-> <c- n>T</c-><c- p>;</c->
  <c- k>using</c-> <c- n>allocator_type</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>;</c->
  <c- k>using</c-> <c- n>pointer</c-> <c- o>=</c-> <c- k>typename</c-> <c- nc>allocator_traits</c-><c- o>&lt;</c-><c- n>Allocator</c-><c- o>>::</c-><c- n>pointer</c-><c- p>;</c->
  <c- k>using</c-> <c- n>const_pointer</c-> <c- o>=</c-> <c- k>typename</c-> <c- nc>allocator_traits</c-><c- o>&lt;</c-><c- n>Allocator</c-><c- o>>::</c-><c- n>const_pointer</c-><c- p>;</c->
  <c- k>using</c-> <c- n>reference</c-> <c- o>=</c-> <c- n>value_type</c-><c- o>&amp;</c-><c- p>;</c->
  <c- k>using</c-> <c- n>const_reference</c-> <c- o>=</c-> <c- k>const</c-> <c- n>value_type</c-><c- o>&amp;</c-><c- p>;</c->
  <c- k>using</c-> <c- n>size_type</c-> <c- o>=</c-> <i><c- n>implementation</c-><c- o>-</c-><c- n>defined</c-></i><c- p>;</c-> <c- c1>// see [container.requirements]</c->
  <c- k>using</c-> <c- n>difference_type</c-> <c- o>=</c-> <i><c- n>implementation</c-><c- o>-</c-><c- n>defined</c-></i><c- p>;</c-> <c- c1>// see [container.requirements]</c->
  <c- k>using</c-> <c- n>iterator</c-> <c- o>=</c-> <i><c- n>implementation</c-><c- o>-</c-><c- n>defined</c-></i><c- p>;</c-> <c- c1>// see [container.requirements]</c->
  <c- k>using</c-> <c- n>const_iterator</c-> <c- o>=</c-> <i><c- n>implementation</c-><c- o>-</c-><c- n>defined</c-></i><c- p>;</c-> <c- c1>// see [container.requirements]</c->
  <c- k>using</c-> <c- n>reverse_iterator</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>reverse_iterator</c-><c- o>&lt;</c-><c- n>iterator</c-><c- o>></c-><c- p>;</c-> <c- c1>// see [container.requirements]</c->
  <c- k>using</c-> <c- n>const_reverse_iterator</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>reverse_iterator</c-><c- o>&lt;</c-><c- n>const_iterator</c-><c- o>></c-><c- p>;</c-> <c- c1>// see [container.requirements]</c->

  <c- k>constexpr</c-> <c- n>hive</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>(</c-><c- k>noexcept</c-><c- p>(</c-><c- n>Allocator</c-><c- p>()))</c-> <c- o>:</c-> <c- n>hive</c-><c- p>(</c-><c- n>Allocator</c-><c- p>())</c-> <c- p>{</c-> <c- p>}</c->
  <c- k>explicit</c-> <c- n>hive</c-><c- p>(</c-><c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
  <del><c- k>explicit</c-> <c- n>hive</c-><c- p>(</c-><c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>(</c-><c- k>noexcept</c-><c- p>(</c-><c- n>Allocator</c-><c- p>()))</c-> <c- o>:</c-> <c- n>hive</c-><c- p>(</c-><c- n>block_limits</c-><c- p>,</c-> <c- n>Allocator</c-><c- p>())</c-> <c- p>{</c-> <c- p>}</c-></del>
  <del><c- n>hive</c-><c- p>(</c-><c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></del>
  <c- k>explicit</c-> <c- n>hive</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c->
  <del><c- k>explicit</c-> <c- n>hive</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c-></del>
  <c- n>hive</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- k>const</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c->
  <del><c- n>hive</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- k>const</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c-></del>
  <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>InputIterator</c-><c- o>></c->
    <c- n>hive</c-><c- p>(</c-><c- n>InputIterator</c-> <c- n>first</c-><c- p>,</c-> <c- n>InputIterator</c-> <c- n>last</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c->
  <del><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>InputIterator</c-><c- o>></c-></del>
    <del><c- n>hive</c-><c- p>(</c-><c- n>InputIterator</c-> <c- n>first</c-><c- p>,</c-> <c- n>InputIterator</c-> <c- n>last</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c-></del>
  <c- k>template</c-><c- o>&lt;</c-><i><c- n>container</c-><c- o>-</c-><c- n>compatible</c-><c- o>-</c-><c- n>range</c-></i><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>R</c-><c- o>></c->
    <c- n>hive</c-><c- p>(</c-><c- n>from_range_t</c-><c- p>,</c-> <c- n>R</c-><c- o>&amp;&amp;</c-> <c- n>rg</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c->
  <del><c- k>template</c-><c- o>&lt;</c-><i><c- n>container</c-><c- o>-</c-><c- n>compatible</c-><c- o>-</c-><c- n>range</c-></i><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>R</c-><c- o>></c-></del>
    <del><c- n>hive</c-><c- p>(</c-><c- n>from_range_t</c-><c- p>,</c-> <c- n>R</c-><c- o>&amp;&amp;</c-> <c- n>rg</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c-></del>
  <c- n>hive</c-><c- p>(</c-><c- k>const</c-> <c- n>hive</c-><c- o>&amp;</c-><c- p>);</c->
  <c- n>hive</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>hive</c-><c- p>(</c-><c- k>const</c-> <c- n>hive</c-><c- o>&amp;</c-><c- p>,</c-> <c- k>const</c-> <c- n>type_identity_t</c-><c- o>&lt;</c-><c- n>Allocator</c-><c- o>>&amp;</c-><c- p>);</c->
  <c- n>hive</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- k>const</c-> <c- n>type_identity_t</c-><c- o>&lt;</c-><c- n>Allocator</c-><c- o>>&amp;</c-><c- p>);</c->
  <c- n>hive</c-><c- p>(</c-><c- n>initializer_list</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c->
  <del><c- n>hive</c-><c- p>(</c-><c- n>initializer_list</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c-></del>
  <c- o>~</c-><c- n>hive</c-><c- p>();</c->
  <c- n>hive</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>hive</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
  <c- n>hive</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;&amp;</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>(</c-><c- n>allocator_traits</c-><c- o>&lt;</c-><c- n>Allocator</c-><c- o>>::</c-><c- n>propagate_on_container_move_assignment</c-><c- o>::</c-><c- n>value</c-> <c- o>||</c-> <c- n>allocator_traits</c-><c- o>&lt;</c-><c- n>Allocator</c-><c- o>>::</c-><c- n>is_always_equal</c-><c- o>::</c-><c- n>value</c-><c- p>);</c->
  <c- n>hive</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>initializer_list</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>);</c->
  <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>InputIterator</c-><c- o>></c->
    <c- b>void</c-> <c- n>assign</c-><c- p>(</c-><c- n>InputIterator</c-> <c- n>first</c-><c- p>,</c-> <c- n>InputIterator</c-> <c- n>last</c-><c- p>);</c->
  <c- k>template</c-><c- o>&lt;</c-><i><c- n>container</c-><c- o>-</c-><c- n>compatible</c-><c- o>-</c-><c- n>range</c-></i><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>R</c-><c- o>></c->
    <c- b>void</c-> <c- n>assign_range</c-><c- p>(</c-><c- n>R</c-><c- o>&amp;&amp;</c-> <c- n>rg</c-><c- p>);</c->

  <c- b>void</c-> <c- nf>assign</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- k>const</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>t</c-><c- p>);</c->
  <c- b>void</c-> <c- nf>assign</c-><c- p>(</c-><c- n>initializer_list</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>);</c->
  <c- n>allocator_type</c-> <c- nf>get_allocator</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- c1>// iterators</c->
  <c- n>iterator</c->               <c- nf>begin</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>const_iterator</c->         <c- nf>begin</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>iterator</c->               <c- nf>end</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>const_iterator</c->         <c- nf>end</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>reverse_iterator</c->       <c- nf>rbegin</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>const_reverse_iterator</c-> <c- nf>rbegin</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>reverse_iterator</c->       <c- nf>rend</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>const_reverse_iterator</c-> <c- nf>rend</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- n>const_iterator</c->         <c- nf>cbegin</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>const_iterator</c->         <c- nf>cend</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>const_reverse_iterator</c-> <c- nf>crbegin</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>const_reverse_iterator</c-> <c- nf>crend</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- c1>// capacity</c->
  <c- p>[[</c-><c- n>nodiscard</c-><c- p>]]</c-> <c- b>bool</c-> <c- n>empty</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>size_type</c-> <c- nf>size</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>size_type</c-> <c- nf>max_size</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <ins><c- n>size_type</c-> <c- nf>max_block_size</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c-></ins>
  <c- n>size_type</c-> <c- nf>capacity</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- b>void</c-> <c- nf>reserve</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>);</c->
  <ins><c- b>bool</c-> <c- nf>reshape</c-><c- p>(</c-><c- b>size_t</c-> <c- n>min</c-><c- p>,</c-> <c- b>size_t</c-> <c- n>n</c-> <c- o>=</c-> <c- mi>0</c-><c- p>);</c-></ins>
  <c- b>void</c-> <c- nf>shrink_to_fit</c-><c- p>();</c->
  <del><c- b>void</c-> <c- nf>trim_capacity</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>;</c-></del>
  <del><c- b>void</c-> <c- nf>trim_capacity</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></del>
  <ins><c- b>void</c-> <c- nf>trim_capacity</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-> <c- o>=</c-> <c- mi>0</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></ins>

  <c- c1>// modifiers</c->
  <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-><c- p>...</c-> <c- n>Args</c-><c- o>></c-> <c- n>iterator</c-> <c- n>emplace</c-><c- p>(</c-><c- n>Args</c-><c- o>&amp;&amp;</c-><c- p>...</c-> <c- n>args</c-><c- p>);</c->
  <c- n>iterator</c-> <c- nf>insert</c-><c- p>(</c-><c- k>const</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
  <c- n>iterator</c-> <c- nf>insert</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;&amp;</c-> <c- n>x</c-><c- p>);</c->
  <c- b>void</c-> <c- nf>insert</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- k>const</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
  <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>InputIterator</c-><c- o>></c->
    <c- b>void</c-> <c- n>insert</c-><c- p>(</c-><c- n>InputIterator</c-> <c- n>first</c-><c- p>,</c-> <c- n>InputIterator</c-> <c- n>last</c-><c- p>);</c->
  <c- k>template</c-><c- o>&lt;</c-><i><c- n>container</c-><c- o>-</c-><c- n>compatible</c-><c- o>-</c-><c- n>range</c-></i><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>R</c-><c- o>></c->
    <c- b>void</c-> <c- n>insert_range</c-><c- p>(</c-><c- n>R</c-><c- o>&amp;&amp;</c-> <c- n>rg</c-><c- p>);</c->
  <c- b>void</c-> <c- nf>insert</c-><c- p>(</c-><c- n>initializer_list</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>);</c->
  <c- n>iterator</c-> <c- nf>erase</c-><c- p>(</c-><c- n>const_iterator</c-> <c- n>position</c-><c- p>);</c->
  <c- n>iterator</c-> <c- nf>erase</c-><c- p>(</c-><c- n>const_iterator</c-> <c- n>first</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>last</c-><c- p>);</c->
  <c- b>void</c-> <c- nf>swap</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>(</c-><c- n>allocator_traits</c-><c- o>&lt;</c-><c- n>Allocator</c-><c- o>>::</c-><c- n>propagate_on_container_swap</c-><c- o>::</c-><c- n>value</c-> <c- o>||</c-> <c- n>allocator_traits</c-><c- o>&lt;</c-><c- n>Allocator</c-><c- o>>::</c-><c- n>is_always_equal</c-><c- o>::</c-><c- n>value</c-><c- p>);</c->
  <c- b>void</c-> <c- nf>clear</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- c1>// hive operations</c->
  <c- b>void</c-> <c- nf>splice</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
  <c- b>void</c-> <c- nf>splice</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;&amp;</c-> <c- n>x</c-><c- p>);</c->
  <c- n>size_type</c-> <c- nf>unique</c-><c- p>();</c->
  <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>BinaryPredicate</c-><c- o>></c->
    <c- n>size_type</c-> <c- n>unique</c-><c- p>(</c-><c- n>BinaryPredicate</c-> <c- n>binary_pred</c-><c- p>);</c->

  <del><c- n>hive_limits</c-> <c- nf>block_capacity_limits</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c-></del>
  <del><c- k>static</c-> <c- k>constexpr</c-> <c- n>hive_limits</c-> <c- nf>block_capacity_hard_limits</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>;</c-></del>
  <del><c- b>void</c-> <c- nf>reshape</c-><c- p>(</c-><c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>);</c-></del>

  <c- n>iterator</c-> <c- nf>get_iterator</c-><c- p>(</c-><c- n>const_pointer</c-> <c- n>p</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>const_iterator</c-> <c- nf>get_iterator</c-><c- p>(</c-><c- n>const_pointer</c-> <c- n>p</c-><c- p>)</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- b>bool</c-> <c- nf>is_active</c-><c- p>(</c-><c- n>const_iterator</c-> <c- n>it</c-><c- p>)</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- b>void</c-> <c- nf>sort</c-><c- p>();</c->
  <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Compare</c-><c- o>></c-> <c- b>void</c-> <c- n>sort</c-><c- p>(</c-><c- n>Compare</c-> <c- n>comp</c-><c- p>);</c->
<c- p>}</c->

<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>InputIterator</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Allocator</c-> <c- o>=</c-> <c- n>allocator</c-><c- o>&lt;</c-><i><c- n>iter</c-><c- o>-</c-><c- n>value</c-><c- o>-</c-><c- n>type</c-></i><c- o>&lt;</c-><c- n>InputIterator</c-><c- o>>></c->
  <c- n>hive</c-><c- p>(</c-><c- n>InputIterator</c-><c- p>,</c-> <c- n>InputIterator</c-><c- p>,</c-> <c- n>Allocator</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>())</c->
    <c- o>-></c-> <c- n>hive</c-><c- o>&lt;</c-><i><c- n>iter</c-><c- o>-</c-><c- n>value</c-><c- o>-</c-><c- n>type</c-></i><c- o>&lt;</c-><c- n>InputIterator</c-><c- o>></c-><c- p>,</c-> <c- n>Allocator</c-><c- o>></c-><c- p>;</c->

<del><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>InputIterator</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Allocator</c-> <c- o>=</c-> <c- n>allocator</c-><c- o>&lt;</c-><i><c- n>iter</c-><c- o>-</c-><c- n>value</c-><c- o>-</c-><c- n>type</c-></i><c- o>&lt;</c-><c- n>InputIterator</c-><c- o>>></c-></del>
  <del><c- n>hive</c-><c- p>(</c-><c- n>InputIterator</c-><c- p>,</c-> <c- n>InputIterator</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- n>Allocator</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>())</c-></del>
    <del><c- o>-></c-> <c- n>hive</c-><c- o>&lt;</c-><i><c- n>iter</c-><c- o>-</c-><c- n>value</c-><c- o>-</c-><c- n>type</c-></i><c- o>&lt;</c-><c- n>InputIterator</c-><c- o>></c-><c- p>,</c-> <c- n>block_limits</c-><c- p>,</c-> <c- n>Allocator</c-><c- o>></c-><c- p>;</c-></del>

<c- k>template</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>input_range</c-> <c- n>R</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Allocator</c-> <c- o>=</c-> <c- n>allocator</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>R</c-><c- o>>>></c->
  <c- n>hive</c-><c- p>(</c-><c- n>from_range_t</c-><c- p>,</c-> <c- n>R</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- n>Allocator</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>())</c->
    <c- o>-></c-> <c- n>hive</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-><c- p>,</c-> <c- n>Allocator</c-><c- o>></c-><c- p>;</c->

<del><c- k>template</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>input_range</c-> <c- n>R</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Allocator</c-> <c- o>=</c-> <c- n>allocator</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>R</c-><c- o>>>></c-></del>
  <del><c- n>hive</c-><c- p>(</c-><c- n>from_range_t</c-><c- p>,</c-> <c- n>R</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- n>Allocator</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>())</c-></del>
    <del><c- o>-></c-> <c- n>hive</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-><c- p>,</c-> <c- n>block_limits</c-><c- p>,</c-> <c- n>Allocator</c-><c- o>></c-><c- p>;</c-></del>
<c- p>}</c->
</pre>
   <p>An incomplete type <code class="highlight"><c- n>T</c-></code> may be used when instantiating <code class="highlight"><c- n>hive</c-></code> if the allocator meets the allocator completeness requirements
([allocator.requirements.completeness]). <code class="highlight"><c- n>T</c-></code> shall be complete before any member of the resulting specialization of <code class="highlight"><c- n>hive</c-></code> is referenced.</p>
   <h3 class="heading settled" data-level="5.2" id="wording-hive-cons"><span class="secno">5.2. </span><span class="content">[hive.cons]</span><a class="self-link" href="#wording-hive-cons"></a></h3>
<pre class="highlight"><c- k>explicit</c-> <c- n>hive</c-><c- p>(</c-><c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   <p><i>Effects:</i> Constructs an empty hive, using the specified allocator.</p>
   <p><i>Complexity:</i> Constant.</p>
<pre class="highlight"><del><c- n>hive</c-><c- p>(</c-><c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></del>
</pre>
   <del><i>Effects:</i> Constructs an empty hive, with the specified Allocator. Initializes <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i> with <code class="highlight"><c- n>block_limits</c-></code>.</del>
   <p>
    <del><i>Complexity:</i> Constant.</del>
   </p>
<pre class="highlight"><c- k>explicit</c-> <c- n>hive</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c->
<del><c- n>hive</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c-></del>
</pre>
   <p><i>Preconditions:</i> <code class="highlight"><c- n>T</c-></code> is <em>Cpp17DefaultInsertable</em> into <code class="highlight"><c- n>hive</c-></code>.</p>
   <p>
    <i>Effects:</i> Constructs a hive with <code class="highlight"><c- n>n</c-></code> default-inserted elements, using the specified allocator. 
    <del>If the second overload is called,
also initializes <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i> with <code class="highlight"><c- n>block_limits</c-></code>.</del>
   </p>
   <p>
    <i>Complexity:</i> Linear in <code class="highlight"><c- n>n</c-></code>. 
    <del>Creates at most <code class="highlight"><c- p>(</c-><c- n>n</c-> <c- o>/</c-> <c- n>current</c-><c- o>-</c-><c- n>limits</c-><c- p>.</c-><c- n>max</c-><c- p>)</c-> <c- o>+</c-> <c- mi>1</c-></code> element block allocations.</del>
   </p>
<pre class="highlight"><c- n>hive</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- k>const</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c->
<del><c- n>hive</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>,</c-> <c- k>const</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c-></del>
</pre>
   <p><i>Preconditions:</i> <code class="highlight"><c- n>T</c-></code> is <em>Cpp17CopyInsertable</em> into <code class="highlight"><c- n>hive</c-></code>.</p>
   <p>
    <i>Effects:</i> Constructs a hive with <code class="highlight"><c- n>n</c-></code> copies of value, using the specified allocator. 
    <del>If the second overload is called,
also initializes <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i> with <code class="highlight"><c- n>block_limits</c-></code>.</del>
   </p>
   <p>
    <i>Complexity:</i> Linear in <code class="highlight"><c- n>n</c-></code>. 
    <del>Creates at most <code class="highlight"><c- p>(</c-><c- n>n</c-> <c- o>/</c-> <c- n>current</c-><c- o>-</c-><c- n>limits</c-><c- p>.</c-><c- n>max</c-><c- p>)</c-> <c- o>+</c-> <c- mi>1</c-></code> element block allocations.</del>
   </p>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><i><c- n>container</c-><c- o>-</c-><c- n>compatible</c-><c- o>-</c-><c- n>range</c-></i><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>R</c-><c- o>></c->
  <c- n>hive</c-><c- p>(</c-><c- n>from_range_t</c-><c- p>,</c-> <c- n>R</c-><c- o>&amp;&amp;</c-> <c- n>rg</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c->
<del><c- k>template</c-><c- o>&lt;</c-><i><c- n>container</c-><c- o>-</c-><c- n>compatible</c-><c- o>-</c-><c- n>range</c-></i><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>R</c-><c- o>></c-></del>
  <del><c- n>hive</c-><c- p>(</c-><c- n>from_range_t</c-><c- p>,</c-> <c- n>R</c-><c- o>&amp;&amp;</c-> <c- n>rg</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c-></del>
</pre>
   <p><i>Preconditions:</i> <code class="highlight"><c- n>T</c-></code> is <em>Cpp17EmplaceConstructible</em> into <code class="highlight"><c- n>hive</c-></code> from <code class="highlight"><c- o>*</c-><c- n>ranges</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>rg</c-><c- p>)</c-></code>.</p>
   <p>
    <i>Effects:</i> Constructs a hive object with the elements of the range <code class="highlight"><c- n>rg</c-></code>. 
    <del>If the second overload is called,
also initializes <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i> with <code class="highlight"><c- n>block_limits</c-></code>.</del>
   </p>
   <p>
    <i>Complexity:</i> Linear in <code class="highlight"><c- n>ranges</c-><c- o>::</c-><c- n>distance</c-><c- p>(</c-><c- n>rg</c-><c- p>)</c-></code>. 
    <del>Creates at most <code class="highlight"><c- p>(</c-><c- n>ranges</c-><c- o>::</c-><c- n>distance</c-><c- p>(</c-><c- n>rg</c-><c- p>)</c-> <c- o>/</c-> <c- n>current</c-><c- o>-</c-><c- n>limits</c-><c- p>.</c-><c- n>max</c-><c- p>)</c-> <c- o>+</c-> <c- mi>1</c-></code> element block allocations.</del>
   </p>
<pre class="highlight"><c- n>hive</c-><c- p>(</c-><c- n>initializer_list</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>il</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c->
<del><c- n>hive</c-><c- p>(</c-><c- n>initializer_list</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>il</c-><c- p>,</c-> <c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>,</c-> <c- k>const</c-> <c- n>Allocator</c-><c- o>&amp;</c-> <c- o>=</c-> <c- n>Allocator</c-><c- p>());</c-></del>
</pre>
   <p><i>Preconditions:</i> <code class="highlight"><c- n>T</c-></code> is <em>Cpp17CopyInsertable</em> into <code class="highlight"><c- n>hive</c-></code>.</p>
   <p>
    <i>Effects:</i> Constructs a hive object with the elements of <code class="highlight"><c- n>il</c-></code>. 
    <del>If the second overload is called,
also initializes <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i> with <code class="highlight"><c- n>block_limits</c-></code>.</del>
   </p>
   <p>
    <i>Complexity</i>: Linear in <code class="highlight"><c- n>il</c-><c- p>.</c-><c- n>size</c-><c- p>()</c-></code>. 
    <del>Creates at most <code class="highlight"><c- p>(</c-><c- n>il</c-><c- p>.</c-><c- n>size</c-><c- p>()</c-> <c- o>/</c-> <c- n>current</c-><c- o>-</c-><c- n>limits</c-><c- p>.</c-><c- n>max</c-><c- p>)</c-> <c- o>+</c-> <c- mi>1</c-></code> element block allocations.</del>
   </p>
   <h3 class="heading settled" data-level="5.3" id="wording-hive-capacity"><span class="secno">5.3. </span><span class="content">[hive.capacity]</span><a class="self-link" href="#wording-hive-capacity"></a></h3>
   <h4 class="heading settled" data-level="5.3.1" id="max_block_size"><span class="secno">5.3.1. </span><span class="content">max_block_size</span><a class="self-link" href="#max_block_size"></a></h4>
<pre class="highlight"><ins><c- n>size_type</c-> <c- nf>max_block_size</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c-></ins>
</pre>
   <ins><i>Returns:</i> The largest possible capacity of a single memory block.</ins>
   <p>
    <ins><i>Complexity:</i> Constant.</ins>
   </p>
   <h4 class="heading settled" data-level="5.3.2" id="capacity"><span class="secno">5.3.2. </span><span class="content">capacity</span><a class="self-link" href="#capacity"></a></h4>
<pre class="highlight"><c- n>size_type</c-> <c- nf>capacity</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   <p>
    <i>Returns:</i> The total number of elements that the hive can hold without requiring allocation of more 
    <del>element memory</del>
     blocks.
   </p>
   <p><i>Complexity:</i> Constant time.</p>
   <h4 class="heading settled" data-level="5.3.3" id="reserve"><span class="secno">5.3.3. </span><span class="content">reserve</span><a class="self-link" href="#reserve"></a></h4>
<pre class="highlight"><c- b>void</c-> <c- nf>reserve</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>);</c->
</pre>
   <p>
    <i>Effects:</i> A directive that informs a hive of a planned change in size, so that it can manage the storage allocation accordingly. 
    <del>Does
not cause reallocation of elements. Iterators</del>
    <ins>Invalidates the past-the-end iterator. Iterators and
references</ins>
     to elements in <code class="highlight"><c- o>*</c-><c- k>this</c-></code> remain valid. If <code class="highlight"><c- n>n</c-> <c- o>&lt;=</c-> <c- n>capacity</c-><c- p>()</c-></code> there are no effects.
   </p>
   <p>
    <del><i>Complexity:</i> It does not change the size of the sequence and creates at most <code class="highlight"><c- p>(</c-><c- n>n</c-> <c- o>/</c-> <c- n>block_capacity_limits</c-><c- p>().</c-><c- n>max</c-><c- p>)</c-> <c- o>+</c-> <c- mi>1</c-></code> element block allocations.</del>
   </p>
   <p>
    <i>Throws:</i> <code class="highlight"><c- n>length_error</c-></code> if <code class="highlight"><c- n>n</c-> <c- o>></c-> <c- n>max_size</c-><c- p>()</c-></code>. 
    <ins>Any exception thrown from <code class="highlight"><c- n>allocate</c-></code>.</ins>
   </p>
   <p><i>Postconditions:</i> <code class="highlight"><c- n>capacity</c-><c- p>()</c-> <c- o>>=</c-> <c- n>n</c-></code> is <code class="highlight">true</code>.</p>
   <h4 class="heading settled" data-level="5.3.4" id="shrink_to_fit"><span class="secno">5.3.4. </span><span class="content">shrink_to_fit</span><a class="self-link" href="#shrink_to_fit"></a></h4>
<pre class="highlight"><c- b>void</c-> <c- nf>shrink_to_fit</c-><c- p>();</c->
</pre>
   <p><i>Preconditions:</i> <code class="highlight"><c- n>T</c-></code> is <em>Cpp17MoveInsertable</em> into <code class="highlight"><c- n>hive</c-></code>.</p>
   <p>
    <i>Effects:</i> <code class="highlight"><c- n>shrink_to_fit</c-></code> is a non-binding request to reduce <code class="highlight"><c- n>capacity</c-><c- p>()</c-></code> to be closer to <code class="highlight"><c- n>size</c-><c- p>()</c-></code>.
[<i>Note:</i> The request is non-binding to allow latitude for implementation-specific optimizations. <i>—end note</i>]
It does not increase <code class="highlight"><c- n>capacity</c-><c- p>()</c-></code>, but may reduce <code class="highlight"><c- n>capacity</c-><c- p>()</c-></code>. 
    <del>It may reallocate elements.</del>
    <ins>Invalidates
all references, pointers, and iterators referring to the elements in the sequence, as well as the past-the-end
iterator. [<i>Note:</i> This operation may change the iterative order of the elements in <code class="highlight"><c- o>*</c-><c- k>this</c-></code>. <i>—end note</i>]</ins>
   </p>
   <p>
    <i>Complexity:</i> 
    <del>If reallocation happens, linear in the size of the sequence.</del>
    <ins>Linear in <code class="highlight"><c- n>size</c-><c- p>()</c-></code>.</ins>
   </p>
   <del><i>Remarks:</i> Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence,
as well as the past-the-end iterator.
[<i>Note:</i> If no reallocation happens, they remain valid. <i>—end note</i>]
[<i>Note:</i> This operation may change the iterative order of the elements in *this. <i>—end note</i>]</del>
   <h4 class="heading settled" data-level="5.3.5" id="trim_capacity"><span class="secno">5.3.5. </span><span class="content">trim_capacity</span><a class="self-link" href="#trim_capacity"></a></h4>
<pre class="highlight"><del><c- b>void</c-> <c- nf>trim_capacity</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>;</c-></del>
<del><c- b>void</c-> <c- nf>trim_capacity</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></del>
<ins><c- b>void</c-> <c- nf>trim_capacity</c-><c- p>(</c-><c- n>size_type</c-> <c- n>n</c-> <c- o>=</c-> <c- mi>0</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></ins>
</pre>
   <p>
    <i>Effects:</i> 
    <del>Removes and deallocates reserved blocks created by prior calls to <code class="highlight"><c- n>reserve</c-></code>, <code class="highlight"><c- n>clear</c-></code>, or <code class="highlight"><c- n>erase</c-></code>.
If such blocks are present, for the first overload <code class="highlight"><c- n>capacity</c-><c- p>()</c-></code> is reduced. For the second overload <code class="highlight"><c- n>capacity</c-><c- p>()</c-></code> will be reduced to no less than <code class="highlight"><c- n>n</c-></code>.</del>
    <ins><code class="highlight"><c- n>trim_capacity</c-></code> is a non-binding request to reduce <code class="highlight"><c- n>capacity</c-><c- p>()</c-></code> to be
closer to <code class="highlight"><c- n>n</c-></code>. It does not increase <code class="highlight"><c- n>capacity</c-><c- p>()</c-></code>; it may reduce <code class="highlight"><c- n>capacity</c-><c- p>()</c-></code>, but not below <code class="highlight"><c- n>n</c-></code>.</ins>
   </p>
   <p>
    <i>Complexity:</i> Linear in the number of reserved blocks 
    <del>deallocated</del>
    .
   </p>
   <p>
    <i>Remarks:</i> 
    <del>Does not reallocate elements and no</del>
    <ins>No</ins>
     iterators or references to elements in <code class="highlight"><c- o>*</c-><c- k>this</c-></code> are invalidated.
   </p>
   <h3 class="heading settled" data-level="5.4" id="wording-hive-operations"><span class="secno">5.4. </span><span class="content">[hive.operations]</span><a class="self-link" href="#wording-hive-operations"></a></h3>
   <p>In this subclause, arguments for a template parameter named <code class="highlight"><c- n>Predicate</c-></code> or <code class="highlight"><c- n>BinaryPredicate</c-></code> shall meet the
corresponding requirements in [algorithms.requirements]. The semantics of <code class="highlight"><c- n>i</c-> <c- o>+</c-> <c- n>n</c-></code> and <code class="highlight"><c- n>i</c-> <c- o>-</c-> <c- n>n</c-></code>, where <code class="highlight"><c- n>i</c-></code> is an iterator into the list and <code class="highlight"><c- n>n</c-></code> is an integer, are the same as those of <code class="highlight"><c- n>next</c-><c- p>(</c-><c- n>i</c-><c- p>,</c-> <c- n>n</c-><c- p>)</c-></code> and <code class="highlight"><c- n>prev</c-><c- p>(</c-><c- n>i</c-><c- p>,</c-> <c- n>n</c-><c- p>)</c-></code>,
respectively. For <code class="highlight"><c- n>sort</c-></code>, the definitions and requirements in [alg.sorting] apply.</p>
   <del><code class="highlight"><c- n>hive</c-></code> provides a splice operation that destructively moves all elements from one hive to another.
The behavior of splice operations is undefined if <code class="highlight"><c- n>get_allocator</c-><c- p>()</c-> <c- o>!=</c-> <c- n>x</c-><c- p>.</c-><c- n>get_allocator</c-><c- p>()</c-></code>.</del>
   <h4 class="heading settled" data-level="5.4.1" id="splice"><span class="secno">5.4.1. </span><span class="content">splice</span><a class="self-link" href="#splice"></a></h4>
<pre class="highlight"><c- b>void</c-> <c- nf>splice</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
<c- b>void</c-> <c- nf>splice</c-><c- p>(</c-><c- n>hive</c-><c- o>&amp;&amp;</c-> <c- n>x</c-><c- p>);</c->
</pre>
   <p><i>Preconditions:</i> <code class="highlight"><c- n>addressof</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-> <c- o>!=</c-> <c- k>this</c-></code> is <code class="highlight">true</code>.</p>
   <p>
    <i>Effects:</i> Inserts the contents of <code class="highlight"><c- n>x</c-></code> into <code class="highlight"><c- o>*</c-><c- k>this</c-></code> and <code class="highlight"><c- n>x</c-></code> becomes empty. Pointers and references to the moved elements of <code class="highlight"><c- n>x</c-></code> now refer to those same elements but as members of <code class="highlight"><c- o>*</c-><c- k>this</c-></code>. Iterators referring to the moved elements 
    <del>shall</del>
     continue
to refer to their elements, but they now behave as iterators into <code class="highlight"><c- o>*</c-><c- k>this</c-></code>, not into <code class="highlight"><c- n>x</c-></code>.
   </p>
   <p>
    <i>Complexity:</i> 
    <del>At worst, linear in the number of active blocks in <code class="highlight"><c- n>x</c-></code> + the number of active blocks in <code class="highlight"><c- o>*</c-><c- k>this</c-></code>.</del>
    <ins>Linear in the number of active blocks in the resulting hive.</ins>
   </p>
   <p>
    <i>Throws:</i> 
    <del><code class="highlight"><c- n>length_error</c-></code> if any of <code class="highlight"><c- n>x</c-></code>'s element memory block capacities are outside of the current minimum and maximum element memory block capacity limits of <code class="highlight"><c- o>*</c-><c- k>this</c-></code>.</del>
    <ins>Nothing.</ins>
   </p>
   <p>
    <i>Remarks:</i> The behavior 
    <del>of splice operations</del>
     is undefined if <code class="highlight"><c- n>get_allocator</c-><c- p>()</c-> <c- o>!=</c-> <c- n>x</c-><c- p>.</c-><c- n>get_allocator</c-><c- p>()</c-></code>. 
    <del>Reserved blocks in <code class="highlight"><c- n>x</c-></code> are not transferred into <code class="highlight"><c- o>*</c-><c- k>this</c-></code>.</del>
   </p>
   <h4 class="heading settled" data-level="5.4.2" id="block_capacity_limits"><span class="secno">5.4.2. </span><span class="content">block_capacity_limits</span><a class="self-link" href="#block_capacity_limits"></a></h4>
<pre class="highlight"><del><c- n>hive_limits</c-> <c- nf>block_capacity_limits</c-><c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c-></del>
</pre>
   <del><i>Effects:</i> Returns <i><code class="highlight"><c- n>current</c-><c- o>-</c-><c- n>limits</c-></code></i>.</del>
   <p>
    <del><i>Complexity:</i> Constant.</del>
   </p>
   <h4 class="heading settled" data-level="5.4.3" id="block_capacity_hard_limits"><span class="secno">5.4.3. </span><span class="content">block_capacity_hard_limits</span><a class="self-link" href="#block_capacity_hard_limits"></a></h4>
<pre class="highlight"><del><c- k>static</c-> <c- k>constexpr</c-> <c- n>hive_limits</c-> <c- nf>block_capacity_hard_limits</c-><c- p>();</c-></del>
</pre>
   <del><i>Returns:</i> A <code class="highlight"><c- n>hive_limits</c-></code> struct with the <code class="highlight"><c- n>min</c-></code> and <code class="highlight"><c- n>max</c-></code> members set to the implementation’s hard limits.</del>
   <p>
    <del><i>Complexity:</i> Constant.</del>
   </p>
   <h4 class="heading settled" data-level="5.4.4" id="reshape"><span class="secno">5.4.4. </span><span class="content">reshape</span><a class="self-link" href="#reshape"></a></h4>
<pre class="highlight"><del><c- b>void</c-> <c- nf>reshape</c-><c- p>(</c-><c- n>hive_limits</c-> <c- n>block_limits</c-><c- p>);</c-></del>
<ins><c- b>bool</c-> <c- nf>reshape</c-><c- p>(</c-><c- b>size_t</c-> <c- n>min</c-><c- p>,</c-> <c- b>size_t</c-> <c- n>n</c-> <c- o>=</c-> <c- mi>0</c-><c- p>);</c-></ins>
</pre>
   <p><i>Preconditions:</i> <code class="highlight"><c- n>T</c-></code> shall be <em>Cpp17MoveInsertable</em> into <code class="highlight"><c- n>hive</c-></code>.</p>
   <p>
    <i>Effects:</i> 
    <del>Sets minimum and maximum element memory block capacities to the <code class="highlight"><c- n>min</c-></code> and <code class="highlight"><c- n>max</c-></code> members of the supplied <code class="highlight"><c- n>hive_limits</c-></code> struct.
If the hive is not empty, adjusts existing memory block capacities to conform to the new minimum and maximum block capacities, where necessary.
If existing memory block capacities are within the supplied minimum/maximum range, no reallocation of elements takes place.
If they are not within the supplied range, elements are reallocated to new or existing memory blocks which fit within the supplied range,
and the old memory blocks are deallocated. If elements are reallocated, all iterators and references to reallocated elements are invalidated.</del>
    <ins>Reallocates
storage by allocating new blocks and/or transferring elements among existing blocks so that the capacity of each memory block
that remains allocated is greater than or equal to <code class="highlight"><c- n>min</c-></code>, and <code class="highlight"><c- n>capacity</c-><c- p>()</c-></code> is greater than or equal to <code class="highlight"><c- n>n</c-></code>.
If reallocation takes place, all iterators, pointers, and references to elements of the container, including the past-the-end iterator, are invalidated.
Reallocation may change the iteration order of the elements of <code class="highlight"><c- o>*</c-><c- k>this</c-></code>.</ins>
   </p>
   <ins><i>Returns:</i> <code class="highlight">true</code> if any iterators were invalidated; otherwise <code class="highlight">false</code>.</ins>
   <p>
    <i>Complexity:</i> 
    <del>At worst linear in the number of active and reserved blocks in <code class="highlight"><c- o>*</c-><c- k>this</c-></code>. If reallocation occurs, also linear in
the number of elements reallocated.</del>
    <ins>Linear in <code class="highlight"><c- n>size</c-><c- p>()</c-></code>.</ins>
   </p>
   <p>
    <i>Throws:</i> 
    <ins><code class="highlight"><c- n>length_error</c-></code> if <code class="highlight"><c- n>min</c-> <c- o>></c-> <c- n>max_block_size</c-><c- p>()</c-> <c- o>||</c-> <c- n>n</c-> <c- o>></c-> <c- n>max_size</c-><c- p>()</c-></code>. Any exception thrown from <code class="highlight"><c- n>allocate</c-></code> or from the initialization
of <code class="highlight"><c- n>T</c-></code>.</ins>
    <del>If reallocation occurs, uses <code class="highlight"><c- n>Allocator</c-><c- o>::</c-><c- n>allocate</c-><c- p>()</c-></code> which may throw an appropriate exception. [<i>Note:</i> This operation
may change the iterative order of the elements in <code class="highlight"><c- o>*</c-><c- k>this</c-></code>. <i>—end note</i>]</del>
   </p>
   <ins><i>Postconditions:</i> <code class="highlight"><c- n>capacity</c-><c- p>()</c-> <c- o>>=</c-> <c- n>n</c-></code> is <code class="highlight">true</code>.</ins>
   <h2 class="heading settled" data-level="6" id="acknowledgements"><span class="secno">6. </span><span class="content">Acknowledgements</span><a class="self-link" href="#acknowledgements"></a></h2>
   <p>Thanks to Matthew Bentley for proposing <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>hive</c-></code>.</p>
   <p>Thanks to Joe Gottman for his comments on a draft of this paper.</p>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don’t scroll to compensate for the ToC if we’re above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don’t know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn’t exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn’t standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don’t have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we’re at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can’t find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-bench">[Bench]
   <dd>Arthur O'Dwyer. <a href="https://github.com/Quuxplusone/SG14/blob/e0012e6b56/benchmarks/hive_bench.cpp"><cite>Benchmark code (git branch 'ajo')</cite></a>. June 2022. URL: <a href="https://github.com/Quuxplusone/SG14/blob/e0012e6b56/benchmarks/hive_bench.cpp">https://github.com/Quuxplusone/SG14/blob/e0012e6b56/benchmarks/hive_bench.cpp</a>
   <dt id="biblio-d0447r20">[D0447R20]
   <dd>Matthew Bentley. <a href="https://plflib.org/D0447R20_-_Introduction_of_hive_to_the_Standard_Library.html"><cite>Introduction of std::hive to the standard library</cite></a>. May 2022. URL: <a href="https://plflib.org/D0447R20_-_Introduction_of_hive_to_the_Standard_Library.html">https://plflib.org/D0447R20_-_Introduction_of_hive_to_the_Standard_Library.html</a>
   <dt id="biblio-impl">[Impl]
   <dd>Arthur O'Dwyer. <a href="https://github.com/Quuxplusone/SG14/blob/e0012e6b56/include/sg14/plf_hive.h"><cite>Reference implementation of P2596R0 (git branch 'ajo')</cite></a>. June 2022. URL: <a href="https://github.com/Quuxplusone/SG14/blob/e0012e6b56/include/sg14/plf_hive.h">https://github.com/Quuxplusone/SG14/blob/e0012e6b56/include/sg14/plf_hive.h</a>
   <dt id="biblio-plfcolony">[PlfColony]
   <dd>Matthew Bentley. <a href="https://github.com/mattreecebentley/plf_colony/issues?q=is%3Aissue"><cite>plf_colony: All Issues</cite></a>. August 2016–April 2022. URL: <a href="https://github.com/mattreecebentley/plf_colony/issues?q=is%3Aissue">https://github.com/mattreecebentley/plf_colony/issues?q=is%3Aissue</a>
   <dt id="biblio-plfstack">[PlfStack]
   <dd>Etienne Parmentier; Matthew Bentley. <a href="https://github.com/mattreecebentley/plf_stack/issues/1"><cite>plf_stack: change_group_sizes and related functions not available</cite></a>. November 2020. URL: <a href="https://github.com/mattreecebentley/plf_stack/issues/1">https://github.com/mattreecebentley/plf_stack/issues/1</a>
  </dl>