<!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, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="mobile-web-app-capable" content="yes">
    <title>
        Structured binding declaration as a _condition_ - HackMD
    </title>
    <link rel="icon" type="image/png" href="https://hackmd.io/favicon.png">
    <link rel="apple-touch-icon" href="https://hackmd.io/apple-touch-icon.png">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha256-916EbMg70RQy9LHiGkXzG8hSg9EdNy97GazNG/aiY1w=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha256-eZrrJcwDc/3uDhsdt61sL2oOBY362qM3lon1gyExkL0=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css" integrity="sha256-3iu9jgsy9TpTwXKb7bNQzqWekRX7pPK+2OLj3R922fo=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/octicons/3.5.0/octicons.min.css" integrity="sha256-QiWfLIsCT02Sdwkogf6YMiQlj4NE84MKkzEMkZnMGdg=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.1/themes/prism.min.css" integrity="sha256-vtR0hSWRc3Tb26iuN2oZHt3KRUomwTufNIf5/4oeCyg=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@hackmd/emojify.js@2.1.0/dist/css/basic/emojify.min.css" integrity="sha256-UOrvMOsSDSrW6szVLe8ZDZezBxh5IoIfgTwdNDgTjiU=" crossorigin="anonymous" />
    <style>
        @import url(https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,500,500i|Source+Code+Pro:300,400,500|Source+Sans+Pro:300,300i,400,400i,600,600i|Source+Serif+Pro&subset=latin-ext);.hljs{background:#fff;color:#333;display:block;overflow-x:auto;padding:.5em}.hljs-comment,.hljs-meta{color:#969896}.hljs-emphasis,.hljs-quote,.hljs-string,.hljs-strong,.hljs-template-variable,.hljs-variable{color:#df5000}.hljs-keyword,.hljs-selector-tag,.hljs-type{color:#a71d5d}.hljs-attribute,.hljs-bullet,.hljs-literal,.hljs-number,.hljs-symbol{color:#0086b3}.hljs-built_in,.hljs-builtin-name{color:#005cc5}.hljs-name,.hljs-section{color:#63a35c}.hljs-tag{color:#333}.hljs-attr,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-title{color:#795da3}.hljs-addition{background-color:#eaffea;color:#55a532}.hljs-deletion{background-color:#ffecec;color:#bd2c00}.hljs-link{text-decoration:underline}.markdown-body{word-wrap:break-word;font-size:16px;line-height:1.5}.markdown-body:after,.markdown-body:before{content:"";display:table}.markdown-body:after{clear:both}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .absent{color:#c00}.markdown-body .anchor{float:left;line-height:1;margin-left:-20px;padding-right:4px}.markdown-body .anchor:focus{outline:none}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-bottom:16px;margin-top:0}.markdown-body hr{background-color:#e7e7e7;border:0;height:.25em;margin:24px 0;padding:0}.markdown-body blockquote{border-left:.25em solid #ddd;color:#777;font-size:16px;padding:0 1em}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body kbd,.popover kbd{background-color:#fcfcfc;border:1px solid;border-color:#ccc #ccc #bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb;color:#555;display:inline-block;font-size:11px;line-height:10px;padding:3px 5px;vertical-align:middle}.markdown-body .loweralpha{list-style-type:lower-alpha}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{font-weight:600;line-height:1.25;margin-bottom:16px;margin-top:24px}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#000;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1 code,.markdown-body h1 tt,.markdown-body h2 code,.markdown-body h2 tt,.markdown-body h3 code,.markdown-body h3 tt,.markdown-body h4 code,.markdown-body h4 tt,.markdown-body h5 code,.markdown-body h5 tt,.markdown-body h6 code,.markdown-body h6 tt{font-size:inherit}.markdown-body h1{font-size:2em}.markdown-body h1,.markdown-body h2{border-bottom:1px solid #eee;padding-bottom:.3em}.markdown-body h2{font-size:1.5em}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:.875em}.markdown-body h6{color:#777;font-size:.85em}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol.no-list,.markdown-body ul.no-list{list-style-type:none;padding:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-bottom:0;margin-top:0}.markdown-body li>p{margin-top:16px}.markdown-body li+li{padding-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{font-size:1em;font-style:italic;font-weight:700;margin-top:16px;padding:0}.markdown-body dl dd{margin-bottom:16px;padding:0 16px}.markdown-body table{display:block;overflow:auto;width:100%;word-break:normal;word-break:keep-all}.markdown-body table th{font-weight:700}.markdown-body table td,.markdown-body table th{border:1px solid #ddd;padding:6px 13px}.markdown-body table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-body table tr:nth-child(2n){background-color:#f8f8f8}.markdown-body img{background-color:#fff;box-sizing:initial;max-width:100%}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body .emoji{background-color:initial;max-width:none;vertical-align:text-top}.markdown-body span.frame{display:block;overflow:hidden}.markdown-body span.frame>span{border:1px solid #ddd;display:block;float:left;margin:13px 0 0;overflow:hidden;padding:7px;width:auto}.markdown-body span.frame span img{display:block;float:left}.markdown-body span.frame span span{clear:both;color:#333;display:block;padding:5px 0 0}.markdown-body span.align-center{clear:both;display:block;overflow:hidden}.markdown-body span.align-center>span{display:block;margin:13px auto 0;overflow:hidden;text-align:center}.markdown-body span.align-center span img{margin:0 auto;text-align:center}.markdown-body span.align-right{clear:both;display:block;overflow:hidden}.markdown-body span.align-right>span{display:block;margin:13px 0 0;overflow:hidden;text-align:right}.markdown-body span.align-right span img{margin:0;text-align:right}.markdown-body span.float-left{display:block;float:left;margin-right:13px;overflow:hidden}.markdown-body span.float-left span{margin:13px 0 0}.markdown-body span.float-right{display:block;float:right;margin-left:13px;overflow:hidden}.markdown-body span.float-right>span{display:block;margin:13px auto 0;overflow:hidden;text-align:right}.markdown-body code,.markdown-body tt{background-color:#0000000a;border-radius:3px;font-size:85%;margin:0;padding:.2em 0}.markdown-body code:after,.markdown-body code:before,.markdown-body tt:after,.markdown-body tt:before{content:"\00a0";letter-spacing:-.2em}.markdown-body code br,.markdown-body tt br{display:none}.markdown-body del code{text-decoration:inherit}.markdown-body pre{word-wrap:normal}.markdown-body pre>code{background:#0000;border:0;font-size:100%;margin:0;padding:0;white-space:pre;word-break:normal}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{border-radius:3px;font-size:85%;line-height:1.45;overflow:auto}.markdown-body:not(.next-editor) pre{background-color:#f7f7f7;padding:16px}.markdown-body pre code,.markdown-body pre tt{word-wrap:normal;background-color:initial;border:0;display:inline;line-height:inherit;margin:0;max-width:auto;overflow:visible;padding:0}.markdown-body pre code:after,.markdown-body pre code:before,.markdown-body pre tt:after,.markdown-body pre tt:before{content:normal}.markdown-body .csv-data td,.markdown-body .csv-data th{font-size:12px;line-height:1;overflow:hidden;padding:5px;text-align:left;white-space:nowrap}.markdown-body .csv-data .blob-line-num{background:#fff;border:0;padding:10px 8px 9px;text-align:right}.markdown-body .csv-data tr{border-top:0}.markdown-body .csv-data th{background:#f8f8f8;border-top:0;font-weight:700}.news .alert .markdown-body blockquote{border:0;padding:0 0 0 40px}.activity-tab .news .alert .commits,.activity-tab .news .markdown-body blockquote{padding-left:0}.task-list-item{list-style-type:none}.task-list-item label{font-weight:400}.task-list-item.enabled label{cursor:pointer}.task-list-item+.task-list-item{margin-top:3px}.task-list-item-checkbox{cursor:default!important;float:left;margin:.31em 0 .2em -1.3em!important;vertical-align:middle}.markdown-body{max-width:758px;overflow:visible!important;padding-bottom:40px;padding-top:40px;position:relative}.markdown-body.next-editor{overflow-x:hidden!important}.markdown-body .emoji{vertical-align:top}.markdown-body pre{border:inherit!important}.markdown-body code{color:inherit!important}.markdown-body pre code .wrapper{display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex}.markdown-body pre code .gutter{float:left;overflow:hidden;-webkit-user-select:none;user-select:none}.markdown-body pre code .gutter.linenumber{border-right:3px solid #6ce26c!important;box-sizing:initial;color:#afafaf!important;cursor:default;display:inline-block;min-width:20px;padding:0 8px 0 0;position:relative;text-align:right;z-index:4}.markdown-body pre code .gutter.linenumber>span:before{content:attr(data-linenumber)}.markdown-body pre code .code{float:left;margin:0 0 0 16px}.markdown-body .gist .line-numbers{border-bottom:none;border-left:none;border-top:none}.markdown-body .gist .line-data{border:none}.markdown-body .gist table{border-collapse:inherit!important;border-spacing:0}.markdown-body code[data-gist-id]{background:none;padding:0}.markdown-body code[data-gist-id]:after,.markdown-body code[data-gist-id]:before{content:""}.markdown-body code[data-gist-id] .blob-num{border:unset}.markdown-body code[data-gist-id] table{margin-bottom:unset;overflow:unset}.markdown-body code[data-gist-id] table tr{background:unset}.markdown-body[dir=rtl] pre{direction:ltr}.markdown-body[dir=rtl] code{direction:ltr;unicode-bidi:embed}.markdown-body .alert>p:last-child{margin-bottom:0}.markdown-body pre.abc,.markdown-body pre.flow-chart,.markdown-body pre.graphviz,.markdown-body pre.mermaid,.markdown-body pre.sequence-diagram,.markdown-body pre.vega{background-color:inherit;border-radius:0;overflow:visible;text-align:center;white-space:inherit}.markdown-body pre.abc>code,.markdown-body pre.flow-chart>code,.markdown-body pre.graphviz>code,.markdown-body pre.mermaid>code,.markdown-body pre.sequence-diagram>code,.markdown-body pre.vega>code{text-align:left}.markdown-body pre.abc>svg,.markdown-body pre.flow-chart>svg,.markdown-body pre.graphviz>svg,.markdown-body pre.mermaid>svg,.markdown-body pre.sequence-diagram>svg,.markdown-body pre.vega>svg{height:100%;max-width:100%}.markdown-body pre>code.wrap{word-wrap:break-word;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap}.markdown-body .alert>p:last-child,.markdown-body .alert>ul:last-child{margin-bottom:0}.markdown-body summary{display:list-item}.markdown-body summary:focus{outline:none}.markdown-body details summary{cursor:pointer}.markdown-body details:not([open])>:not(summary){display:none}.markdown-body figure{margin:1em 40px}.markdown-body .mark,.markdown-body mark{background-color:#fff1a7}.vimeo,.youtube{background-color:#000;background-position:50%;background-repeat:no-repeat;background-size:contain;cursor:pointer;display:table;overflow:hidden;text-align:center}.vimeo,.youtube{position:relative;width:100%}.youtube{padding-bottom:56.25%}.vimeo img{object-fit:contain;width:100%;z-index:0}.youtube img{object-fit:cover;z-index:0}.vimeo iframe,.youtube iframe,.youtube img{height:100%;left:0;position:absolute;top:0;width:100%}.vimeo iframe,.youtube iframe{vertical-align:middle;z-index:1}.vimeo .icon,.youtube .icon{color:#fff;height:auto;left:50%;opacity:.3;position:absolute;top:50%;transform:translate(-50%,-50%);transition:opacity .2s;width:auto;z-index:0}.vimeo:hover .icon,.youtube:hover .icon{opacity:.6;transition:opacity .2s}.slideshare .inner,.speakerdeck .inner{position:relative;width:100%}.slideshare .inner iframe,.speakerdeck .inner iframe{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.figma{display:table;padding-bottom:56.25%;position:relative;width:100%}.figma iframe{border:1px solid #eee;bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.markmap-container{height:300px}.markmap-container>svg{height:100%;width:100%}.MJX_Assistive_MathML{display:none}#MathJax_Message{z-index:1000!important}.ui-infobar{color:#777;margin:25px auto -25px;max-width:760px;position:relative;z-index:2}.toc .invisable-node{list-style-type:none}.ui-toc{bottom:20px;position:fixed;z-index:998}.ui-toc.both-mode{margin-left:8px}.ui-toc.both-mode .ui-toc-label{border-bottom-left-radius:0;border-top-left-radius:0;height:40px;padding:10px 4px}.ui-toc-label{background-color:#e6e6e6;border:none;color:#868686;transition:opacity .2s}.ui-toc .open .ui-toc-label{color:#fff;opacity:1;transition:opacity .2s}.ui-toc-label:focus{background-color:#ccc;color:#000;opacity:.3}.ui-toc-label:hover{background-color:#ccc;opacity:1;transition:opacity .2s}.ui-toc-dropdown{margin-bottom:20px;margin-top:20px;max-height:70vh;max-width:45vw;overflow:auto;padding-left:10px;padding-right:10px;text-align:inherit;width:25vw}.ui-toc-dropdown>.toc{max-height:calc(70vh - 100px);overflow:auto}.ui-toc-dropdown[dir=rtl] .nav{letter-spacing:.0029em;padding-right:0}.ui-toc-dropdown a{overflow:hidden;text-overflow:ellipsis;white-space:pre}.ui-toc-dropdown .nav>li>a{color:#767676;display:block;font-size:13px;font-weight:500;padding:4px 20px}.ui-toc-dropdown .nav>li:first-child:last-child>ul,.ui-toc-dropdown .toc.expand ul{display:block}.ui-toc-dropdown .nav>li>a:focus,.ui-toc-dropdown .nav>li>a:hover{background-color:initial;border-left:1px solid #000;color:#000;padding-left:19px;text-decoration:none}.ui-toc-dropdown[dir=rtl] .nav>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav>li>a:hover{border-left:none;border-right:1px solid #000;padding-right:19px}.ui-toc-dropdown .nav>.active:focus>a,.ui-toc-dropdown .nav>.active:hover>a,.ui-toc-dropdown .nav>.active>a{background-color:initial;border-left:2px solid #000;color:#000;font-weight:700;padding-left:18px}.ui-toc-dropdown[dir=rtl] .nav>.active:focus>a,.ui-toc-dropdown[dir=rtl] .nav>.active:hover>a,.ui-toc-dropdown[dir=rtl] .nav>.active>a{border-left:none;border-right:2px solid #000;padding-right:18px}.ui-toc-dropdown .nav .nav{display:none;padding-bottom:10px}.ui-toc-dropdown .nav>.active>ul{display:block}.ui-toc-dropdown .nav .nav>li>a{font-size:12px;font-weight:400;padding-bottom:1px;padding-left:30px;padding-top:1px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>a{padding-right:30px}.ui-toc-dropdown .nav .nav>li>ul>li>a{font-size:12px;font-weight:400;padding-bottom:1px;padding-left:40px;padding-top:1px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>ul>li>a{padding-right:40px}.ui-toc-dropdown .nav .nav>li>a:focus,.ui-toc-dropdown .nav .nav>li>a:hover{padding-left:29px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav .nav>li>a:hover{padding-right:29px}.ui-toc-dropdown .nav .nav>li>ul>li>a:focus,.ui-toc-dropdown .nav .nav>li>ul>li>a:hover{padding-left:39px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>ul>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav .nav>li>ul>li>a:hover{padding-right:39px}.ui-toc-dropdown .nav .nav>.active:focus>a,.ui-toc-dropdown .nav .nav>.active:hover>a,.ui-toc-dropdown .nav .nav>.active>a{font-weight:500;padding-left:28px}.ui-toc-dropdown[dir=rtl] .nav .nav>.active:focus>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active:hover>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active>a{padding-right:28px}.ui-toc-dropdown .nav .nav>.active>.nav>.active:focus>a,.ui-toc-dropdown .nav .nav>.active>.nav>.active:hover>a,.ui-toc-dropdown .nav .nav>.active>.nav>.active>a{font-weight:500;padding-left:38px}.ui-toc-dropdown[dir=rtl] .nav .nav>.active>.nav>.active:focus>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active>.nav>.active:hover>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active>.nav>.active>a{padding-right:38px}.markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang^=ja] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ ゴシック,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang=zh-tw] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang=zh-cn] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html .markdown-body[lang^=ja]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ ゴシック,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html .markdown-body[lang=zh-tw]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html .markdown-body[lang=zh-cn]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang^=ja] .ui-toc-dropdown{font-family:Source Sans Pro,Helvetica,Arial,Meiryo UI,MS PGothic,ＭＳ Ｐゴシック,sans-serif}html[lang=zh-tw] .ui-toc-dropdown{font-family:Source Sans Pro,Helvetica,Arial,Microsoft JhengHei UI,微軟正黑UI,sans-serif}html[lang=zh-cn] .ui-toc-dropdown{font-family:Source Sans Pro,Helvetica,Arial,Microsoft YaHei UI,微软雅黑UI,sans-serif}html .ui-toc-dropdown[lang^=ja]{font-family:Source Sans Pro,Helvetica,Arial,Meiryo UI,MS PGothic,ＭＳ Ｐゴシック,sans-serif}html .ui-toc-dropdown[lang=zh-tw]{font-family:Source Sans Pro,Helvetica,Arial,Microsoft JhengHei UI,微軟正黑UI,sans-serif}html .ui-toc-dropdown[lang=zh-cn]{font-family:Source Sans Pro,Helvetica,Arial,Microsoft YaHei UI,微软雅黑UI,sans-serif}.ui-affix-toc{max-height:70vh;max-width:15vw;overflow:auto;position:fixed;top:0}.back-to-top,.expand-toggle,.go-to-bottom{color:#999;display:block;font-size:12px;font-weight:500;margin-left:10px;margin-top:10px;padding:4px 10px}.back-to-top:focus,.back-to-top:hover,.expand-toggle:focus,.expand-toggle:hover,.go-to-bottom:focus,.go-to-bottom:hover{color:#563d7c;text-decoration:none}.back-to-top,.go-to-bottom{margin-top:0}.ui-user-icon{background-position:50%;background-repeat:no-repeat;background-size:cover;border-radius:50%;display:block;height:20px;margin-bottom:2px;margin-right:5px;margin-top:2px;width:20px}.ui-user-icon.small{display:inline-block;height:18px;margin:0 0 .2em;vertical-align:middle;width:18px}.ui-infobar>small>span{line-height:22px}.ui-infobar>small .dropdown{display:inline-block}.ui-infobar>small .dropdown a:focus,.ui-infobar>small .dropdown a:hover{text-decoration:none}.ui-more-info{color:#888;cursor:pointer;vertical-align:middle}.ui-more-info .fa{font-size:16px}.ui-connectedGithub,.ui-published-note{color:#888}.ui-connectedGithub{line-height:23px;white-space:nowrap}.ui-connectedGithub a.file-path{color:#888;padding-left:22px;text-decoration:none}.ui-connectedGithub a.file-path:active,.ui-connectedGithub a.file-path:hover{color:#888;text-decoration:underline}.ui-connectedGithub .fa{font-size:20px}.ui-published-note .fa{font-size:20px;vertical-align:top}.unselectable{-webkit-user-select:none;-o-user-select:none;user-select:none}.selectable{-webkit-user-select:text;-o-user-select:text;user-select:text}.inline-spoiler-section{cursor:pointer}.inline-spoiler-section .spoiler-text{background-color:#333;border-radius:2px}.inline-spoiler-section .spoiler-text>*{opacity:0}.inline-spoiler-section .spoiler-img{filter:blur(10px)}.inline-spoiler-section.raw{background-color:#333;border-radius:2px}.inline-spoiler-section.raw>*{opacity:0}.inline-spoiler-section.unveil{cursor:auto}.inline-spoiler-section.unveil .spoiler-text{background-color:#3333331a}.inline-spoiler-section.unveil .spoiler-text>*{opacity:1}.inline-spoiler-section.unveil .spoiler-img{filter:none}@media print{blockquote,div,img,pre,table{page-break-inside:avoid!important}a[href]:after{font-size:12px!important}}.markdown-body.slides{color:#222;position:relative;z-index:1}.markdown-body.slides:before{background-color:currentColor;bottom:0;box-shadow:0 0 0 50vw;content:"";display:block;left:0;position:absolute;right:0;top:0;z-index:-1}.markdown-body.slides section[data-markdown]{background-color:#fff;margin-bottom:1.5em;position:relative;text-align:center}.markdown-body.slides section[data-markdown] code{text-align:left}.markdown-body.slides section[data-markdown]:before{content:"";display:block;padding-bottom:56.23%}.markdown-body.slides section[data-markdown]>div:first-child{left:1em;max-height:100%;overflow:hidden;position:absolute;right:1em;top:50%;transform:translateY(-50%)}.markdown-body.slides section[data-markdown]>ul{display:inline-block}.markdown-body.slides>section>section+section:after{border:3px solid #777;content:"";height:1.5em;position:absolute;right:1em;top:-1.5em}.site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,sans-serif}html[lang^=ja] .site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ ゴシック,sans-serif}html[lang=zh-tw] .site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif}html[lang=zh-cn] .site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif}body{font-smoothing:subpixel-antialiased!important;-webkit-font-smoothing:subpixel-antialiased!important;-moz-osx-font-smoothing:auto!important;-webkit-overflow-scrolling:touch;font-family:Source Sans Pro,Helvetica,Arial,sans-serif;letter-spacing:.025em}html[lang^=ja] body{font-family:Source Sans Pro,Helvetica,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ ゴシック,sans-serif}html[lang=zh-tw] body{font-family:Source Sans Pro,Helvetica,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif}html[lang=zh-cn] body{font-family:Source Sans Pro,Helvetica,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}abbr[data-original-title],abbr[title]{cursor:help}body.modal-open{overflow-y:auto;padding-right:0!important}svg{text-shadow:none}
    </style>
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js" integrity="sha256-3Jy/GbSLrg0o9y5Z5n1uw0qxZECH7C6OQpVBgNFYa0g=" crossorigin="anonymous"></script>
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js" integrity="sha256-g6iAfvZp+nDQ2TdTR/VVKJf3bGro4ub5fvWSWVRi2NE=" crossorigin="anonymous"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.9/es5-shim.min.js" integrity="sha256-8E4Is26QH0bD52WoQpcB+R/tcWQtpzlCojrybUd7Mxo=" crossorigin="anonymous"></script>
    <![endif]-->
</head>

<body>
    <div id="doc" class="markdown-body container-fluid comment-enabled" data-hard-breaks="false"><style>
ins { background-color: #CCFFCC }
s { background-color: #FFCACA }
blockquote { color: inherit !important }
table.no-alt tr:nth-child(2n) { background-color: inherit }
.godbolt {
    background-size: contain;
    background-repeat: no-repeat;
    background-position-y: center;
    background-image: url("data:image/x-icon;base64,AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAMAAAAEAAAABAAAAAUAAAAGAAAABgAAAAUAAAAEAAAABAAAAAMAAAACAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAGAAAACAAAAAkAAAALAAAADAAAAAwAAAALAAAACgAAAAgAAAAGAAAABAAAAAMAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAwAAAAUAAAAIAAAADAAAAA8AAAASAAAAFQAAABYAAAAWAAAAFAAAABMAAAAPAAAADAAAAAgAAAAFAAAAAwAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAwAAAAMAAAACwAAAAoAAAAIAAAABgAAAAUAAAADAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAgAAAAIAAAADAAAABAAAAAUAAAAGAAAABgAAAAUAAAAFAAAABAAAAAMAAAACAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAADAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////+B/////////wD/////////AH////////4Af////////gA////////8AB/v////4eAAB4f////AAAAAA////4AAAAAB////AAAAAAD///4AAAAAAH///gAB/8AAf///AAf/8AD///8AH//4AP///4A///4B////gH///wH///+A////Af///wH///+A////A8AAA/////4DwAAD/////gfAAAP////4B+AAA////8AH////////wAf////////AB+AAP////8AHwAAf////wAfAAB/////AB8AAH////8AH////////wAf////////wB+AAA/////4HwAAD/////gPAAAP/////A8AAA/////8B////gP///4D///+A////gH///wH///+AP//+Af///4Af//wA////AA//8AD///4AA//AAH///gAAAAAAf///AAAAAAD///+AAAAAAf///8AAAAAD////4eAAB4f////3+AAf7//////+AH////////4Af////////gB/////////AP////////+A////////////////////////////////////////////////////////////////////8=")
}
</style><table><tbody>
<tr><th>Doc. no.:</th>    <td>P0963R1</td></tr>
<tr><th>Date:</th>        <td>2023-08-14</td></tr>
<tr><th>Audience:</th>    <td>Evolution Working Group</td></tr>
<tr><th>Reply-to:</th>    <td>Zhihao Yuan &lt;zy at miator dot net&gt;</td></tr>
</tbody></table><h1 id="Structured-binding-declaration-as-a-condition" data-id="Structured-binding-declaration-as-a-condition"><a class="anchor hidden-xs" href="#Structured-binding-declaration-as-a-condition" title="Structured-binding-declaration-as-a-condition"><span class="octicon octicon-link"></span></a><span>Structured binding declaration as a </span><em><span>condition</span></em></h1><p><span class="toc"><ul>
<li><a href="#Structured-binding-declaration-as-a-condition" title="Structured binding declaration as a condition">Structured binding declaration as a condition</a><ul>
<li><a href="#Changes" title="Changes">Changes</a></li>
<li><a href="#Introduction" title="Introduction">Introduction</a></li>
<li><a href="#Motivation" title="Motivation">Motivation</a></li>
<li><a href="#Design-Decisions" title="Design Decisions">Design Decisions</a><ul>
<li><a href="#Unconditionally-decompose" title="Unconditionally decompose">Unconditionally decompose</a></li>
<li><a href="#Testing-is-sequenced-after-decomposing" title="Testing is sequenced after decomposing">Testing is sequenced after decomposing</a></li>
<li><a href="#No-underlying-array-object" title="No underlying array object">No underlying array object</a></li>
</ul>
</li>
<li><a href="#Wording" title="Wording">Wording</a></li>
<li><a href="#Implementation" title="Implementation">Implementation</a></li>
<li><a href="#Acknowledgements" title="Acknowledgements">Acknowledgements</a></li>
<li><a href="#References" title="References">References</a></li>
</ul>
</li>
</ul>
</span></p><h2 id="Changes" data-id="Changes"><a class="anchor hidden-xs" href="#Changes" title="Changes"><span class="octicon octicon-link"></span></a><span>Changes</span></h2><dl>
<dt><span>Since R0</span></dt>
<dd>
<ul>
<li><span>Rework the motivation</span></li>
<li><span>Clarify that decomposition is sequenced before testing</span></li>
</ul>
</dd>
</dl><h2 id="Introduction" data-id="Introduction"><a class="anchor hidden-xs" href="#Introduction" title="Introduction"><span class="octicon octicon-link"></span></a><span>Introduction</span></h2><p><span>C++17 structured binding declaration is designed as a variant of variable declarations. As of today, it may appear as a statement on its own or as the declaration part of a range-based </span><code>for</code><span> loop. Meanwhile, the </span><em><span>condition</span></em><span> of an </span><code>if</code><span> statement may also be a variable declaration and can benefit from being a structured binding declaration. This paper proposes to allow structured binding declarations with initializers appearing in place of the </span><em><span>conditions</span></em><span> in </span><code>if</code><span>, </span><code>while</code><span>, </span><code>for</code><span>, and </span><code>switch</code><span> statements.</span></p><table class="no-alt"><tbody>
<tr><th>
<p><em><span>simple-declaration</span></em></p>
</th><td>
<pre><code class="cpp hljs"><span class="token keyword">auto</span> <span class="token punctuation">[</span>b<span class="token punctuation">,</span> p<span class="token punctuation">]</span> <span class="token operator">=</span> ranges<span class="token double-colon punctuation">::</span><span class="token function">mismatch</span><span class="token punctuation">(</span>current<span class="token punctuation">,</span> end<span class="token punctuation">,</span> pbegin<span class="token punctuation">,</span> pend<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td></tr><tr><th>
<p><em><span>for-range-declaration</span></em></p>
</th><td>
<pre><code class="cpp hljs"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token punctuation">[</span>index<span class="token punctuation">,</span> value<span class="token punctuation">]</span> <span class="token operator">:</span> views<span class="token double-colon punctuation">::</span><span class="token function">enumerate</span><span class="token punctuation">(</span>vec<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"{}: {}"</span><span class="token punctuation">,</span> index<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">}</span>
</code></pre>
</td></tr>
<tr><th>
<p><mark><em><span>condition</span></em></mark></p>
</th>
<td>
<pre><code class="cpp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token punctuation">[</span>to<span class="token punctuation">,</span> ec<span class="token punctuation">]</span> <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">to_chars</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> last<span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">auto</span> s <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">string</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> to<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">}</span>
</code></pre>
</td></tr>
</tbody></table><h2 id="Motivation" data-id="Motivation"><a class="anchor hidden-xs" href="#Motivation" title="Motivation"><span class="octicon octicon-link"></span></a><span>Motivation</span></h2><p><span>By design, structured binding is only about decomposition. The information of an object to be decomposed equals the information of all the components combined. However, after deploying structured bindings for a few years, it has been found that, in some scenarios, certain side information contributes to complexity if left out.</span></p><dl>
<dt><span>Scenario 1</span></dt>
<dd>
<p><span>The author sees a pattern that can be demonstrated using the following code snippet:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token punctuation">[</span>first<span class="token punctuation">,</span> last<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">parse</span><span class="token punctuation">(</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> first <span class="token operator">!=</span> last<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// interpret [first, last) into a value</span>
<span class="token punctuation">}</span>
</code></pre>
<p><span>The idea is to split parsing and the action. By returning a pair of pointers, it’s not only easy to incorporate C-style APIs in the implementation of the actions but also flexible to form different, windowed inputs by mixing &amp; matching the pointers.</span></p>
<p><span>However, if you wear glasses of “I did not write the code,” the condition </span><code>first != last</code><span> doesn’t say much. It’s repetitive, opens the opportunity of being combined with other conditions, and can cause mistakes if comparing different pairs.</span></p>
<p><span>It would be nice if, when defining the intermediate type that carries the pairs to be decomposed, the condition can be baked into the type,</span></p>
<pre><code class="cpp hljs"><span class="token keyword">struct</span> <span class="token class-name">parse_window</span>
<span class="token punctuation">{</span>
    <span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>first<span class="token punctuation">,</span> <span class="token operator">*</span>last<span class="token punctuation">;</span>
    <span class="token keyword">explicit</span> <span class="token keyword">operator</span> <span class="token keyword">bool</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token keyword">noexcept</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> first <span class="token operator">!=</span> last<span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
<p><span>and eliminates the need to maintain a convention:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token punctuation">[</span>first<span class="token punctuation">,</span> last<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">parse</span><span class="token punctuation">(</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// interpret [first, last) into a value</span>
<span class="token punctuation">}</span>
</code></pre>
<p><span>In this example, </span><strong><span>information about the condition is spread across the components</span></strong><span>, and “how to form the condition” is not self-explanatory. If structured binding can channel this knowledge contextually, the library authors and the users may settle with a more solid pattern.</span></p>
</dd>
<dt><span>Scenario 2</span></dt>
<dd>
<p><span>Here is an updated example of using </span><code>&lt;charconv&gt;</code><span> in C++26 after adopting P2497</span><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><span>:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> result <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">to_chars</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> last<span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">auto</span> <span class="token punctuation">[</span>ptr<span class="token punctuation">,</span> _<span class="token punctuation">]</span> <span class="token operator">=</span> result<span class="token punctuation">;</span>
    <span class="token comment">// okay to proceed</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">auto</span> <span class="token punctuation">[</span>ptr<span class="token punctuation">,</span> ec<span class="token punctuation">]</span> <span class="token operator">=</span> result<span class="token punctuation">;</span>
    <span class="token comment">// handle errors</span>
<span class="token punctuation">}</span>
</code></pre>
<p><span>We succeeded at restricting the variable to the minimal lexical scope where needed, but the code still struggled to implement what the users wanted to express.</span></p>
<p><span>The example can be a lot simpler if, when testing the </span><code>result</code><span> variable which has no role other than being decomposed later, the test is done as a part of decomposition without naming the intermediate </span><code>result</code><span>:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token punctuation">[</span>ptr<span class="token punctuation">,</span> ec<span class="token punctuation">]</span> <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">to_chars</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> last<span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// okay to proceed</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token comment">// handle errors</span>
<span class="token punctuation">}</span>
</code></pre>
</dd>
</dl><p><span>So, even when </span><strong><span>a single component contains information about the condition</span></strong><span> (</span><code>result.ec</code><span> in this example), people continue to be motivated to consolidate the knowledge of “how to test” into the complete object. But how to test when the complete object happens to be the underlying object of structured binding? The proposed feature answers the need.</span></p><dl>
<dt><span>Scenario 3</span></dt>
<dd>
<p><span>In an iterative solver, the code runs a primary solving step, like the following, in a loop. The call returns the state of the problem, decomposed into matrices and vectors:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">auto</span> <span class="token punctuation">[</span>Ap<span class="token punctuation">,</span> bp<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">solve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p><span>The solver must determine, right after the step, whether it gets an optimal solution. Mathematically, this can be done by evaluating one or more components like this:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">is_optimal</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span>  <span class="token comment">// scan the x vector</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>
</code></pre>
<p><span>But doing so may involve a linear algorithm or worse. Meanwhile, the </span><code>solve()</code><span> procedure may know whether the answer is optimal and save this information in the result as if it is cached. If the language allows retrieving this information, the following code can be terser and more efficient at the same time:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token punctuation">[</span>Ap<span class="token punctuation">,</span> bp<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">solve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>  <span class="token comment">// no need to scan x again</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>
</code></pre>
<p><span>In this example, </span><strong><span>the information about the condition needs to be reconstructed from the components at a cost</span></strong><span>. The complete object is an excellent place to cache this information but is not in a position to bring this redundant information into a separate component.</span></p>
</dd>
<dt><span>Scenario 4</span></dt>
<dd>
<p><span>Consider this example that uses the CTRE</span><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup><span> library:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token punctuation">[</span>all<span class="token punctuation">,</span> city<span class="token punctuation">,</span> state<span class="token punctuation">,</span> zip<span class="token punctuation">]</span> <span class="token operator">=</span> ctre<span class="token double-colon punctuation">::</span>match<span class="token operator">&lt;</span><span class="token string">"(\\w+), (\\w+) (\\d+)"</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span> all<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> location<span class="token punctuation">{</span>city<span class="token punctuation">,</span> state<span class="token punctuation">,</span> zip<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><span>It is surprising to see a regular expression that introduces 3 capture groups generating a result of 4 components unless the readers are already familiar with other Perl-like regex engines, which offer a “default” capture group to represent the entire match. Such a match group can be referred to as </span><code>\0</code><span> when performing regex-based substitution, which isn’t what we’re doing here.</span></p>
<p><span>It might be more WYSIWYG if, in the next generation of the API, three capture groups mean three components to extract:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token punctuation">[</span>city<span class="token punctuation">,</span> state<span class="token punctuation">,</span> zip<span class="token punctuation">]</span> <span class="token operator">=</span> ctre2<span class="token double-colon punctuation">::</span>match<span class="token operator">&lt;</span><span class="token string">"(\\w+), (\\w+) (\\d+)"</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> location<span class="token punctuation">{</span>city<span class="token punctuation">,</span> state<span class="token punctuation">,</span> zip<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><span>In this example, if solely looking at the outcome, the information to be tested in the condition is not in the components. But still, when </span><strong><span>all components but one have similar roles</span></strong><span>, folding such a particular component into an implicit test well-suited for its role makes the code easier to understand.</span></p>
</dd>
</dl><h2 id="Design-Decisions" data-id="Design-Decisions"><a class="anchor hidden-xs" href="#Design-Decisions" title="Design-Decisions"><span class="octicon octicon-link"></span></a><span>Design Decisions</span></h2><h3 id="Unconditionally-decompose" data-id="Unconditionally-decompose"><a class="anchor hidden-xs" href="#Unconditionally-decompose" title="Unconditionally-decompose"><span class="octicon octicon-link"></span></a><span>Unconditionally decompose</span></h3><p><span>It is tempting to add extra semantics given the proposed syntax, such as conditionally evaluating the binding protocol after testing the underlying object:</span></p><pre><code class="cpp hljs"><span class="token keyword">auto</span> <span class="token function">consume_int</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> std<span class="token double-colon punctuation">::</span>optional<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">consume_int</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>  <span class="token comment">// let e be the underlying object</span>
    <span class="token comment">// i = *e</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token comment">// *e is not evaluated</span>
<span class="token punctuation">}</span>
</code></pre><p><span>This idea turns </span><code>std::optional&lt;T&gt;</code><span> into a new kind of type that is “conditionally destructurable.” Imagine this: if </span><code>[x]</code><span> can destructure </span><code>optional&lt;T&gt;</code><span>, then </span><code>[x, y]</code><span> won’t destructure </span><code>optional&lt;tuple&lt;T, U&gt;&gt;</code><span>. The pattern matching proposal</span><sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup><span> has better answers to these: </span><code>let ?x</code><span> and </span><code>let ?[x, y]</code><span>. With pattern matching, one can rewrite the hypothetical code snippet above as:</span></p><pre><code class="csharp hljs"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">consume_int</span><span class="token punctuation">(</span><span class="token punctuation">)</span> match <span class="token keyword">let</span> <span class="token punctuation">?</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// use(i)</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token comment">// has no value</span>
<span class="token punctuation">}</span>
</code></pre><p><span>The idea of conditionally decomposing confuses sum types with product types; therefore, it is not included in this paper.</span></p><h3 id="Testing-is-sequenced-after-decomposing" data-id="Testing-is-sequenced-after-decomposing"><a class="anchor hidden-xs" href="#Testing-is-sequenced-after-decomposing" title="Testing-is-sequenced-after-decomposing"><span class="octicon octicon-link"></span></a><span>Testing is sequenced after decomposing</span></h3><p><span>If decomposition is taken place unconditionally, when that happens becomes a question. Does it happen before evaluating the </span><em><span>condition</span></em><span> or after? The author’s mental model for structured binding in </span><em><span>condition</span></em><span> is the following:</span></p><pre>if (auto [a, b, c] = fn()) {
    statements;
}
</pre><p><span>is equivalent to</span></p><pre>if (auto [a, b, c] = fn(); <i>e</i>) {
    statements;
}
</pre><p><span>where </span><em><code>e</code></em><span> is the underlying object of the structured binding declaration. Therefore, evaluating the </span><em><span>condition</span></em><span> should be sequenced after decomposing the underlying object.</span></p><p><span>You can play with this effect here:  </span><ruby><a href="https://godbolt.org/z/b89aTP31a" target="_blank" rel="noopener"><span class="godbolt"><span> </span></span><span>b89aTP31a</span></a><rt><span>Compiler Explorer</span></rt></ruby><span>.</span></p><h3 id="No-underlying-array-object" data-id="No-underlying-array-object"><a class="anchor hidden-xs" href="#No-underlying-array-object" title="No-underlying-array-object"><span class="octicon octicon-link"></span></a><span>No underlying array object</span></h3><p><span>It is worthwhile to figure out what array decomposition does in a </span><em><span>condition</span></em><span>. The </span><em><span>condition</span></em><span> forbids declaring arrays, so this paper neither allows decomposing arrays. However, the </span><em><span>condition</span></em><span> accepts array references, which always evaluate to </span><code>true</code><span>, which is also unchanged in this paper. The following works with the proposed change:</span></p><pre><code class="c++ hljs"><span class="hljs-keyword">if</span> (auto<span class="hljs-operator">&amp;</span> [a, b, c] <span class="hljs-operator">=</span> <span class="hljs-string">"ht"</span>)
    <span class="hljs-comment">// true branch is always taken</span>
