<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.10">
<meta name="author" content="Rene Rivera">
<meta name="copyright" content="Copyright 2019 Rene Rivera">
<title>Member Layout Control</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment @import statement to use as custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite::before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
:not(pre)>code.nobreak{word-wrap:normal}
:not(pre)>code.nowrap{white-space:nowrap}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details>summary:first-of-type{cursor:pointer;display:list-item;outline:none;margin-bottom:.75em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class="highlight"],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos{border-right:1px solid currentColor;opacity:.35;padding-right:.5em}
pre.pygments .lineno{border-right:1px solid currentColor;opacity:.35;display:inline-block;margin-right:.75em}
pre.pygments .lineno::before{content:"";margin-right:-.125em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
table.tableblock{max-width:100%;border-collapse:separate}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
td.tableblock>.content>:last-child.sidebarblock{margin-bottom:0}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot,table.frame-ends{border-width:1px 0}
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>Member Layout Control</h1>
<div class="details">
<span id="author" class="author">Rene Rivera</span><br>
<span id="email" class="email"><a href="mailto:grafikrobot@gmail.com">grafikrobot@gmail.com</a></span><br>
<span id="revnumber"> P1605R0,</span>
<span id="revdate">2020-02-21</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#_abstract">1. Abstract</a></li>
<li><a href="#_changes">2. Changes</a></li>
<li><a href="#_introduction">3. Introduction</a></li>
<li><a href="#_proposal">4. Proposal</a></li>
<li><a href="#_proposed_wording">5. Proposed Wording</a></li>
<li><a href="#_design_decisions_and_considerations">6. Design Decisions and Considerations</a></li>
<li><a href="#_acknowledgements">7. Acknowledgements</a></li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<style>
/*
Copyright ene Rivera 2019
Use, modification and distribution are subject to the
Boost Software License, Version 1.0. (See accompanying file
LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/

.admonitionblock .icon .title {
    font-size: 2.5em;
    text-shadow: 1px 1px 2px rgba(0, 0, 0, .5);
}
.caution .icon .title {
    color: rgba(192, 51, 0, 1);
}
.important .icon .title {
    color: rgba(192, 0, 0, 1);
}
.note .icon .title {
    color: rgba(26, 64, 128, 1);
}
.tip .icon .title {
    color: rgba(255, 192, 0, 1);
}
.warning .icon .title {
    color: rgba(192, 102, 0, 1);
}
.hdlist p {
    margin-bottom: 0.25rem;
}
td.hdlist1, td.hdlist2 {
    padding-bottom: 0;
}
p,blockquote,dt,td.content,span.alt {
    font-size: 1.1rem
}
h1, h2, h3, h4, h5, h6 {
    font-weight: bold;
}
h1 {
    font-size: 2.25em;
}
h2 {
    font-size: 1.5em;
}
h3,#toctitle,.sidebarblock>.content>.title {
    font-size: 1.3em;
}
h4, h5 {
    font-size: 1.2em;
}
h6 {
    font-size: 1.1em;
}
div.compare-before {
    width: 49%;
    display: inline-block;
    vertical-align: top;
}
div.compare-after {
    width: 49%;
    display: inline-block;
    vertical-align: top;
}
.del, .del code {
    text-decoration: line-through !important;
    background-color: #FFA0A0 !important;
}
.ins, .ins code {
    background-color: rgb(200, 250, 200) !important;
    /* color: rgb(0, 136, 0) !important; */
    text-decoration: underline !important;
}
</style>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Document number
</td>
<td class="hdlist2">
<p>ISO/IEC/JTC1/SC22/WG21/P1605R0</p>
</td>
</tr>
<tr>
<td class="hdlist1">
Date
</td>
<td class="hdlist2">
<p>2020-02-21</p>
</td>
</tr>
<tr>
<td class="hdlist1">
Reply-to
</td>
<td class="hdlist2">
<p>Rene Rivera, <a href="mailto:grafikrobot@gmail.com">grafikrobot@gmail.com</a></p>
</td>
</tr>
<tr>
<td class="hdlist1">
Audience
</td>
<td class="hdlist2">
<p>WG21</p>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_abstract"><a class="anchor" href="#_abstract"></a>1. Abstract</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This proposes to add a core language facility to control the class data member
order layout without otherwise impacting class definitions.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_changes"><a class="anchor" href="#_changes"></a>2. Changes</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_r0_initial"><a class="anchor" href="#_r0_initial"></a>2.1. R0 (Initial)</h3>
<div class="paragraph">
<p>Initial content without standard wording.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_introduction"><a class="anchor" href="#_introduction"></a>3. Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In many domains where C++ thrives there is a contention with the desire
for optimal data and code vs clear definitions. It is a desire that is
hampered by the member layout rules in C++. Developers are faced
with the choice of having well grouped and relevant information in class
definitions and suboptimal memory use, or having memory use and incoherent
class definitions. This proposal aims to add a facility to reconcile both
goals of class design. This proposal hopes to achieve these goals:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Fine grain member layout control.</p>
</li>
<li>
<p>Keep member access control for access control.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To solve the problem we need to first see the problem. We can use a working
example to work through what we need to address. Let start with a common
use case of having a class with flags and values to enable/disable
different features of it (highly abstracted):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">class</span> <span class="tok-nc">A</span>
<span class="tok-p">{</span>
    <span class="tok-k">public</span><span class="tok-o">:</span>

    <span class="tok-c1">// Feature A allows for using A.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_a_enabled</span>
    <span class="tok-c1">// == true. The feature_a_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,15000].</span>

    <span class="tok-kt">bool</span> <span class="tok-n">feature_a_enabled</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-n">feature_a_value</span><span class="tok-p">;</span>

    <span class="tok-c1">// Feature B allows for using B.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_b_enabled</span>
    <span class="tok-c1">// == true. The feature_b_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,60000].</span>

    <span class="tok-kt">bool</span> <span class="tok-n">feature_b_enabled</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-n">feature_b_value</span><span class="tok-p">;</span>
<span class="tok-p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>We can also look at a likely function that uses the members to do a
calculation. In this case we&#8217;ll look at minimal function:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-nf">A_q</span><span class="tok-p">(</span><span class="tok-n">A</span> <span class="tok-k">const</span> <span class="tok-o">&amp;</span> <span class="tok-n">a</span><span class="tok-p">)</span>
<span class="tok-p">{</span>
    <span class="tok-k">return</span> <span class="tok-n">a</span><span class="tok-p">.</span><span class="tok-n">feature_a_value</span> <span class="tok-o">+</span> <span class="tok-n">a</span><span class="tok-p">.</span><span class="tok-n">feature_b_value</span><span class="tok-p">;</span>
<span class="tok-p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>As expected the resulting assembly code for this is minimal and efficient:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="nasm"><span></span><span class="tok-nf">A_q</span><span class="tok-p">(</span><span class="tok-nv">A</span> <span class="tok-nv">const</span><span class="tok-o">&amp;</span><span class="tok-p">):</span>
  <span class="tok-nf">mov</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">DWORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">4</span><span class="tok-p">]</span>
  <span class="tok-nf">add</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">DWORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">12</span><span class="tok-p">]</span>
  <span class="tok-nf">ret</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The problem comes in when we look at the data size of the class:</p>
