<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>p1820r0.html</title>
  <meta name="generator" content="Haroopad 0.13.1" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <style>div.oembedall-githubrepos{border:1px solid #DDD;border-radius:4px;list-style-type:none;margin:0 0 10px;padding:8px 10px 0;font:13.34px/1.4 helvetica,arial,freesans,clean,sans-serif;width:452px;background-color:#fff}div.oembedall-githubrepos .oembedall-body{background:-moz-linear-gradient(center top,#FAFAFA,#EFEFEF);background:-webkit-gradient(linear,left top,left bottom,from(#FAFAFA),to(#EFEFEF));border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top:1px solid #EEE;margin-left:-10px;margin-top:8px;padding:5px 10px;width:100%}div.oembedall-githubrepos h3{font-size:14px;margin:0;padding-left:18px;white-space:nowrap}div.oembedall-githubrepos p.oembedall-description{color:#444;font-size:12px;margin:0 0 3px}div.oembedall-githubrepos p.oembedall-updated-at{color:#888;font-size:11px;margin:0}div.oembedall-githubrepos ul.oembedall-repo-stats{border:none;float:right;font-size:11px;font-weight:700;padding-left:15px;position:relative;z-index:5;margin:0}div.oembedall-githubrepos ul.oembedall-repo-stats li{border:none;color:#666;display:inline-block;list-style-type:none;margin:0!important}div.oembedall-githubrepos ul.oembedall-repo-stats li a{background-color:transparent;border:none;color:#666!important;background-position:5px -2px;background-repeat:no-repeat;border-left:1px solid #DDD;display:inline-block;height:21px;line-height:21px;padding:0 5px 0 23px}div.oembedall-githubrepos ul.oembedall-repo-stats li:first-child a{border-left:medium none;margin-right:-3px}div.oembedall-githubrepos ul.oembedall-repo-stats li a:hover{background:5px -27px no-repeat #4183C4;color:#FFF!important;text-decoration:none}div.oembedall-githubrepos ul.oembedall-repo-stats li:first-child a:hover{border-bottom-left-radius:3px;border-top-left-radius:3px}ul.oembedall-repo-stats li:last-child a:hover{border-bottom-right-radius:3px;border-top-right-radius:3px}span.oembedall-closehide{background-color:#aaa;border-radius:2px;cursor:pointer;margin-right:3px}div.oembedall-container{margin-top:5px;text-align:left}.oembedall-ljuser{font-weight:700}.oembedall-ljuser img{vertical-align:bottom;border:0;padding-right:1px}.oembedall-stoqembed{border-bottom:1px dotted #999;float:left;overflow:hidden;width:730px;line-height:1;background:#FFF;color:#000;font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif;font-size:80%;text-align:left;margin:0;padding:0}.oembedall-stoqembed a{color:#07C;text-decoration:none;margin:0;padding:0}.oembedall-stoqembed a:hover{text-decoration:underline}.oembedall-stoqembed a:visited{color:#4A6B82}.oembedall-stoqembed h3{font-family:Trebuchet MS,Liberation Sans,DejaVu Sans,sans-serif;font-size:130%;font-weight:700;margin:0;padding:0}.oembedall-stoqembed .oembedall-reputation-score{color:#444;font-size:120%;font-weight:700;margin-right:2px}.oembedall-stoqembed .oembedall-user-info{height:35px;width:185px}.oembedall-stoqembed .oembedall-user-info .oembedall-user-gravatar32{float:left;height:32px;width:32px}.oembedall-stoqembed .oembedall-user-info .oembedall-user-details{float:left;margin-left:5px;overflow:hidden;white-space:nowrap;width:145px}.oembedall-stoqembed .oembedall-question-hyperlink{font-weight:700}.oembedall-stoqembed .oembedall-stats{background:#EEE;margin:0 0 0 7px;padding:4px 7px 6px;width:58px}.oembedall-stoqembed .oembedall-statscontainer{float:left;margin-right:8px;width:86px}.oembedall-stoqembed .oembedall-votes{color:#555;padding:0 0 7px;text-align:center}.oembedall-stoqembed .oembedall-vote-count-post{font-size:240%;color:#808185;display:block;font-weight:700}.oembedall-stoqembed .oembedall-views{color:#999;padding-top:4px;text-align:center}.oembedall-stoqembed .oembedall-status{margin-top:-3px;padding:4px 0;text-align:center;background:#75845C;color:#FFF}.oembedall-stoqembed .oembedall-status strong{color:#FFF;display:block;font-size:140%}.oembedall-stoqembed .oembedall-summary{float:left;width:635px}.oembedall-stoqembed .oembedall-excerpt{line-height:1.2;margin:0;padding:0 0 5px}.oembedall-stoqembed .oembedall-tags{float:left;line-height:18px}.oembedall-stoqembed .oembedall-tags a:hover{text-decoration:none}.oembedall-stoqembed .oembedall-post-tag{background-color:#E0EAF1;border-bottom:1px solid #3E6D8E;border-right:1px solid #7F9FB6;color:#3E6D8E;font-size:90%;line-height:2.4;margin:2px 2px 2px 0;padding:3px 4px;text-decoration:none;white-space:nowrap}.oembedall-stoqembed .oembedall-post-tag:hover{background-color:#3E6D8E;border-bottom:1px solid #37607D;border-right:1px solid #37607D;color:#E0EAF1}.oembedall-stoqembed .oembedall-fr{float:right}.oembedall-stoqembed .oembedall-statsarrow{background-image:url(http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=3);background-repeat:no-repeat;overflow:hidden;background-position:0 -435px;float:right;height:13px;margin-top:12px;width:7px}.oembedall-facebook1{border:1px solid #1A3C6C;padding:0;font:13.34px/1.4 verdana;width:500px}.oembedall-facebook2{background-color:#627add}.oembedall-facebook2 a{color:#e8e8e8;text-decoration:none}.oembedall-facebookBody{background-color:#fff;vertical-align:top;padding:5px}.oembedall-facebookBody .contents{display:inline-block;width:100%}.oembedall-facebookBody div img{float:left;margin-right:5px}div.oembedall-lanyard{-webkit-box-shadow:none;-webkit-transition-delay:0s;-webkit-transition-duration:.4000000059604645s;-webkit-transition-property:width;-webkit-transition-timing-function:cubic-bezier(0.42,0,.58,1);background-attachment:scroll;background-clip:border-box;background-color:transparent;background-image:none;background-origin:padding-box;border-width:0;box-shadow:none;color:#112644;display:block;float:left;font-family:'Trebuchet MS',Trebuchet,sans-serif;font-size:16px;height:253px;line-height:19px;margin:0;max-width:none;min-height:0;outline:#112644 0;overflow-x:visible;overflow-y:visible;padding:0;position:relative;text-align:left;vertical-align:baseline;width:804px}div.oembedall-lanyard .tagline{font-size:1.5em}div.oembedall-lanyard .wrapper{overflow:hidden;clear:both}div.oembedall-lanyard .split{float:left;display:inline}div.oembedall-lanyard .prominent-place .flag:active,div.oembedall-lanyard .prominent-place .flag:focus,div.oembedall-lanyard .prominent-place .flag:hover,div.oembedall-lanyard .prominent-place .flag:link,div.oembedall-lanyard .prominent-place .flag:visited{float:left;display:block;width:48px;height:48px;position:relative;top:-5px;margin-right:10px}div.oembedall-lanyard .place-context{font-size:.889em}div.oembedall-lanyard .prominent-place .sub-place{display:block}div.oembedall-lanyard .prominent-place{font-size:1.125em;line-height:1.1em;font-weight:400}div.oembedall-lanyard .main-date{color:#8CB4E0;font-weight:700;line-height:1.1}div.oembedall-lanyard .first{width:48.57%;margin:0 0 0 2.857%}.mermaid .label{color:#333}.node circle,.node polygon,.node rect{fill:#cde498;stroke:#13540c;stroke-width:1px}.edgePath .path{stroke:green;stroke-width:1.5px}.cluster rect{fill:#cdffb2;rx:40;stroke:#6eaa49;stroke-width:1px}.cluster text{fill:#333}.actor{stroke:#13540c;fill:#cde498}text.actor{fill:#000;stroke:none}.actor-line{stroke:grey}.messageLine0{stroke-width:1.5;stroke-dasharray:"2 2";marker-end:"url(#arrowhead)";stroke:#333}.messageLine1{stroke-width:1.5;stroke-dasharray:"2 2";stroke:#333}#arrowhead{fill:#333}#crosshead path{fill:#333!important;stroke:#333!important}.messageText{fill:#333;stroke:none}.labelBox{stroke:#326932;fill:#cde498}.labelText,.loopText{fill:#000;stroke:none}.loopLine{stroke-width:2;stroke-dasharray:"2 2";marker-end:"url(#arrowhead)";stroke:#326932}.note{stroke:#6eaa49;fill:#fff5ad}.noteText{fill:#000;stroke:none;font-family:'trebuchet ms',verdana,arial;font-size:14px}.section{stroke:none;opacity:.2}.section0,.section2{fill:#6eaa49}.section1,.section3{fill:#fff;opacity:.2}.sectionTitle0,.sectionTitle1,.sectionTitle2,.sectionTitle3{fill:#333}.sectionTitle{text-anchor:start;font-size:11px;text-height:14px}.grid .tick{stroke:lightgrey;opacity:.3;shape-rendering:crispEdges}.grid path{stroke-width:0}.today{fill:none;stroke:red;stroke-width:2px}.task{stroke-width:2}.taskText{text-anchor:middle;font-size:11px}.taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px}.taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}.taskText0,.taskText1,.taskText2,.taskText3{fill:#fff}.task0,.task1,.task2,.task3{fill:#487e3a;stroke:#13540c}.taskTextOutside0,.taskTextOutside1,.taskTextOutside2,.taskTextOutside3{fill:#000}.active0,.active1,.active2,.active3{fill:#cde498;stroke:#13540c}.activeText0,.activeText1,.activeText2,.activeText3{fill:#000!important}.done0,.done1,.done2,.done3{stroke:grey;fill:lightgrey;stroke-width:2}.doneText0,.doneText1,.doneText2,.doneText3{fill:#000!important}.crit0,.crit1,.crit2,.crit3{stroke:#f88;fill:red;stroke-width:2}.activeCrit0,.activeCrit1,.activeCrit2,.activeCrit3{stroke:#f88;fill:#cde498;stroke-width:2}.doneCrit0,.doneCrit1,.doneCrit2,.doneCrit3{stroke:#f88;fill:lightgrey;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}.activeCritText0,.activeCritText1,.activeCritText2,.activeCritText3,.doneCritText0,.doneCritText1,.doneCritText2,.doneCritText3{fill:#000!important}.titleText{text-anchor:middle;font-size:18px;fill:#000}text{font-family:'trebuchet ms',verdana,arial;font-size:14px}html{height:100%}body{margin:0!important;padding:5px 20px 26px!important;background-color:#fff;font-family:"Lucida Grande","Segoe UI","Apple SD Gothic Neo","Malgun Gothic","Lucida Sans Unicode",Helvetica,Arial,sans-serif;font-size:.9em;overflow-x:hidden;overflow-y:auto}br,h1,h2,h3,h4,h5,h6{clear:both}hr.page{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x;border:0;height:3px;padding:0}hr.underscore{border-top-style:dashed!important}body >:first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:3px}iframe{border:0}figure{-webkit-margin-before:0;-webkit-margin-after:0;-webkit-margin-start:0;-webkit-margin-end:0}kbd{border:1px solid #aaa;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:1px 2px 2px #ddd;-webkit-box-shadow:1px 2px 2px #ddd;box-shadow:1px 2px 2px #ddd;background-color:#f9f9f9;background-image:-moz-linear-gradient(top,#eee,#f9f9f9,#eee);background-image:-o-linear-gradient(top,#eee,#f9f9f9,#eee);background-image:-webkit-linear-gradient(top,#eee,#f9f9f9,#eee);background-image:linear-gradient(top,#eee,#f9f9f9,#eee);padding:1px 3px;font-family:inherit;font-size:.85em}.oembeded .oembed_photo{display:inline-block}img[data-echo]{margin:25px 0;width:100px;height:100px;background:url(../img/ajax.gif) center center no-repeat #fff}.spinner{display:inline-block;width:10px;height:10px;margin-bottom:-.1em;border:2px solid rgba(0,0,0,.5);border-top-color:transparent;border-radius:100%;-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}.spinner:after{content:'';display:block;width:0;height:0;position:absolute;top:-6px;left:0;border:4px solid transparent;border-bottom-color:rgba(0,0,0,.5);-webkit-transform:rotate(45deg);transform:rotate(45deg)}@-webkit-keyframes spin{to{-webkit-transform:rotate(360deg)}}@keyframes spin{to{transform:rotate(360deg)}}p.toc{margin:0!important}p.toc ul{padding-left:10px}p.toc>ul{padding:10px;margin:0 10px;display:inline-block;border:1px solid #ededed;border-radius:5px}p.toc li,p.toc ul{list-style-type:none}p.toc li{width:100%;padding:0;overflow:hidden}p.toc li a::after{content:"."}p.toc li a:before{content:"• "}p.toc h5{text-transform:uppercase}p.toc .title{float:left;padding-right:3px}p.toc .number{margin:0;float:right;padding-left:3px;background:#fff;display:none}input.task-list-item{margin-left:-1.62em}.markdown{font-family:"Hiragino Sans GB","Microsoft YaHei",STHeiti,SimSun,"Lucida Grande","Lucida Sans Unicode","Lucida Sans",'Segoe UI',AppleSDGothicNeo-Medium,'Malgun Gothic',Verdana,Tahoma,sans-serif;padding:20px}.markdown a{text-decoration:none;vertical-align:baseline}.markdown a:hover{text-decoration:underline}.markdown h1{font-size:2.2em;font-weight:700;margin:1.5em 0 1em}.markdown h2{font-size:1.8em;font-weight:700;margin:1.275em 0 .85em}.markdown h3{font-size:1.6em;font-weight:700;margin:1.125em 0 .75em}.markdown h4{font-size:1.4em;font-weight:700;margin:.99em 0 .66em}.markdown h5{font-size:1.2em;font-weight:700;margin:.855em 0 .57em}.markdown h6{font-size:1em;font-weight:700;margin:.75em 0 .5em}.markdown h1+p,.markdown h1:first-child,.markdown h2+p,.markdown h2:first-child,.markdown h3+p,.markdown h3:first-child,.markdown h4+p,.markdown h4:first-child,.markdown h5+p,.markdown h5:first-child,.markdown h6+p,.markdown h6:first-child{margin-top:0}.markdown hr{border:1px solid #ccc}.markdown p{margin:1em 0;word-wrap:break-word}.markdown ol{list-style-type:decimal}.markdown li{display:list-item;line-height:1.4em}.markdown blockquote{margin:1em 20px}.markdown blockquote>:first-child{margin-top:0}.markdown blockquote>:last-child{margin-bottom:0}.markdown blockquote cite:before{content:'\2014 \00A0'}.markdown .code{border-radius:3px;word-wrap:break-word}.markdown pre{border-radius:3px;word-wrap:break-word;border:1px solid #ccc;overflow:auto;padding:.5em}.markdown pre code{border:0;display:block}.markdown pre>code{font-family:Consolas,Inconsolata,Courier,monospace;font-weight:700;white-space:pre;margin:0}.markdown code{border-radius:3px;word-wrap:break-word;border:1px solid #ccc;padding:0 5px;margin:0 2px}.markdown img{max-width:100%}.markdown mark{color:#000;background-color:#fcf8e3}.markdown table{padding:0;border-collapse:collapse;border-spacing:0;margin-bottom:16px}.markdown table tr td,.markdown table tr th{border:1px solid #ccc;margin:0;padding:6px 13px}.markdown table tr th{font-weight:700}.markdown table tr th>:first-child{margin-top:0}.markdown table tr th>:last-child{margin-bottom:0}.markdown table tr td>:first-child{margin-top:0}.markdown table tr td>:last-child{margin-bottom:0}@import url(http://fonts.googleapis.com/css?family=Roboto+Condensed:300italic,400italic,700italic,400,300,700);.haroopad{padding:20px;color:#222;font-size:15px;font-family:"Roboto Condensed",Tauri,"Hiragino Sans GB","Microsoft YaHei",STHeiti,SimSun,"Lucida Grande","Lucida Sans Unicode","Lucida Sans",'Segoe UI',AppleSDGothicNeo-Medium,'Malgun Gothic',Verdana,Tahoma,sans-serif;background:#fff;line-height:1.6;-webkit-font-smoothing:antialiased}.haroopad a{color:#3269a0}.haroopad a:hover{color:#4183c4}.haroopad h2{border-bottom:1px solid #e6e6e6}.haroopad h6{color:#777}.haroopad hr{border:1px solid #e6e6e6}.haroopad blockquote>code,.haroopad h1>code,.haroopad h2>code,.haroopad h3>code,.haroopad h4>code,.haroopad h5>code,.haroopad h6>code,.haroopad li>code,.haroopad p>code,.haroopad td>code{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:85%;background-color:rgba(0,0,0,.02);padding:.2em .5em;border:1px solid #efefef}.haroopad pre>code{font-size:1em;letter-spacing:-1px;font-weight:700}.haroopad blockquote{border-left:4px solid #e6e6e6;padding:0 15px;color:#777}.haroopad table{background-color:#fafafa}.haroopad table tr td,.haroopad table tr th{border:1px solid #e6e6e6}.haroopad table tr:nth-child(2n){background-color:#f2f2f2}.hljs{display:block;overflow-x:auto;padding:.5em;background:#fdf6e3;color:#657b83;-webkit-text-size-adjust:none}.diff .hljs-header,.hljs-comment,.hljs-doctype,.hljs-javadoc,.hljs-pi,.lisp .hljs-string{color:#93a1a1}.css .hljs-tag,.hljs-addition,.hljs-keyword,.hljs-request,.hljs-status,.hljs-winutils,.method,.nginx .hljs-title{color:#859900}.hljs-command,.hljs-dartdoc,.hljs-hexcolor,.hljs-link_url,.hljs-number,.hljs-phpdoc,.hljs-regexp,.hljs-rules .hljs-value,.hljs-string,.hljs-tag .hljs-value,.tex .hljs-formula{color:#2aa198}.css .hljs-function,.hljs-built_in,.hljs-chunk,.hljs-decorator,.hljs-id,.hljs-identifier,.hljs-localvars,.hljs-title,.vhdl .hljs-literal{color:#268bd2}.hljs-attribute,.hljs-class .hljs-title,.hljs-constant,.hljs-link_reference,.hljs-parent,.hljs-type,.hljs-variable,.lisp .hljs-body,.smalltalk .hljs-number{color:#b58900}.css .hljs-pseudo,.diff .hljs-change,.hljs-attr_selector,.hljs-cdata,.hljs-header,.hljs-pragma,.hljs-preprocessor,.hljs-preprocessor .hljs-keyword,.hljs-shebang,.hljs-special,.hljs-subst,.hljs-symbol,.hljs-symbol .hljs-string{color:#cb4b16}.hljs-deletion,.hljs-important{color:#dc322f}.hljs-link_label{color:#6c71c4}.tex .hljs-formula{background:#eee8d5}.MathJax_Hover_Frame{border-radius:.25em;-webkit-border-radius:.25em;-moz-border-radius:.25em;-khtml-border-radius:.25em;box-shadow:0 0 15px #83A;-webkit-box-shadow:0 0 15px #83A;-moz-box-shadow:0 0 15px #83A;-khtml-box-shadow:0 0 15px #83A;border:1px solid #A6D!important;display:inline-block;position:absolute}.MathJax_Hover_Arrow{position:absolute;width:15px;height:11px;cursor:pointer}#MathJax_About{position:fixed;left:50%;width:auto;text-align:center;border:3px outset;padding:1em 2em;background-color:#DDD;color:#000;cursor:default;font-family:message-box;font-size:120%;font-style:normal;text-indent:0;text-transform:none;line-height:normal;letter-spacing:normal;word-spacing:normal;word-wrap:normal;white-space:nowrap;float:none;z-index:201;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;-khtml-border-radius:15px;box-shadow:0 10px 20px gray;-webkit-box-shadow:0 10px 20px gray;-moz-box-shadow:0 10px 20px gray;-khtml-box-shadow:0 10px 20px gray;filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}.MathJax_Menu{position:absolute;background-color:#fff;color:#000;width:auto;padding:2px;border:1px solid #CCC;margin:0;cursor:default;font:menu;text-align:left;text-indent:0;text-transform:none;line-height:normal;letter-spacing:normal;word-spacing:normal;word-wrap:normal;white-space:nowrap;float:none;z-index:201;box-shadow:0 10px 20px gray;-webkit-box-shadow:0 10px 20px gray;-moz-box-shadow:0 10px 20px gray;-khtml-box-shadow:0 10px 20px gray;filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}.MathJax_MenuItem{padding:2px 2em;background:0 0}.MathJax_MenuArrow{position:absolute;right:.5em;color:#666}.MathJax_MenuActive .MathJax_MenuArrow{color:#fff}.MathJax_MenuArrow.RTL{left:.5em;right:auto}.MathJax_MenuCheck{position:absolute;left:.7em}.MathJax_MenuCheck.RTL{right:.7em;left:auto}.MathJax_MenuRadioCheck{position:absolute;left:1em}.MathJax_MenuRadioCheck.RTL{right:1em;left:auto}.MathJax_MenuLabel{padding:2px 2em 4px 1.33em;font-style:italic}.MathJax_MenuRule{border-top:1px solid #CCC;margin:4px 1px 0}.MathJax_MenuDisabled{color:GrayText}.MathJax_MenuActive{background-color:Highlight;color:HighlightText}.MathJax_Menu_Close{position:absolute;width:31px;height:31px;top:-15px;left:-15px}#MathJax_Zoom{position:absolute;background-color:#F0F0F0;overflow:auto;display:block;z-index:301;padding:.5em;border:1px solid #000;margin:0;font-weight:400;font-style:normal;text-align:left;text-indent:0;text-transform:none;line-height:normal;letter-spacing:normal;word-spacing:normal;word-wrap:normal;white-space:nowrap;float:none;box-shadow:5px 5px 15px #AAA;-webkit-box-shadow:5px 5px 15px #AAA;-moz-box-shadow:5px 5px 15px #AAA;-khtml-box-shadow:5px 5px 15px #AAA;filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}#MathJax_ZoomOverlay{position:absolute;left:0;top:0;z-index:300;display:inline-block;width:100%;height:100%;border:0;padding:0;margin:0;background-color:#fff;opacity:0;filter:alpha(opacity=0)}#MathJax_ZoomFrame{position:relative;display:inline-block;height:0;width:0}#MathJax_ZoomEventTrap{position:absolute;left:0;top:0;z-index:302;display:inline-block;border:0;padding:0;margin:0;background-color:#fff;opacity:0;filter:alpha(opacity=0)}.MathJax_Preview{color:#888}#MathJax_Message{position:fixed;left:1px;bottom:2px;background-color:#E6E6E6;border:1px solid #959595;margin:0;padding:2px 8px;z-index:102;color:#000;font-size:80%;width:auto;white-space:nowrap}#MathJax_MSIE_Frame{position:absolute;top:0;left:0;width:0;z-index:101;border:0;margin:0;padding:0}.MathJax_Error{color:#C00;font-style:italic}footer{position:fixed;font-size:.8em;text-align:right;bottom:0;margin-left:-25px;height:20px;width:100%}</style>
</head>
<body class="markdown haroopad">
<h1 id="p1820r0:-recommendations-for-a-compromise-on-handling-errors-and-cancellations-in-executors"><a name="p1820r0:-recommendations-for-a-compromise-on-handling-errors-and-cancellations-in-executors" href="#p1820r0:-recommendations-for-a-compromise-on-handling-errors-and-cancellations-in-executors"></a>P1820r0: Recommendations for a compromise on handling errors and cancellations in executors</h1><p><strong>Date: 2019-10-07</strong></p><p><strong>Audience: SG1, LEWG</strong></p><p><strong>Authors: Gordon Brown</strong></p><p><strong>Emails: gordon@codeplay.com</strong></p><p><strong>Reply to: gordon@codeplay.com</strong></p><h2 id="acknowledgements"><a name="acknowledgements" href="#acknowledgements"></a>Acknowledgements</h2><p>Thanks to Chris Kohlhoff, Jamie Allsop, David Hollman, Eric Niebler, Kirk Shoop, Lewis Baker, Lee Howes, Jared Hoberock, Michał Dominiak and Christopher Di Bella for their helpful feedback.</p><h2 id="preface"><a name="preface" href="#preface"></a>Preface</h2><p>This paper was originally written with the aim of resolving two conflicting positions on how to handle errors and cancellations in executors presented in <a href="wg21.link/p1660">P1660</a> and <a href="wg21.link/p1791">P1791</a> at the Cologne 2019 meeting. However, many of the recommended changes have now been applied in <a href="wg21.link/p0443r11">P0443r11</a>.</p><h2 id="1.-motivation"><a name="1.-motivation" href="#1.-motivation"></a>1. Motivation</h2><p><a href="wg21.link/p1660">P1660</a> proposes a mechanism for handling errors and cancellations by which work items are represented by a <code>callback</code> which in addition to being an <code>invocable</code> also provides the <code>error</code> and <code>done</code> member functions for signalling errors and cancellations respectively. This approach has the benefit of allowing errors and cancellations to be propagated back via a separate channel from the value channel, even through different execution contexts. However it requires these channels to be provided every time a work item is enqueued.</p><p><a href="wg21.link/p1791">P1791</a> proposes an alternative mechanism for handling errors by which errors are handled by a callback associated with the executor via the <code>on_error_t</code> property, allowing the callback that handles errors to be specified only does not require work items to be defined as a <code>callback</code>. This approach is also useful for when you want errors to be handled by the execution context and maps closer to execution contexts such as OpenCL or CUDA which cannot always identify which work item triggered the error.</p><p><a href="wg21.link/p1660">P1660</a> provides a way to couple tasks with error and cancellation handling via the <code>callback</code> concept, however there exists domains where it’s desireable to invoke functions which simply model <code>invocable</code> and handle errors and cancellations via some out-of-band mechanism such as calling <code>std::terminate</code>, propagating to some back-channel (provided either by the user or by the execution context) or even leaving the errors unhandled. The approach suggested in <a href="wg21.link/p1660">P1660</a> does allow errors to be handled via alternative mechanisms however those mechanisms are currently entirely implementation defined, leaving error handling in the domains described above as unsupported in this model, which subsequently leaves these domains as unsupported.</p><p>Furthermore, there are some domains, such as GPU compute, where arbitrary callbacks to the host from a GPU driver would be detrimental to performance. However, there are algorithms expected to be defined with the <code>callback</code>concept as a basis operation such as those which define arbitrary error and cancellation handling channels which would require exactly this kind of arbitrary host callbacks. For execution contexts in such domains the only solution is to either ignore the semantic expectations of the algorithm or use a completely alternate set of algorithms, both of which are not acceptable solutions for a general executor solution.</p><p>In the case of a domain that would prefer to implement error and cancellation handling via an alternative mechanism to <code>callback</code>s, if a <code>callback</code> based approach was required by the basis operations this would introduce an unavoidable burden on implementation overhead to handling error in cases where it is necessary to type-erase the tasks, even if errors could be handled in an alternate mechanism.</p><p>Another consideration on code share-ability, is that since <code>sender</code>s (as described by <a href="wg21.link/p1660">P1660</a>) are required to be specialized per execution context in order to be implemented efficiently, any algorithms which are defined with the <code>callback</code> concept as their basis operation cannot support executors which cannot or choose not to handle errors via <code>callback</code>s. This will ultimately mean codebases written to such algorithms may have to be re-written when being ported to run on different execution contexts, which is a concern for generic programming.</p><h2 id="2.-summary"><a name="2.-summary" href="#2.-summary"></a>2. Summary</h2><p>Throughout the discussion on this topic a number of recommendations have been identified:</p><table>
<thead>
<tr>
<th>Recommendation</th>
<th>Status in <a href="wg21.link/p0443r11">P0443r11</a></th>
</tr>
</thead>
<tbody>
<tr>
<td>1. The <code>invocable</code> and <code>callback</code> concepts are independent and not part of a subsumption hierarchy.</td>
<td>Adopted as <code>invocable</code> and <code>receiver</code> concepts.</td>
</tr>
<tr>
<td>2. An algorithm or control structure can be constrained on <code>invocable</code>, and not be expected to support types which model <code>callback</code>.</td>
<td>Adopted via <code>executor</code>-based algorithms.</td>
</tr>
<tr>
<td>3. An algorithm or control structure can be constrained on <code>callback</code> and must honour the <code>callback</code> type’s error an done channels.</td>
<td>Adopted via <code>sender</code>-based algorithms.</td>
</tr>
<tr>
<td>4. An executor can opt to support only an execution function which accepts <code>invocable</code>.</td>
<td>Adopted as <code>executor</code> concept.</td>
</tr>
<tr>
<td>5. An executor can opt to support only an execution function which accepts <code>callback</code>.</td>
<td>Adopted as <code>sender</code> concept.</td>
</tr>
<tr>
<td>6. The error and cancellation handling behavior of an execution function which accepts <code>invocable</code> should be well-defined via properties.</td>
<td>Not adopted.</td>
</tr>
</tbody>
</table><h2 id="3.-suggested-change:-executor-properties-for-error-handling-and-cancellation"><a name="3.-suggested-change:-executor-properties-for-error-handling-and-cancellation" href="#3.-suggested-change:-executor-properties-for-error-handling-and-cancellation"></a>3. Suggested change: executor properties for error handling and cancellation</h2><p>To allow an executor to specify alternative error and cancellation mechanisms this paper proposes that P0443 adopt two new groups of behavioral properties (as defined by <a href="wg21.link/p0443">P0443</a>), <code>execution::invocable_error_channel_t</code> and <code>execution::invocable_cancellation_channel_t</code>, which can be used to specify to an executor how to handle errors when a work item is specified with an <code>invocable</code> rather than a <code>callback</code>.</p><p>This paper currently proposes a limited number of properties for <code>execution::invocable_error_channel_t</code> and <code>execution::invocable_cancellation_channel_t</code>, however it is expected that these property groups be extended to incorporate other error and cancellation mechanism in the future as requirements for them arise.</p><h3 id="`execution::invocable_error_channel_t`"><a name="`execution::invocable_error_channel_t`" href="#`execution::invocable_error_channel_t`"></a><code>execution::invocable_error_channel_t</code></h3><p>The <code>execution::invocable_error_channel_t</code> properties is a group of mutually exclusive behavioral properties that specify the guarantee which an Executor makes as to how it responds to an error of a work item being executed.</p><p>For some Executor type <code>E</code>, when a work item being executed by an execution agent created by <code>E</code> results in an error <code>err</code>, <code>E</code> must:</p><ul>
<li>If the work-item was submitted as a <code>callback</code> <code>cb</code>, call <code>cb.error(err)</code>.</li><li>Else, if the work-item was submitted as an <code>invocable</code> <code>i</code>, behave as-if calling a default constructed <code>callback</code> with <code>i</code> as its value channel and a default error channel who’s behavior is specified by <code>execution::invocable_error_channel_t</code>.</li></ul><table>
<thead>
<tr>
<th>Property type</th>
<th>Property object</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>execution::invocable_error_channel_t::terminate_t</code></td>
<td><code>execution::invocable_error_channel.terminate</code></td>
<td>The error channel of the default constructed <code>callback</code> will invoke <code>std::terminate</code>.</td>
</tr>
<tr>
<td><code>execution::invocable_error_channel_t::back_channel_t</code></td>
<td><code>execution::invocable_error_channel.back_channel(i)</code></td>
<td>The error channel of the default constructed <code>callback</code> behaves as-if calling <code>bk(err)</code>, where <code>bk</code> is an <code>invocable</code> that is used as a back-channel for <code>E</code>. <br> <code>execution::invocable_error_channel.back_channel</code> takes a parameter <code>bk</code>, where <code>bk</code> is an <code>invocable&lt;Error&gt;</code>.</td>
</tr>
</tbody>
</table><h3 id="`execution::invocable_cancellation_channel_t`"><a name="`execution::invocable_cancellation_channel_t`" href="#`execution::invocable_cancellation_channel_t`"></a><code>execution::invocable_cancellation_channel_t</code></h3><p>The <code>execution::invocable_cancellation_channel_t</code> properties is a group of mutually exclusive behavioral properties that specify the guarantee which an Executor makes as to how it responds to a cancellation of a work item being executed.</p><p>For some Executor type <code>E</code>:</p><table>
<thead>
<tr>
<th>Property type</th>
<th>Property object</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>execution::invocable_cancellation_channel_t::unhandled_t</code></td>
<td><code>execution::invocable_cancellation_channel.unhandled</code></td>
<td>When a work item being executed by <code>E</code> is cancelled <code>E</code> does not propagate the cancellation.</td>
</tr>
<tr>
<td><code>execution::invocable_cancellation_channel_t::back_channel_t</code></td>
<td><code>execution::invocable_cancellation_channel.back_channel(i)</code></td>
<td>When a work item being executed by <code>E</code> is cancelled, <code>E</code> propagates the cancellation by calling <code>bk()</code>, where <code>bk</code> is an <code>invocable</code> that is used as a back-channel for <code>E</code>. <br> <code>execution::invocable_cancellation_channel.back_channel</code> takes a parameter <code>bk</code>, where <code>bk</code> is an <code>invocable&lt;&gt;</code>.</td>
</tr>
</tbody>
</table><h3 id="status-in-p0443"><a name="status-in-p0443" href="#status-in-p0443"></a>Status in P0443</h3><p>This recommendation was not adopted into <a href="wg21.link/p0443r11">P0443r11</a>. </p><h2 id="4.-suggested-change:-separate-executor-concepts-for-`execute(invocable)`-and-`execute(callback)`"><a name="4.-suggested-change:-separate-executor-concepts-for-`execute(invocable)`-and-`execute(callback)`" href="#4.-suggested-change:-separate-executor-concepts-for-`execute(invocable)`-and-`execute(callback)`"></a>4. Suggested change: separate executor concepts for <code>execute(invocable)</code> and <code>execute(callback)</code></h2><p>In order to allow executor authors freedom to choose the level of support they want for their executors (i.e. support for types which model <code>callback</code> or types which model <code>invocable</code>), whilst also allowing algorithm authors to specify constraints on the kind of executors required this paper proposes that P0443 introduces a subsumption hierarchy of executor types taking the form of <code>invocable_executor</code> and <code>callback_executor</code> as a refinement of <code>invocable_executor</code>.</p><p><em>[ Note: The names of these concepts are placeholder names and are expected to be bikeshed. ]</em></p><h3 id="`invocable_executor`-concept"><a name="`invocable_executor`-concept" href="#`invocable_executor`-concept"></a><code>invocable_executor</code> concept</h3><p>The <code>invocable_executor</code> concept requires a type to have a <code>.execute</code> member function which takes an <code>invocable</code> which handles errors and continuations according to the value of the <code>execution::invocable_error_channel_t</code> and <code>execution::invocable_cancellation_channel_t</code> properties for the executor respectively.</p><pre><code data-origin="<pre><code>template&amp;lt;class T, class F = void(*)()&amp;gt;
concept invocable_executor = invocable&amp;lt;F&amp;gt; &amp;amp;&amp;amp;
   requires (T&amp;amp;&amp;amp; t, F&amp;amp;&amp;amp; f) {
      std::forward&amp;lt;T&amp;gt;(t).execute(std::forward&amp;lt;F&amp;gt;(f));
   };
</code></pre>">template&lt;class T, class F = void(*)()&gt;
concept invocable_executor = invocable&lt;F&gt; &amp;&amp;
   requires (T&amp;&amp; t, F&amp;&amp; f) {
      std::forward&lt;T&gt;(t).execute(std::forward&lt;F&gt;(f));
   };
</code></pre><h3 id="`callback_executor`-concept"><a name="`callback_executor`-concept" href="#`callback_executor`-concept"></a><code>callback_executor</code> concept</h3><p>The <code>callback_executor</code> concept requires a type to model the <code>invocable_executor</code> concept and to have a further <code>.execute</code> member function which takes a <code>callback</code> which handles errors and cancellations via the <code>error</code> and <code>done</code> channels of the <code>callback</code> as defined in <a href="wg21.link/p1660">P1660</a>.</p><pre><code data-origin="<pre><code>template&amp;lt;class T, class C = __callback&amp;gt;
concept callback_executor = invocable_executor&amp;lt;T&amp;gt; ||
  (callback&amp;lt;C&amp;gt; &amp;amp;&amp;amp; requires (T&amp;amp;&amp;amp; t, C&amp;amp;&amp;amp; c) {
      std::forward&amp;lt;T&amp;gt;(t).execute(std::forward&amp;lt;C&amp;gt;(c));
  });
</code></pre>">template&lt;class T, class C = __callback&gt;
concept callback_executor = invocable_executor&lt;T&gt; ||
  (callback&lt;C&gt; &amp;&amp; requires (T&amp;&amp; t, C&amp;&amp; c) {
      std::forward&lt;T&gt;(t).execute(std::forward&lt;C&gt;(c));
  });
</code></pre><p><em>[ Note: <code>__callback</code> is a type used for exposition purposes only. ]</em></p><h3 id="status-in-p0443"><a name="status-in-p0443" href="#status-in-p0443"></a>Status in P0443</h3><p>This recommendation was adopted into <a href="wg21.link/p0443r11">P0443r11</a> with the concepts <code>executor</code> which is required to provide <code>execute(invocable)</code> and <code>sender</code> which is required to provide <code>submit(callback)</code> as separate types rather than a subsumption hierarchy, and minus the requirement to support on <code>executor</code> to perform error handling according to the <code>execution::invocable_error_channel_t</code> and <code>execution::invocable_cancellation_channel_t</code> properties.</p><h2 id="5.-suggested-change:-customization-point-`execution::execute`"><a name="5.-suggested-change:-customization-point-`execution::execute`" href="#5.-suggested-change:-customization-point-`execution::execute`"></a>5. Suggested change: customization point <code>execution::execute</code></h2><p>In order to allow adaptations between a <code>invocable_executor</code> and a <code>callback_executor</code> this paper recommends that P0443 provide the <code>execution::execute</code> customization point object.</p><p>For a given executor <code>e</code> of type <code>E</code> and a given function <code>f</code>of type <code>F</code>, <code>execution:execute(e, f)</code> should behave as follows:</p><table>
<thead>
<tr>
<th></th>
<th><code>E</code> models <code>invocable_executor</code></th>
<th><code>E</code> models <code>callback_executor</code></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>F</code> models <code>invocable</code></td>
<td>Invokes <code>execute(invocable &amp;&amp;)</code>. <br> Errors and cancellations are handled according to the value of the <code>execution::invocable_error_channel_t</code> and <code>execution::invocable_cancellation_channel_t</code> properties for <code>E</code> respectively.</td>
<td>Invokes <code>execute(invocable &amp;&amp;)</code>. <br> Errors and cancellations are handled according to the value of the <code>execution::invocable_error_channel_t</code> and <code>execution::invocable_cancellation_channel_t</code> properties for <code>E</code> respectively.</td>
</tr>
<tr>
<td><code>F</code> models <code>callback</code></td>
<td>Compile-time error.</td>
<td>Invokes <code>execute(callback &amp;&amp;)</code>. <br> Errors and cancellations are handled by <code>F::error</code> and <code>F::done</code> respectively.</td>
</tr>
</tbody>
</table><p>The one caveat to the semantic relationship between executor type and function type is that as <code>invocable</code> and <code>callback</code> are a subsumption hierarchy, calling <code>execution:execute</code> with an executor type that models <code>invocable_executor</code> and a function type which models <code>callback</code> will result in the <code>error</code> and <code>done</code> channels of the <code>callback</code> not being used. However if this is a problem for algorithm authors for any particular algorithm this can be avoided by simply constraining the algorithm on <code>callback_executor</code> therefore preventing the user from using a type which only models <code>invocable_executor</code>.</p><p><em>[ Note: The above definitions of <code>invocable_executor</code> and <code>callback_executor</code> are for exposition purposes, and the <code>callback_executor</code> concept can also be implemented as a single overload which handles both cases. ]</em></p><h3 id="status-in-p0443"><a name="status-in-p0443" href="#status-in-p0443"></a>Status in P0443</h3><p>This recommendation was adopted into <a href="wg21.link/p0443r11">P0443r11</a> with the customization points <code>tbd::execute(executor, invocable)</code> which is required to provide the semantics of <code>execute(invocable)</code> and <code>tbd::submit(sender, callback)</code> which is required to provide the semantics of <code>submit(callback)</code>, and minus the requirement to support on <code>execute(executor, invocable)</code> to perform error handling according to the <code>execution::invocable_error_channel_t</code> and <code>execution::invocable_cancellation_channel_t</code> properties.</p><h2 id="6.-suggested-change:-separately-constrained-algorithms-and-control-structures"><a name="6.-suggested-change:-separately-constrained-algorithms-and-control-structures" href="#6.-suggested-change:-separately-constrained-algorithms-and-control-structures"></a>6. Suggested change: Separately constrained algorithms and control structures</h2><p>By introducing the subsumption hierarchy of executor types; <code>invocable_executor</code> and <code>callback_executor</code> algorithm authors can allow an algorithm to be generic to the executor type or enforce strict requirements on whether only types which model <code>callback</code> can be used.</p><table>
<thead>
<tr>
<th>Algorithm constraints</th>
<th>Expected behavior</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>template &lt;class S, class F&gt; requires invocable_executor&lt;typename S::executor_type&gt; auto transform(S sender, F func);</code></td>
<td>Generic algorithm which can take an executor that models either <code>invocable_executor</code> or <code>callback_executor</code> behaving appropriately to what is passed, returning a sender which may use <code>callback</code> or may use <code>execution::invocable_error_channel_t</code> and <code>execution::invocable_cancellation_channel_t</code>.</td>
</tr>
<tr>
<td><code>template &lt;class S, class F, class E&gt; requires callback_executor&lt;typename S::executor_type&gt; auto transform_error(S sender, F func, E errorFunc);</code></td>
<td><code>callback</code> specific algorithm which can only take an executor that models either <code>callback_executor</code> and therefore must return a sender that uses <code>callback</code>.</td>
</tr>
</tbody>
</table><h3 id="status-in-p0443"><a name="status-in-p0443" href="#status-in-p0443"></a>Status in P0443</h3><p>It is the intended direction of P0443 is to adopt algorithms such as those defined above, however <a href="wg21.link/p0443r11">P0443r11</a> does not yet specify these.</p>

<footer style="position:fixed; font-size:.8em; text-align:right; bottom:0px; margin-left:-25px; height:20px; width:100%;">generated by <a href="http://pad.haroopress.com" target="_blank">haroopad</a></footer>
</body>
</html>