</code></pre><p><span>Decomposing arrays in </span><em><span>conditions</span></em><span> is very unmotivated.</span></p><h2 id="Wording" data-id="Wording"><a class="anchor hidden-xs" href="#Wording" title="Wording"><span class="octicon octicon-link"></span></a><span>Wording</span></h2><p><span>The wording is relative to N4950.</span></p><p><span>Extend the grammar in </span><a href="https://eel.is/c++draft/stmt.stmt#stmt.pre-1" target="_blank" rel="noopener"><span>[stmt.stmt]/1</span></a><span> as follows:</span></p><blockquote>
<p><em><span>condition:</span></em>
<span>&nbsp;&nbsp;&nbsp;</span><em><span>expression</span></em>
<span>&nbsp;&nbsp;&nbsp;</span><em><span>attribute-specifier-seq</span><sub><span>opt</span></sub><span> decl-specifier-seq declarator brace-or-equal-initializer</span></em>
<span>&nbsp;&nbsp;&nbsp;</span><ins><em><span>attribute-specifier-seq</span><sub><span>opt</span></sub><span> decl-specifier-seq ref-qualifier</span><sub><span>opt</span></sub></em><span> </span><code>[</code><span> </span><em><span>identifier-list</span></em><span> </span><code>]</code><span> </span><em><span>brace-or-equal-initializer</span></em></ins></p>
</blockquote><p><span>Modify </span><a href="https://eel.is/c++draft/stmt.stmt#stmt.pre-4" target="_blank" rel="noopener"><span>[stmt.stmt]/4</span></a><span> as follows:</span></p><blockquote>
<p><span>The rules for </span><em><span>conditions</span></em><span> apply both to </span><em><span>selection-statements</span></em><span> (</span><a href="https://eel.is/c++draft/stmt.stmt#stmt.select" target="_blank" rel="noopener"><span>[stmt.select]</span></a><span>) and to the </span><code>for</code><span> and </span><code>while</code><span> statements (</span><a href="https://eel.is/c++draft/stmt.stmt#stmt.iter" target="_blank" rel="noopener"><span>[stmt.iter]</span></a><span>). A </span><em><span>condition</span></em><span> that is not an </span><em><span>expression</span></em><span> is a declaration (</span><a href="https://eel.is/c++draft/dcl.dcl" target="_blank" rel="noopener"><span>[dcl.dcl]</span></a><span>). The </span><em><span>declarator</span></em><span> shall not specify a function or an array. The </span><em><span>decl-specifier-seq</span></em><span> shall not define a class or enumeration. If the </span><code>auto</code><span> </span><em><span>type-specifier</span></em><span> appears in the </span><em><span>decl-specifier-seq</span></em><span>, the type of the identifier being declared is deduced from the initializer as described in </span><a href="https://eel.is/c++draft/dcl.spec.auto" target="_blank" rel="noopener"><span>[dcl.spec.auto]</span></a><span>. </span><ins><span>If </span><em><span>identifier-list</span></em><span> appears in the </span><em><span>condition</span></em><span>, the declaration is a structured binding declaration (</span><a href="https://eel.is/c++draft/dcl.struct.bind" target="_blank" rel="noopener"><span>[dcl.struct.bind]</span></a><span>), where the </span><em><span>assignment-expression</span></em><span> in the </span><em><span>brace-or-equal-initializer</span></em><span> shall not have array type if no </span><em><span>ref-qualifier</span></em><span> is present.</span></ins></p>
</blockquote><p><span>Insert a paragraph between </span><a href="https://eel.is/c++draft/stmt.stmt#stmt.pre-4" target="_blank" rel="noopener"><span>[stmt.stmt]/4</span></a><span> and </span><a href="https://eel.is/c++draft/stmt.stmt#stmt.pre-5" target="_blank" rel="noopener"><span>[stmt.stmt]/5</span></a><span>:</span></p><blockquote>
<p><ins><span>The variable of a </span><em><span>condition</span></em><span> that is an initialized declaration is the declared variable.  The variable of a </span><em><span>condition</span></em><span> that is a structured binding declaration (</span><a href="https://eel.is/c++draft/dcl.struct.bind" target="_blank" rel="noopener"><span>[dcl.struct.bind]</span></a><span>) is the variable </span><em><code>e</code></em><span> with a unique name.</span></ins></p>
</blockquote><p><span>Rewrite the original </span><a href="https://eel.is/c++draft/stmt.stmt#stmt.pre-5" target="_blank" rel="noopener"><span>[stmt.stmt]/5</span></a><span> as follows:</span></p><blockquote>
<p><s><span>The value of a condition that is an initialized declaration in a statement other than a switch statement is the value of the declared variable contextually converted to bool. If that conversion is ill-formed, the program is ill-formed. The value of a condition that is an expression is the value of the expression, contextually converted to bool for statements other than switch; if</span></s><ins><span>If a </span><em><span>condition</span></em><span> is an expression, the value of the condition is the value of the expression, contextually converted to </span><code>bool</code><span> (</span><a href="https://eel.is/c++draft/conv#def:conversion,contextual_to_bool" target="_blank" rel="noopener"><span>7.3</span></a><span>) for statements other than </span><code>switch</code><span>; if that conversion is ill-formed, the program is ill-formed.  Otherwise, in a </span><code>switch</code><span> statement, the value of the </span><em><span>condition</span></em><span> is the value of the variable of the condition if it has integral or enumeration type, or that variable implicitly converted to integral or enumeration type otherwise.  In a statement other than a </span><code>switch</code><span> statement, the value of the </span><em><span>condition</span></em><span> is the value of the variable of the condition contextually converted to </span><code>bool</code><span>.  If</span></ins><span> that conversion is ill-formed, the program is ill-formed.  The value of the condition will be referred to as simply “the condition” where the usage is unambiguous. </span><ins><span>If a </span><em><span>condition</span></em><span> is a structured binding declaration, the operation to obtain the value of the condition is sequenced after initializing all the bindings.</span></ins></p>
</blockquote><h2 id="Implementation" data-id="Implementation"><a class="anchor hidden-xs" href="#Implementation" title="Implementation"><span class="octicon octicon-link"></span></a><span>Implementation</span></h2><p><span>The proposed change has been shipped in Clang since 6.0.0, guarded by </span><code>-Wbinding-in-condition</code><span>: </span><ruby><a href="https://godbolt.org/z/b64x65716" target="_blank" rel="noopener"><span class="godbolt"><span> </span></span><span>b64x65716</span></a><rt><span>Compiler Explorer</span></rt></ruby><span>.</span></p><h2 id="Acknowledgements" data-id="Acknowledgements"><a class="anchor hidden-xs" href="#Acknowledgements" title="Acknowledgements"><span class="octicon octicon-link"></span></a><span>Acknowledgements</span></h2><p><span>Thank Richard Smith for encouraging the work and Hana Dusíková for providing motivating examples.</span></p><h2 id="References" data-id="References"><a class="anchor hidden-xs" href="#References" title="References"><span class="octicon octicon-link"></span></a><span>References</span></h2><hr class="footnotes-sep"><section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><span>Wakely, Jonathan. P2497R0 </span><em><span>Testing for success or failure of </span><code>&lt;charconv&gt;</code><span> functions</span></em><span>.</span>
<a href="https://wg21.link/p2497r0" target="_blank" rel="noopener"><span>https://wg21.link/p2497r0</span></a> <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p><span>Dusíková, Hana. P1433R0 </span><em><span>Compile Time Regular Expressions</span></em><span>.</span>
<a href="https://wg21.link/p1433r0" target="_blank" rel="noopener"><span>https://wg21.link/p1433r0</span></a> <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn3" class="footnote-item"><p><span>Park, Michael. P2688R0 </span><em><span>Pattern Matching Discussion for Kona 2022</span></em><span>.</span>
<a href="https://wg21.link/p2688r0" target="_blank" rel="noopener"><span>https://wg21.link/p2688r0</span></a> <a href="#fnref3" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section></div>
    <div class="ui-toc dropup unselectable hidden-print" style="display:none;">
        <div class="pull-right dropdown">
            <a id="tocLabel" class="ui-toc-label btn btn-default" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false" title="Table of content">
                <i class="fa fa-bars"></i>
            </a>
            <ul id="ui-toc" class="ui-toc-dropdown dropdown-menu" aria-labelledby="tocLabel">
                <div class="toc"><ul class="nav">