</div>
<div class="listingblock text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">)</span> <span class="tok-o">==</span> <span class="tok-mi">16</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Sixteen bytes might seem small. But if we are dealing with a large number
items the data size becomes a serious consideration:</p>
</div>
<div class="listingblock text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">[</span><span class="tok-mi">1024</span><span class="tok-o">*</span><span class="tok-mi">1024</span><span class="tok-p">])</span> <span class="tok-o">==</span> <span class="tok-mi">16777216</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>When faced with that result and the constraints of some systems, say an
embedded system with only 64MiB of total RAM, having one data structure
take up 1/3 of your system is not acceptable. And programmers have used
various techniques to ameliorate such waste. The most common being rearranging
members to minimize the alignment padding. For our example we can place the
<code>bool</code> members last and together to allow all the members to be packed:</p>
</div>
<div class="listingblock compare-before">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">class</span> <span class="tok-nc">A</span>
<span class="tok-p">{</span>
    <span class="tok-k">public</span><span class="tok-o">:</span>

    <span class="tok-c1">// Feature A allows for using A.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_a_enabled</span>
    <span class="tok-c1">// == true. The feature_a_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,15000].</span>

    <span class="tok-kt">bool</span> <span class="tok-n">feature_a_enabled</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-n">feature_a_value</span><span class="tok-p">;</span>

    <span class="tok-c1">// Feature B allows for using B.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_b_enabled</span>
    <span class="tok-c1">// == true. The feature_b_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,60000].</span>

    <span class="tok-kt">bool</span> <span class="tok-n">feature_b_enabled</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-n">feature_b_value</span><span class="tok-p">;</span>
<span class="tok-p">};</span></code></pre>
</div>
</div>
<div class="listingblock compare-after">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">class</span> <span class="tok-nc">A</span>
<span class="tok-p">{</span>
    <span class="tok-k">public</span><span class="tok-o">:</span>

    <span class="tok-c1">// Feature A allows for using A.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_a_enabled</span>
    <span class="tok-c1">// == true. The feature_a_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,15000].</span>

    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-n">feature_a_value</span><span class="tok-p">;</span>

    <span class="tok-c1">// Feature B allows for using B.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_b_enabled</span>
    <span class="tok-c1">// == true. The feature_b_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,60000].</span>

    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-n">feature_b_value</span><span class="tok-p">;</span>

    <span class="tok-kt">bool</span> <span class="tok-n">feature_a_enabled</span><span class="tok-p">;</span>
    <span class="tok-kt">bool</span> <span class="tok-n">feature_b_enabled</span><span class="tok-p">;</span>
<span class="tok-p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>With that arrangement we still have the minimal, optimal, access for our
prototypical <code>A_q</code> function:</p>
</div>
<div class="listingblock compare-before">
<div class="content">
<pre class="pygments highlight"><code data-lang="nasm"><span></span><span class="tok-nf">A_q</span><span class="tok-p">(</span><span class="tok-nv">A</span> <span class="tok-nv">const</span><span class="tok-o">&amp;</span><span class="tok-p">):</span>
  <span class="tok-nf">mov</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">DWORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">4</span><span class="tok-p">]</span>
  <span class="tok-nf">add</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">DWORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">12</span><span class="tok-p">]</span>
  <span class="tok-nf">ret</span></code></pre>