<li><a href="#Structured-binding-declaration-as-a-condition" title="Structured binding declaration as a condition">Structured binding declaration as a condition</a><ul class="nav">
<li><a href="#Changes" title="Changes">Changes</a></li>
<li><a href="#Introduction" title="Introduction">Introduction</a></li>
<li><a href="#Motivation" title="Motivation">Motivation</a></li>
<li><a href="#Design-Decisions" title="Design Decisions">Design Decisions</a><ul class="nav">
<li><a href="#Unconditionally-decompose" title="Unconditionally decompose">Unconditionally decompose</a></li>
<li><a href="#Testing-is-sequenced-after-decomposing" title="Testing is sequenced after decomposing">Testing is sequenced after decomposing</a></li>
<li><a href="#No-underlying-array-object" title="No underlying array object">No underlying array object</a></li>
</ul>
</li>
<li><a href="#Wording" title="Wording">Wording</a></li>
<li><a href="#Implementation" title="Implementation">Implementation</a></li>
<li><a href="#Acknowledgements" title="Acknowledgements">Acknowledgements</a></li>
<li><a href="#References" title="References">References</a></li>
</ul>
</li>
</ul>
</div><div class="toc-menu"><a class="expand-toggle" href="#">Expand all</a><a class="back-to-top" href="#">Back to top</a><a class="go-to-bottom" href="#">Go to bottom</a></div>
            </ul>
        </div>
    </div>
    <div id="ui-toc-affix" class="ui-affix-toc ui-toc-dropdown unselectable hidden-print" data-spy="affix" style="top:17px;display:none;" null null>
        <div class="toc"><ul class="nav">