</div>
</div>
<div class="listingblock compare-after">
<div class="content">
<pre class="pygments highlight"><code data-lang="nasm"><span></span><span class="tok-nf">A_q</span><span class="tok-p">(</span><span class="tok-nv">A</span> <span class="tok-nv">const</span><span class="tok-o">&amp;</span><span class="tok-p">):</span>
  <span class="tok-nf">mov</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">DWORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-p">]</span>
  <span class="tok-nf">add</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">DWORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">4</span><span class="tok-p">]</span>
  <span class="tok-nf">ret</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>But more importantly we&#8217;ve reduced the overall size of the structure.</p>
</div>
<div class="listingblock compare-before text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">)</span> <span class="tok-o">==</span> <span class="tok-mi">16</span></code></pre>
</div>
</div>
<div class="listingblock compare-after text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">)</span> <span class="tok-o">==</span> <span class="tok-mi">12</span></code></pre>
</div>
</div>
<div class="listingblock compare-before text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">[</span><span class="tok-mi">1024</span><span class="tok-o">*</span><span class="tok-mi">1024</span><span class="tok-p">])</span> <span class="tok-o">==</span> <span class="tok-mi">16777216</span></code></pre>
</div>
</div>
<div class="listingblock compare-after text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">[</span><span class="tok-mi">1024</span><span class="tok-o">*</span><span class="tok-mi">1024</span><span class="tok-p">])</span> <span class="tok-o">==</span> <span class="tok-mi">12582912</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This only works when we restrict ourselves to follow the
ORDERRULE <sup class="footnote" id="_footnote_ORDERRULE">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.
Which is not always possible, and almost always not desired. We can go further
in our space saving though. We can turn the data structure into a bitfield
since we know the numerical limits of all our data members. And with some
trial and error, and some knowledge of what compiler and system we are
supporting can further optimize not just the size but minimize the impact
this will have on the generated code. We can therefore do the following:</p>
</div>
<div class="listingblock compare-before">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">class</span> <span class="tok-nc">A</span>
<span class="tok-p">{</span>
    <span class="tok-k">public</span><span class="tok-o">:</span>

    <span class="tok-c1">// Feature A allows for using A.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_a_enabled</span>
    <span class="tok-c1">// == true. The feature_a_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,15000].</span>

    <span class="tok-kt">bool</span> <span class="tok-n">feature_a_enabled</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-n">feature_a_value</span><span class="tok-p">;</span>

    <span class="tok-c1">// Feature B allows for using B.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_b_enabled</span>
    <span class="tok-c1">// == true. The feature_b_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,60000].</span>

    <span class="tok-kt">bool</span> <span class="tok-n">feature_b_enabled</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-n">feature_b_value</span><span class="tok-p">;</span>
<span class="tok-p">};</span></code></pre>
</div>
</div>
<div class="listingblock compare-after">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">class</span> <span class="tok-nc">A</span>
<span class="tok-p">{</span>
    <span class="tok-k">public</span><span class="tok-o">:</span>

    <span class="tok-c1">// Feature A allows for using A.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_a_enabled</span>
    <span class="tok-c1">// == true. The feature_a_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,15000].</span>


    <span class="tok-c1">// Feature B allows for using B.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_b_enabled</span>
    <span class="tok-c1">// == true. The feature_b_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,60000].</span>

    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-nl">feature_b_value</span><span class="tok-p">:</span><span class="tok-mi">16</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-nl">feature_a_value</span><span class="tok-p">:</span><span class="tok-mi">14</span><span class="tok-p">;</span>
    <span class="tok-kt">bool</span> <span class="tok-nl">feature_a_enabled</span><span class="tok-p">:</span><span class="tok-mi">1</span><span class="tok-p">;</span>
    <span class="tok-kt">bool</span> <span class="tok-nl">feature_b_enabled</span><span class="tok-p">:</span><span class="tok-mi">1</span><span class="tok-p">;</span>
<span class="tok-p">};</span></code></pre>
</div>
</div>
<div class="listingblock compare-before">
<div class="content">
<pre class="pygments highlight"><code data-lang="nasm"><span></span><span class="tok-nf">A_q</span><span class="tok-p">(</span><span class="tok-nv">A</span> <span class="tok-nv">const</span><span class="tok-o">&amp;</span><span class="tok-p">):</span>
  <span class="tok-nf">mov</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">DWORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">4</span><span class="tok-p">]</span>
  <span class="tok-nf">add</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">DWORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">12</span><span class="tok-p">]</span>
  <span class="tok-nf">ret</span></code></pre>
</div>
</div>
<div class="listingblock compare-after">
<div class="content">
<pre class="pygments highlight"><code data-lang="nasm"><span></span><span class="tok-nf">AA_q</span><span class="tok-p">(</span><span class="tok-nv">A</span> <span class="tok-nv">const</span><span class="tok-o">&amp;</span><span class="tok-p">):</span>
  <span class="tok-nf">movzx</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">WORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">2</span><span class="tok-p">]</span>
  <span class="tok-nf">movzx</span> <span class="tok-nb">edx</span><span class="tok-p">,</span> <span class="tok-kt">WORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-p">]</span>
  <span class="tok-nf">and</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-mi">16383</span>
  <span class="tok-nf">add</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-nb">edx</span>
  <span class="tok-nf">ret</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Even though we&#8217;ve added some instructions to deal with the bit field we are
still rather optimal in our access. What do we gain in terms of size?</p>
</div>
<div class="listingblock compare-before text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">)</span> <span class="tok-o">==</span> <span class="tok-mi">16</span></code></pre>
</div>
</div>
<div class="listingblock compare-after text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">)</span> <span class="tok-o">==</span> <span class="tok-mi">4</span></code></pre>
</div>
</div>
<div class="listingblock compare-before text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">[</span><span class="tok-mi">1024</span><span class="tok-o">*</span><span class="tok-mi">1024</span><span class="tok-p">])</span> <span class="tok-o">==</span> <span class="tok-mi">16777216</span></code></pre>
</div>
</div>
<div class="listingblock compare-after text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">[</span><span class="tok-mi">1024</span><span class="tok-o">*</span><span class="tok-mi">1024</span><span class="tok-p">])</span> <span class="tok-o">==</span> <span class="tok-mi">4194304</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This is a now in the palatable range.. We are tracking 1MiB objects in 4MiB.
This, of course, comes at a price. We have now entirely detached the
documentation in the class with the members they refer to. And making it even
worse, the members are seemingly randomly arranged for the casual observer.
This is ripe for causing all kinds of future maintenance problems for
whomever is trying to understand this code.</p>
</div>
<div class="paragraph">
<p>There has been at least one previous attempt to solve this problem. P1112
<sup class="footnote" id="_footnote_P1112">[<a id="_footnoteref_2" class="footnote" href="#_footnotedef_2" title="View footnote.">2</a>]</sup>
proposes a class level attribute to classify the kind of member layout to
apply.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_proposal"><a class="anchor" href="#_proposal"></a>4. Proposal</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We propose adding an optional <code>layout:</code> labeled section to class definitions
wherein one list the order of members, already declared, in the class. The
<code>layout:</code> section would:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>List the names of any members one wishes to specific the order of.</p>
</li>
<li>
<p>Members listed would come first in the class member layout.</p>
</li>
<li>
<p>Members not listed would follow with the existing layout rules.</p>
</li>
<li>
<p>Member layout order does not alter initialization.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To continue with our example from above, the new class declaration using this
feature could be:</p>
</div>
<div class="listingblock compare-before">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">class</span> <span class="tok-nc">A</span>
<span class="tok-p">{</span>
    <span class="tok-k">public</span><span class="tok-o">:</span>

    <span class="tok-c1">// Feature A allows for using A.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_a_enabled</span>
    <span class="tok-c1">// == true. The feature_a_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,15000].</span>

    <span class="tok-c1">// Feature B allows for using B.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_b_enabled</span>
    <span class="tok-c1">// == true. The feature_b_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,60000].</span>

    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-nl">feature_b_value</span><span class="tok-p">:</span><span class="tok-mi">16</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-nl">feature_a_value</span><span class="tok-p">:</span><span class="tok-mi">14</span><span class="tok-p">;</span>
    <span class="tok-kt">bool</span> <span class="tok-nl">feature_a_enabled</span><span class="tok-p">:</span><span class="tok-mi">1</span><span class="tok-p">;</span>
    <span class="tok-kt">bool</span> <span class="tok-nl">feature_b_enabled</span><span class="tok-p">:</span><span class="tok-mi">1</span><span class="tok-p">;</span>
<span class="tok-p">};</span></code></pre>
</div>
</div>
<div class="listingblock compare-after">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">class</span> <span class="tok-nc">A</span>
<span class="tok-p">{</span>
    <span class="tok-k">public</span><span class="tok-o">:</span>

    <span class="tok-c1">// Feature A allows for using A.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_a_enabled</span>
    <span class="tok-c1">// == true. The feature_a_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,15000].</span>

    <span class="tok-kt">bool</span> <span class="tok-nl">feature_a_enabled</span><span class="tok-p">:</span><span class="tok-mi">1</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-nl">feature_a_value</span><span class="tok-p">:</span><span class="tok-mi">14</span><span class="tok-p">;</span>

    <span class="tok-c1">// Feature B allows for using B.</span>
    <span class="tok-c1">// This feature is optional and</span>
    <span class="tok-c1">// is used when feature_b_enabled</span>
    <span class="tok-c1">// == true. The feature_b_value</span>
    <span class="tok-c1">// is a value in the range</span>
    <span class="tok-c1">// [0,60000].</span>

    <span class="tok-kt">bool</span> <span class="tok-nl">feature_b_enabled</span><span class="tok-p">:</span><span class="tok-mi">1</span><span class="tok-p">;</span>
    <span class="tok-kt">unsigned</span> <span class="tok-kt">int</span> <span class="tok-nl">feature_b_value</span><span class="tok-p">:</span><span class="tok-mi">16</span><span class="tok-p">;</span>

    <span class="tok-nl">layout</span><span class="tok-p">:</span>

    <span class="tok-c1">// This layout gives us a 4 byte</span>
    <span class="tok-c1">// structure size with minimal</span>
    <span class="tok-c1">// additional access instructions.</span>
    <span class="tok-c1">// When compiling with x86-64</span>
    <span class="tok-c1">// gcc 9.2 with -O3.</span>

    <span class="tok-n">feature_b_value</span><span class="tok-p">;</span>
    <span class="tok-n">feature_a_value</span><span class="tok-p">;</span>
    <span class="tok-n">feature_a_enabled</span><span class="tok-p">;</span>
    <span class="tok-n">feature_b_enabled</span><span class="tok-p">;</span>
<span class="tok-p">};</span></code></pre>
</div>
</div>
<div class="listingblock compare-before">
<div class="content">
<pre class="pygments highlight"><code data-lang="nasm"><span></span><span class="tok-nf">A_q</span><span class="tok-p">(</span><span class="tok-nv">A</span> <span class="tok-nv">const</span><span class="tok-o">&amp;</span><span class="tok-p">):</span>
  <span class="tok-nf">movzx</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">WORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">2</span><span class="tok-p">]</span>
  <span class="tok-nf">movzx</span> <span class="tok-nb">edx</span><span class="tok-p">,</span> <span class="tok-kt">WORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-p">]</span>
  <span class="tok-nf">and</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-mi">16383</span>
  <span class="tok-nf">add</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-nb">edx</span>
  <span class="tok-nf">ret</span></code></pre>