<li><a href="#Structured-binding-declaration-as-a-condition" title="Structured binding declaration as a condition">Structured binding declaration as a condition</a><ul class="nav">
<li><a href="#Changes" title="Changes">Changes</a></li>
<li><a href="#Introduction" title="Introduction">Introduction</a></li>
<li><a href="#Motivation" title="Motivation">Motivation</a></li>
<li><a href="#Design-Decisions" title="Design Decisions">Design Decisions</a><ul class="nav">
<li><a href="#Unconditionally-decompose" title="Unconditionally decompose">Unconditionally decompose</a></li>
<li><a href="#Testing-is-sequenced-after-decomposing" title="Testing is sequenced after decomposing">Testing is sequenced after decomposing</a></li>
<li><a href="#No-underlying-array-object" title="No underlying array object">No underlying array object</a></li>
</ul>
</li>
<li><a href="#Wording" title="Wording">Wording</a></li>
<li><a href="#Implementation" title="Implementation">Implementation</a></li>
<li><a href="#Acknowledgements" title="Acknowledgements">Acknowledgements</a></li>
<li><a href="#References" title="References">References</a></li>
</ul>
</li>
</ul>
</div><div class="toc-menu"><a class="expand-toggle" href="#">Expand all</a><a class="back-to-top" href="#">Back to top</a><a class="go-to-bottom" href="#">Go to bottom</a></div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous" defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gist-embed/2.6.0/gist-embed.min.js" integrity="sha256-KyF2D6xPIJUW5sUDSs93vWyZm+1RzIpKCexxElmxl8g=" crossorigin="anonymous" defer></script>
    <script>
        var markdown = $(".markdown-body");
        //smooth all hash trigger scrolling
        function smoothHashScroll() {
            var hashElements = $("a[href^='#']").toArray();
            for (var i = 0; i < hashElements.length; i++) {
                var element = hashElements[i];
                var $element = $(element);
                var hash = element.hash;
                if (hash) {
                    $element.on('click', function (e) {
                        // store hash
                        var hash = this.hash;
                        if ($(hash).length <= 0) return;
                        // prevent default anchor click behavior
                        e.preventDefault();
                        // animate
                        $('body, html').stop(true, true).animate({
                            scrollTop: $(hash).offset().top
                        }, 100, "linear", function () {
                            // when done, add hash to url
                            // (default click behaviour)
                            window.location.hash = hash;
                        });
                    });
                }
            }
        }

        smoothHashScroll();
        var toc = $('.ui-toc');
        var tocAffix = $('.ui-affix-toc');
        var tocDropdown = $('.ui-toc-dropdown');
        //toc
        tocDropdown.click(function (e) {
            e.stopPropagation();
        });

        var enoughForAffixToc = true;

        function generateScrollspy() {
            $(document.body).scrollspy({
                target: ''
            });
            $(document.body).scrollspy('refresh');
            if (enoughForAffixToc) {
                toc.hide();
                tocAffix.show();
            } else {
                tocAffix.hide();
                toc.show();
            }
            $(document.body).scroll();
        }

        function windowResize() {
            //toc right
            var paddingRight = parseFloat(markdown.css('padding-right'));
            var right = ($(window).width() - (markdown.offset().left + markdown.outerWidth() - paddingRight));
            toc.css('right', right + 'px');
            //affix toc left
            var newbool;
            var rightMargin = (markdown.parent().outerWidth() - markdown.outerWidth()) / 2;
            //for ipad or wider device
            if (rightMargin >= 133) {
                newbool = true;
                var affixLeftMargin = (tocAffix.outerWidth() - tocAffix.width()) / 2;
                var left = markdown.offset().left + markdown.outerWidth() - affixLeftMargin;
                tocAffix.css('left', left + 'px');
            } else {
                newbool = false;
            }
            if (newbool != enoughForAffixToc) {
                enoughForAffixToc = newbool;
                generateScrollspy();
            }
        }
        $(window).resize(function () {
            windowResize();
        });
        $(document).ready(function () {
            windowResize();
            generateScrollspy();
        });

        //remove hash
        function removeHash() {
            window.location.hash = '';
        }

        var backtotop = $('.back-to-top');
        var gotobottom = $('.go-to-bottom');

        backtotop.click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (scrollToTop)
                scrollToTop();
            removeHash();
        });
        gotobottom.click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (scrollToBottom)
                scrollToBottom();
            removeHash();
        });

        var toggle = $('.expand-toggle');
        var tocExpand = false;

        checkExpandToggle();
        toggle.click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            tocExpand = !tocExpand;
            checkExpandToggle();
        })

        function checkExpandToggle () {
            var toc = $('.ui-toc-dropdown .toc');
            var toggle = $('.expand-toggle');
            if (!tocExpand) {
                toc.removeClass('expand');
                toggle.text('Expand all');
            } else {
                toc.addClass('expand');
                toggle.text('Collapse all');
            }
        }

        function scrollToTop() {
            $('body, html').stop(true, true).animate({
                scrollTop: 0
            }, 100, "linear");
        }

        function scrollToBottom() {
            $('body, html').stop(true, true).animate({
                scrollTop: $(document.body)[0].scrollHeight
            }, 100, "linear");
        }
    </script>
</body>

</html>