</div>
</div>
<div class="listingblock compare-after">
<div class="content">
<pre class="pygments highlight"><code data-lang="nasm"><span></span><span class="tok-nf">A_q</span><span class="tok-p">(</span><span class="tok-nv">A</span> <span class="tok-nv">const</span><span class="tok-o">&amp;</span><span class="tok-p">):</span>
  <span class="tok-nf">movzx</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-kt">WORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-o">+</span><span class="tok-mi">2</span><span class="tok-p">]</span>
  <span class="tok-nf">movzx</span> <span class="tok-nb">edx</span><span class="tok-p">,</span> <span class="tok-kt">WORD</span> <span class="tok-nv">PTR</span> <span class="tok-p">[</span><span class="tok-nb">rdi</span><span class="tok-p">]</span>
  <span class="tok-nf">and</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-mi">16383</span>
  <span class="tok-nf">add</span> <span class="tok-nb">eax</span><span class="tok-p">,</span> <span class="tok-nb">edx</span>
  <span class="tok-nf">ret</span></code></pre>
</div>
</div>
<div class="listingblock compare-before text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">)</span> <span class="tok-o">==</span> <span class="tok-mi">4</span></code></pre>
</div>
</div>
<div class="listingblock compare-after text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">)</span> <span class="tok-o">==</span> <span class="tok-mi">4</span></code></pre>
</div>
</div>
<div class="listingblock compare-before text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">[</span><span class="tok-mi">1024</span><span class="tok-o">*</span><span class="tok-mi">1024</span><span class="tok-p">])</span> <span class="tok-o">==</span> <span class="tok-mi">4194304</span></code></pre>
</div>
</div>
<div class="listingblock compare-after text-center">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">A</span><span class="tok-p">[</span><span class="tok-mi">1024</span><span class="tok-o">*</span><span class="tok-mi">1024</span><span class="tok-p">])</span> <span class="tok-o">==</span> <span class="tok-mi">4194304</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>As we can see the effect of optimizing the layout for the application use case
is preserved. But the drawbacks of the optimization are removed. The <code>layout:</code>
now contains the the members of the class in the order we require they be in.</p>
</div>
<div class="paragraph">
<p>Features of this proposal:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Puts the control of member layout where it matters, in the user&#8217;s hands.
Where the particular tradeoffs of memory vs. performance can be made.</p>
</li>
<li>
<p>The layout can&#8217;t be ignored by the compiler and hence provides ABI stability
across compiler version and possibly across compilers.</p>
</li>
<li>
<p>Coexists with existing <code>#pragma pack</code> compiler feature as it makes the
ordering orthogonal from the packing.</p>
</li>
<li>
<p>Doesn&#8217;t override alignment and addressing requirements, again, because
the ordering control is orthogonal. For example from use of <code>alignas</code>.</p>
</li>
<li>
<p>Simple, minimal, and clear syntax makes it easy to understand intent and
effect.</p>
</li>
<li>
<p>Allows control of individual bit-field members within the same syntax as
other members.</p>
</li>
<li>
<p>The layout declarations can be easily documented to provide rationales for
users of the class.</p>
</li>
<li>
<p>Does not, definitionally, force override ordering of all members and hence
allows for minimal targeted optimizations.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_proposed_wording"><a class="anchor" href="#_proposed_wording"></a>5. Proposed Wording</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To be determined.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_design_decisions_and_considerations"><a class="anchor" href="#_design_decisions_and_considerations"></a>6. Design Decisions and Considerations</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_why_not_have_algorithmic_layouts"><a class="anchor" href="#_why_not_have_algorithmic_layouts"></a>6.1. Why not have algorithmic layouts?</h3>
<div class="paragraph">
<p>P1112 <sup class="footnoteref">[<a class="footnote" href="#_footnotedef_2" title="View footnote.">2</a>]</sup> proposes a mechanism to have "smart" algorithmic layout
control. It proposes to add a <code>[[layout(?)]]</code> attribute to the class to select
from an existing set of algorithmic layouts like: <code>smallest</code>, <code>declorder</code>,
<code>cacheline</code>, and so on. A key problem with an algorithmic approach is the
increased risk of ABI violations as pointed out in P1112.<sup class="footnoteref">[<a class="footnote" href="#_footnotedef_2" title="View footnote.">2</a>]</sup>
Dealing with the C++ ABI is difficult enough as it is. We would like to
avoid adding to the uncertainly and complexity of the C++ ABI.</p>
</div>
</div>
<div class="sect2">
<h3 id="_should_alignment_control_be_allowed_in_the_layout_declarations"><a class="anchor" href="#_should_alignment_control_be_allowed_in_the_layout_declarations"></a>6.2. Should alignment control be allowed in the layout declarations?</h3>
<div class="paragraph">
<p>We need to consider if other member data specifications that affect size of
the class should be consolidated, i.e. allowed, in the layout declaration
section. For example <code>alignas</code> could be allowed as such:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">class</span> <span class="tok-nc">A</span>
<span class="tok-p">{</span>
    <span class="tok-k">public</span><span class="tok-o">:</span>

    <span class="tok-kt">bool</span> <span class="tok-n">a_f</span><span class="tok-p">;</span>
    <span class="tok-kt">int</span> <span class="tok-n">a</span><span class="tok-p">;</span>
    <span class="tok-kt">bool</span> <span class="tok-n">b_f</span><span class="tok-p">;</span>
    <span class="tok-kt">int</span> <span class="tok-n">b</span><span class="tok-p">;</span>

    <span class="tok-nl">layout</span><span class="tok-p">:</span>

    <span class="tok-n">a</span><span class="tok-p">;</span>
    <span class="tok-k">alignas</span><span class="tok-p">(</span><span class="tok-mi">16</span><span class="tok-p">)</span> <span class="tok-n">b</span><span class="tok-p">;</span>
    <span class="tok-n">a_f</span><span class="tok-p">;</span>
    <span class="tok-n">b_f</span><span class="tok-p">;</span>
<span class="tok-p">};</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_should_layout_order_be_reflect_ed"><a class="anchor" href="#_should_layout_order_be_reflect_ed"></a>6.3. Should layout order be reflect-ed?</h3>
<div class="paragraph">
<p>There needs to be some thought and consideration given to how layout ordering
can or should be available through reflection.</p>
</div>
</div>
<div class="sect2">
<h3 id="_should_we_additionally_specify_padding_options"><a class="anchor" href="#_should_we_additionally_specify_padding_options"></a>6.4. Should we additionally specify padding options?</h3>
<div class="paragraph">
<p>It would be interesting to consider adding syntax to formalize both general
and specific inter-member padding. I.e. it could be of benefit to extend this
proposal to formalize and improve the common <code>#pragma pack</code> feature.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_acknowledgements"><a class="anchor" href="#_acknowledgements"></a>7. Acknowledgements</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Thanks to Michael Shoell who, through varied lunch conversations, provided the
impetus for this proposal.</p>
</div>
</div>
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnotedef_1">
<a href="#_footnoteref_1">1</a>. <a href="http://eel.is/c++draft/class.mem#19">class.mem p19</a>&#8201;&#8212;&#8201;  Non-static data members of a (non-union) class with the same access   control and non-zero size ([intro.object]) are allocated so that later   members have higher addresses within a class object. The order of allocation   of non-static data members with different access control is unspecified.   Implementation alignment requirements might cause two adjacent members not to   be allocated immediately after each other; so might requirements for space for managing virtual functions ([class.virtual]) and virtual base classes   ([class.mi]).
</div>
<div class="footnote" id="_footnotedef_2">
<a href="#_footnoteref_2">2</a>. <a href="https://wg21.link/p1112">P1112</a>&#8201;&#8212;&#8201;  <em>Language support for class layout control</em>, Pal Balog
</div>
</div>
<style>
pre.pygments .hll { background-color: #ffffcc }
pre.pygments  { background: #f0f0f0; }
pre.pygments .tok-c { color: #60a0b0; font-style: italic } /* Comment */
pre.pygments .tok-err { border: 1px solid #FF0000 } /* Error */
pre.pygments .tok-k { color: #007020; font-weight: bold } /* Keyword */
pre.pygments .tok-o { color: #666666 } /* Operator */
pre.pygments .tok-ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
pre.pygments .tok-cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
pre.pygments .tok-cp { color: #007020 } /* Comment.Preproc */
pre.pygments .tok-cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
pre.pygments .tok-c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
pre.pygments .tok-cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
pre.pygments .tok-gd { color: #A00000 } /* Generic.Deleted */
pre.pygments .tok-ge { font-style: italic } /* Generic.Emph */
pre.pygments .tok-gr { color: #FF0000 } /* Generic.Error */
pre.pygments .tok-gh { color: #000080; font-weight: bold } /* Generic.Heading */
pre.pygments .tok-gi { color: #00A000 } /* Generic.Inserted */
pre.pygments .tok-go { color: #888888 } /* Generic.Output */
pre.pygments .tok-gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
pre.pygments .tok-gs { font-weight: bold } /* Generic.Strong */
pre.pygments .tok-gu { color: #800080; font-weight: bold } /* Generic.Subheading */
pre.pygments .tok-gt { color: #0044DD } /* Generic.Traceback */
pre.pygments .tok-kc { color: #007020; font-weight: bold } /* Keyword.Constant */
pre.pygments .tok-kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
pre.pygments .tok-kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
pre.pygments .tok-kp { color: #007020 } /* Keyword.Pseudo */
pre.pygments .tok-kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
pre.pygments .tok-kt { color: #902000 } /* Keyword.Type */
pre.pygments .tok-m { color: #40a070 } /* Literal.Number */
pre.pygments .tok-s { color: #4070a0 } /* Literal.String */
pre.pygments .tok-na { color: #4070a0 } /* Name.Attribute */
pre.pygments .tok-nb { color: #007020 } /* Name.Builtin */
pre.pygments .tok-nc { color: #0e84b5; font-weight: bold } /* Name.Class */
pre.pygments .tok-no { color: #60add5 } /* Name.Constant */
pre.pygments .tok-nd { color: #555555; font-weight: bold } /* Name.Decorator */
pre.pygments .tok-ni { color: #d55537; font-weight: bold } /* Name.Entity */
pre.pygments .tok-ne { color: #007020 } /* Name.Exception */
pre.pygments .tok-nf { color: #06287e } /* Name.Function */
pre.pygments .tok-nl { color: #002070; font-weight: bold } /* Name.Label */
pre.pygments .tok-nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
pre.pygments .tok-nt { color: #062873; font-weight: bold } /* Name.Tag */
pre.pygments .tok-nv { color: #bb60d5 } /* Name.Variable */
pre.pygments .tok-ow { color: #007020; font-weight: bold } /* Operator.Word */
pre.pygments .tok-w { color: #bbbbbb } /* Text.Whitespace */
pre.pygments .tok-mb { color: #40a070 } /* Literal.Number.Bin */
pre.pygments .tok-mf { color: #40a070 } /* Literal.Number.Float */
pre.pygments .tok-mh { color: #40a070 } /* Literal.Number.Hex */
pre.pygments .tok-mi { color: #40a070 } /* Literal.Number.Integer */
pre.pygments .tok-mo { color: #40a070 } /* Literal.Number.Oct */
pre.pygments .tok-sa { color: #4070a0 } /* Literal.String.Affix */
pre.pygments .tok-sb { color: #4070a0 } /* Literal.String.Backtick */
pre.pygments .tok-sc { color: #4070a0 } /* Literal.String.Char */
pre.pygments .tok-dl { color: #4070a0 } /* Literal.String.Delimiter */
pre.pygments .tok-sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
pre.pygments .tok-s2 { color: #4070a0 } /* Literal.String.Double */
pre.pygments .tok-se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
pre.pygments .tok-sh { color: #4070a0 } /* Literal.String.Heredoc */
pre.pygments .tok-si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
pre.pygments .tok-sx { color: #c65d09 } /* Literal.String.Other */
pre.pygments .tok-sr { color: #235388 } /* Literal.String.Regex */
pre.pygments .tok-s1 { color: #4070a0 } /* Literal.String.Single */
pre.pygments .tok-ss { color: #517918 } /* Literal.String.Symbol */
pre.pygments .tok-bp { color: #007020 } /* Name.Builtin.Pseudo */
pre.pygments .tok-fm { color: #06287e } /* Name.Function.Magic */
pre.pygments .tok-vc { color: #bb60d5 } /* Name.Variable.Class */
pre.pygments .tok-vg { color: #bb60d5 } /* Name.Variable.Global */
pre.pygments .tok-vi { color: #bb60d5 } /* Name.Variable.Instance */
pre.pygments .tok-vm { color: #bb60d5 } /* Name.Variable.Magic */
pre.pygments .tok-il { color: #40a070 } /* Literal.Number.Integer.Long */
</style>
</body>
</html>