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

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

        body {
                counter-reset: example figure issue;

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

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

                /* Colors */
                color: black;
                background: white top left fixed no-repeat;
                background-size: 25px auto;
        }


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                        background: white;
                        box-shadow: 0 0 2px;
                        border: none;
                        border-top-right-radius: 1.33em;
                        background: white;
                }
                #toc-nav > #toc-jump {
                        padding-bottom: 2em;
                        margin-bottom: -1.9em;
                }

                #toc-nav > a:hover,
                #toc-nav > a:focus {
                        background: #f8f8f8;
                }
                #toc-nav > a:not(:hover):not(:focus) {
                        color: #707070;
                }

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

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

                #toc-toggle-inline {
                        vertical-align: 0.05em;
                        font-size: 80%;
                        color: gray;
                        color: hsla(203,20%,40%,.7);
                        border-style: none;
                        background: transparent;
                        position: relative;
                }
                #toc-toggle-inline:hover:not(:active),
                #toc-toggle-inline:focus:not(:active) {
                        text-shadow: 1px 1px silver;
                        top: -1px;
                        left: -1px;
                }

                #toc-nav :active {
                        color: #C00;
                }
        }

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

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

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

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

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

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

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

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

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

        h1, h2, h3 {
                color: #005A9C;
                background: transparent;
        }

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

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

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

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

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

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

        p {
                margin: 1em 0;
        }

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

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

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

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

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

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

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

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

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


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

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

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

        del { color: red;  text-decoration: line-through; }
        ins { color: #080; text-decoration: underline;    }

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

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

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

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

        pre, code, samp {
                font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
                font-size: .9em;
                page-break-inside: avoid;
                hyphens: none;
                text-transform: none;
        }
        pre code,
        code code {
                font-size: 100%;
        }

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

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

  /* Do something nice. */

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

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

        /* We hyperlink a lot, so make it less intrusive */
        a[href] {
                color: #034575;
                text-decoration: none;
                border-bottom: 1px solid #707070;
                /* Need a bit of extending for it to look okay */
                padding: 0 1px 0;
                margin: 0 -1px 0;
        }
        a:visited {
                border-bottom-color: #BBB;
        }

        /* Use distinguishing colors when user is interacting with the link */
        a[href]:focus,
        a[href]:hover {
                background: #f8f8f8;
                background: rgba(75%, 75%, 75%, .25);
                border-bottom-width: 3px;
                margin-bottom: -2px;
        }
        a[href]:active {
                color: #C00;
                border-color: #C00;
        }

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

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

        img {
                border-style: none;
        }

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

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

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

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

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

        .issue,
        .note,
        .example,
        .advisement,
        .assertion,
        blockquote {
                margin: 1em auto;
        }
        .note  > p:first-child,
        .issue > p:first-child,
        blockquote > :first-child {
                margin-top: 0;
        }
        blockquote > :last-child {
                margin-bottom: 0;
        }

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

        blockquote {
                border-color: silver;
        }

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

        .issue {
                border-color: #E05252;
                background: #FBE9E9;
                counter-increment: issue;
                overflow: auto;
        }
        .issue::before, .issue > .marker {
                text-transform: uppercase;
                color: #AE1E1E;
                padding-right: 1em;
                text-transform: uppercase;
        }
        /* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
           or use class="marker" to mark up the issue number in source. */

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

        .example {
                border-color: #E0CB52;
                background: #FCFAEE;
                counter-increment: example;
                overflow: auto;
                clear: both;
        }
        .example::before, .example > .marker {
                text-transform: uppercase;
                color: #827017;
                min-width: 7.5em;
                display: block;
        }
        /* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
           or use class="marker" to mark up the example number in source. */

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

        .note {
                border-color: #52E052;
                background: #E9FBE9;
                overflow: auto;
        }

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

        details.note > summary {
                display: block;
                color: hsl(120, 70%, 30%);
        }
        details.note[open] > summary {
                border-bottom: 1px silver solid;
        }

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

        .assertion {
                border-color: #AAA;
                background: #EEE;
        }

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

        .advisement {
                border-color: orange;
                border-style: none solid;
                background: #FFEECC;
        }
        strong.advisement {
                display: block;
                text-align: center;
        }
        .advisement > .marker {
                color: #B35F00;
        }

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

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

        .annoying-warning:not(details),
        details.annoying-warning:not([open]) > summary,
        details.annoying-warning[open] {
                background: #fdd;
                color: red;
                font-weight: bold;
                padding: .75em 1em;
                border: thick red;
                border-style: solid;
                border-radius: 1em;
        }
        .annoying-warning :last-child {
                margin-bottom: 0;
        }

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

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

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

        .def {
                padding: .5em 1em;
                background: #DEF;
                margin: 1.2em 0;
                border-left: 0.5em solid #8CCBF2;
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


/*
Alternate table alignment rules

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

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

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

Possible extra rowspan handling

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

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

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


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

        .toc a {
                /* More spacing; use padding to make it part of the click target. */
                padding-top: 0.1rem;
                /* Larger, more consistently-sized click target */
                display: block;
                /* Reverse color scheme */
                color: black;
                border-color: #3980B5;
                border-bottom-width: 3px !important;
                margin-bottom: 0px !important;
        }
        .toc a:visited {
                border-color: #054572;
        }
        .toc a:not(:focus):not(:hover) {
                /* Allow colors to cascade through from link styling */
                border-bottom-color: transparent;
        }

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

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

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

                /* Section numbers in a column of their own */
                .toc .secno {
                        float: left;
                        width: 4rem;
                        white-space: nowrap;
                }

                .toc li {
                        clear: both;
                }

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

                /* Tighten up indentation in narrow ToCs */
                @media (max-width: 30em) {
                        :not(li) > .toc              { margin-left:  4rem; }
                        .toc .secno                  { margin-left: -4rem; }
                        .toc > li li li              { margin-left:  1rem; }
                        .toc > li li li .secno       { margin-left: -5rem; }
                        .toc > li li li li .secno    { margin-left: -6rem; }
                        .toc > li li li li li .secno { margin-left: -7rem; }
                }
        /* } */

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


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

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

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

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

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

        table.index tr:hover td:not([rowspan]),
        table.index tr:hover th:not([rowspan]) {
                background: #f7f8f9;
        }

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

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

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

/******************************************************************************/
/*                                    Legacy                                  */
/******************************************************************************/

        /* This rule is inherited from past style sheets. No idea what it's for. */
        .hide { display: none }



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

        .figure .caption, .sidefigure .caption, figcaption {
                /* in case figure is overlarge, limit caption to 50em */
                max-width: 50rem;
                margin-left: auto;
                margin-right: auto;
        }
        .overlarge > table {
                /* limit preferred width of table */
                max-width: 50em;
                margin-left: auto;
                margin-right: auto;
        }

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

        @media not print {
                .overlarge {
                        overflow-x: auto;
                        /* See Lea Verou's explanation background-attachment:
                         * http://lea.verou.me/2012/04/background-attachment-local/
                         *
                        background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
                                    top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
                                    top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
                                    top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
                                    white;
                        background-repeat: no-repeat;
                        */
                }
        }
</style>
<style type="text/css">
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }
  </style>
  <meta content="Bikeshed version 47cb5324cd11789aef12f220cf86d1780f94ab9c" name="generator">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="209cd791d78b961d1253389611916c0aa1b11ba1" name="document-revision">
<style>/* style-md-lists */

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

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

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

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

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

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

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

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

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

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

[data-link-type=biblio] {
    white-space: pre;
}</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P1238R1<br>SG16: Unicode Direction</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Draft Proposal, <time class="dt-updated" datetime="2019-06-11">2019-06-11</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>Authors:
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:tom@honermann.net">Tom Honermann</a>
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:corentin.jabot@gmail.com">Corentin Jabot</a>
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:phdofthehouse@gmail.com">JeanHeyd Meneide</a>
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:mzeren@vmware.com">Mark Zeren</a>
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:rmf@rmf.io">Martinho Fernandes</a>
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:dascandy@gmail.com">Peter Bindels</a>
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:sdowney@gmail.com">Steve Downey</a>
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:whatwasthataddress@gmail.com">Zach Laine</a>
     <dt>Audience:
     <dd>DIRECTION, SG16
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>SG16 initial Unicode direction and guidance for C++20 and beyond.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li><a href="#changes"><span class="secno">1</span> <span class="content">Changes since <span>[P1238R0]</span></span></a>
    <li>
     <a href="#constraints"><span class="secno">2</span> <span class="content">Constraints: Accepting the things we cannot change</span></a>
     <ol class="toc">
      <li><a href="#constraint-implementation"><span class="secno">2.1</span> <span class="content">Constraint: The ordinary and wide execution encodings are implementation defined</span></a>
      <li><a href="#constraint-runtime"><span class="secno">2.2</span> <span class="content">Constraint: The ordinary and wide execution encodings are run-time properties</span></a>
      <li><a href="#constraint-portability"><span class="secno">2.3</span> <span class="content">Constraint: There is no portable primary execution encoding</span></a>
      <li><a href="#constraint-wchar_t"><span class="secno">2.4</span> <span class="content">Constraint: <code class="highlight"><c- b>wchar_t</c-></code> is a portability deadend</span></a>
      <li><a href="#constraint-char"><span class="secno">2.5</span> <span class="content">Constraint: <code class="highlight"><c- b>char</c-></code> aliases everything</span></a>
      <li><a href="#constraint-nih_syndrome"><span class="secno">2.6</span> <span class="content">Constraint: Implementors cannot afford to rewrite ICU</span></a>
      <li><a href="#constraint-filenames"><span class="secno">2.7</span> <span class="content">Constraint: File names do not have an associated character encoding</span></a>
     </ol>
    <li>
     <a href="#guidelines"><span class="secno">3</span> <span class="content">Guidelines: Keep your eyes on the road, your hands upon the wheel</span></a>
     <ol class="toc">
      <li><a href="#guideline-practices"><span class="secno">3.1</span> <span class="content">Guideline: Avoid excessive inventiveness; look for existing practice</span></a>
      <li><a href="#guideline-inline"><span class="secno">3.2</span> <span class="content">Guideline: Avoid gratuitous departure from C</span></a>
     </ol>
    <li><a href="#direction"><span class="secno">4</span> <span class="content">Direction: Designing for where we want to be and how to get there</span></a>
    <li>
     <a href="#directives"><span class="secno">5</span> <span class="content">Directives: Do or do not, there is no try</span></a>
     <ol class="toc">
      <li><a href="#directive-encoding_aware"><span class="secno">5.1</span> <span class="content">Directive: Standardize new encoding aware text container and view types</span></a>
      <li><a href="#directive-generic_algorithms"><span class="secno">5.2</span> <span class="content">Directive: Standardize generic interfaces for Unicode algorithms</span></a>
      <li><a href="#directives-other_useful"><span class="secno">5.3</span> <span class="content">Directive: Standarize useful features from other languages</span></a>
      <li><a href="#directive-transcoding"><span class="secno">5.4</span> <span class="content">Directive: Improve support for transcoding at program boundaries</span></a>
      <li><a href="#directive-wording"><span class="secno">5.5</span> <span class="content">Directive: Propose resolutions for existing issues and wording improvements opportunistically</span></a>
     </ol>
    <li>
     <a href="#non-directives"><span class="secno">6</span> <span class="content">Non-directives: Thanks, but No Thanks</span></a>
     <ol class="toc">
      <li><a href="#non-directive-ui"><span class="secno">6.1</span> <span class="content">Non-directive: User input</span></a>
      <li><a href="#non-directive-graphics"><span class="secno">6.2</span> <span class="content">Non-directive: Fonts, graphical text rendering</span></a>
     </ol>
    <li><a href="#acknowledgements"><span class="secno">7</span> <span class="content">Acknowledgements</span></a>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <p>The SG16 Unicode study group was officially formed at the 2018 WG21 meeting in Jacksonville, Florida. We have not yet had our inaugural meeting (that is planned to be held during the upcoming meeting in San Diego), but we’ve had an active group of WG21 members meeting via video conference regularly since August of 2017, well before our formation as an official study group. Summaries of these meetings are available at <a href="https://github.com/sg16-unicode/sg16-meetings/blob/master/README.md">the SG16 meetings repository</a>.</p>
   <p>Our proposals so far have focused on relatively small or foundational features that have a realistic chance of being adopted for C++20. These include:</p>
   <ul>
    <li data-md>
     <p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r5.html">P0482R5: char8_t: A type for UTF-8 characters and strings</a> <sup><a data-link-type="biblio" href="#biblio-p0482r5">[P0482R5]</a></sup></p>
    <li data-md>
     <p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1025r1.html">P1025R1: Update The Reference To The Unicode Standard</a> <sup><a data-link-type="biblio" href="#biblio-p1025r1">[P1025R1]</a></sup></p>
    <li data-md>
     <p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1041r1.html">P1041R1: Make char16_t/char32_t string literals be UTF-16/32</a> <sup><a data-link-type="biblio" href="#biblio-p1041r1">[P1041R1]</a></sup></p>
    <li data-md>
     <p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1072r0.html">P1072R0: Default Initialization for basic_string</a> <sup><a data-link-type="biblio" href="#biblio-p1072r0">[P1072R0]</a></sup></p>
    <li data-md>
     <p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1097r1.html">P1097R1: Named character escapes</a> <sup><a data-link-type="biblio" href="#biblio-p1097r1">[P1097R1]</a></sup></p>
   </ul>
   <p>All other work that we are pursuing is targeting C++23 or later.</p>
   <p>This paper discusses a set of constraints, guidelines, directives, and non-directives intended to guide our continuing efforts to improve Unicode and text processing support in C++. Paper authors intending to propose Unicode or text processing related features are encouraged to consider the perspectives and guidelines discussed here in their designs, or to submit papers arguing against them.</p>
   <h2 class="heading settled" data-level="1" id="changes"><span class="secno">1. </span><span class="content">Changes since <a data-link-type="biblio" href="#biblio-p1238r0">[P1238R0]</a></span><a class="self-link" href="#changes"></a></h2>
   <ul>
    <li data-md>
     <p>Added constraint 7, File names do not have an associated character encoding.</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="constraints"><span class="secno">2. </span><span class="content">Constraints: Accepting the things we cannot change</span><a class="self-link" href="#constraints"></a></h2>
   <p>C++ has a long history and, as unfortunate as it may be at times, the past remains stubbornly immutable. As we work to improve the future, we must remain cognizant of the many billions of lines of C++ code in use today and how we will enable past work to retain its value in the future. The following limitations reflect constraints on what we cannot affordably change, at least not in the short term.</p>
   <h3 class="heading settled" data-level="2.1" id="constraint-implementation"><span class="secno">2.1. </span><span class="content">Constraint: The ordinary and wide execution encodings are implementation defined</span><a class="self-link" href="#constraint-implementation"></a></h3>
   <p><a href="https://w3techs.com/technologies/details/en-utf8/all/all">UTF-8 has conquered the web</a> <sup><a data-link-type="biblio" href="#biblio-w3techs">[W3Techs]</a></sup>, but no such convergence has yet occurred for the execution and wide execution character encodings. Popular and commercially significant platforms such as Windows and z/OS continue to support a wide array of ASCII and EBCDIC based encodings for the execution character encoding as required for compatibility by their long time customers.</p>
   <p>Might these platforms eventually move to UTF-8 or possibly cease to be relevant for new C++ standards?</p>
   <p>Microsoft does not yet offer full support for UTF-8 as the execution encoding for its compiler. Support for a /utf-8 compiler option was added recently, but it does not affect the behavior of their standard library implementation, nor is UTF-8 selectable as the execution encoding at run-time via environment settings or by calling <code class="highlight"><c- n>setlocale</c-><c- p>()</c-></code>. Recent Windows 10 releases now support a beta option that allows setting the Windows system code page to UTF-8 and this does affect the standard library (as well as all other programs running on the system). These additions indicate that it will likely be possible to write native UTF-8 programs for Windows using the Microsoft compiler in the not too distant future. However, there will be existing software written for Windows that will need to be migrated to new C++ standards without incurring the cost of transition to UTF-8 for a long time to come.</p>
   <p>IBM has not publicly released a C++11 compliant version of their xlC compiler for z/OS. However, they have <a href="https://developer.ibm.com/mainframe/products/ibm-toolkit-swift-z-os">publicly released support for Swift on z/OS</a> <sup><a data-link-type="biblio" href="#biblio-swiftonz">[SwiftOnZ]</a></sup>, and Swift is built on top of LLVM and Clang. Though IBM has not publicly released a port of Clang to z/OS, this indicates that such a port exists and a post to the Swift <a href="https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20170508/004572.html">developers mailing lists confirms it</a> <sup><a data-link-type="biblio" href="#biblio-clangonz">[ClangOnZ]</a></sup>.</p>
   <p>The <code class="highlight"><c- b>char16_t</c-></code> and <code class="highlight"><c- b>char32_t</c-></code> encodings are currently implementation defined as well. However, all existing implementations use UTF-16 and UTF-32 respectively for these encodings, thus their implementation definedness is not a constraint. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1041r1.html">P1041R1</a> <sup><a data-link-type="biblio" href="#biblio-p1041r1">[P1041R1]</a></sup> proposes officially standardizing UTF-16 and UTF-32 for these encodings.</p>
   <h3 class="heading settled" data-level="2.2" id="constraint-runtime"><span class="secno">2.2. </span><span class="content">Constraint: The ordinary and wide execution encodings are run-time properties</span><a class="self-link" href="#constraint-runtime"></a></h3>
   <p>The execution and wide execution encodings are not static properties of programs, and therefore not fully known at compile-time. These encodings are determined at run-time and may be dynamically changed by calls to <code class="highlight"><c- n>setlocale</c-><c- p>()</c-></code>. At compile-time, character and string literals are transcoded (in translation phase 5) from the source encoding to an encoding that is expected to be compatible with whatever encoding is selected at run-time. If the compile-time selected encoding turns out not to be compatible with the run-time encoding, then encoding confusion (mojibake) ensues.</p>
   <p>The dynamic nature of these encodings is not theoretical. On Windows, the execution encoding is determined at program startup based on the current active code page. On POSIX platforms, the run-time encoding is determined by the LANG, LC_ALL, or LC_CTYPE environment variables. Some existing programs depend on the ability to dynamically change (via POSIX <code class="highlight"><c- n>uselocale</c-><c- p>()</c-></code> or Microsoft’s <code class="highlight"><c- n>_configthreadlocale</c-><c- p>()</c-></code>) the current locale (including the execution encoding) in order for a server process to concurrently serve multiple clients with different locale settings. A recent proposal to WG14 <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2226.htm">(N2226)</a> <sup><a data-link-type="biblio" href="#biblio-wg14-n2226">[WG14-N2226]</a></sup> proposes allowing the current locale settings to vary by thread. Attempting to restrict the ability to dynamically change the execution encoding would break existing code.</p>
   <p>Since the <code class="highlight"><c- b>char16_t</c-></code> and <code class="highlight"><c- b>char32_t</c-></code> encodings are currently implementation defined, they too could vary at run-time. However, as noted earlier, all implementations currently use UTF-16 and UTF-32 and do not support such variance. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1041r1.html">P1041R1</a> <sup><a data-link-type="biblio" href="#biblio-p1041r1">[P1041R1]</a></sup> will solidify current practice and ensure these encodings are known at comple-time.</p>
   <h3 class="heading settled" data-level="2.3" id="constraint-portability"><span class="secno">2.3. </span><span class="content">Constraint: There is no portable primary execution encoding</span><a class="self-link" href="#constraint-portability"></a></h3>
   <p>On POSIX derived systems, the primary interface to the operating system is via the ordinary execution encoding. This contrasts with Windows where the primary interface is via the wide execution encoding and interfaces defined in terms of <code class="highlight"><c- b>char</c-></code> are implemented as wrappers around their wide counterparts. Unfortunately, such wrappers are often poor substitutes for use of their wide cousins due to transcoding limitations; it is common that the ordinary execution encoding is unable to represent all of the characters supported by the wide execution encoding.</p>
   <p>The designers of the C++17 filesystem library had to wrestle with this issue and addressed it via abstraction; <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>filesystem</c-><c- o>::</c-><c- n>path</c-></code> has an implementation defined value_type that reflects the primary operating system encoding. Member functions provide access to paths transcoded to any one of the five standard mandated encodings (ordinary, wide, UTF-8, <code class="highlight"><c- b>char16_t</c-></code>, and <code class="highlight"><c- b>char32_t</c-></code>). This design serves as a useful precedent for future design.</p>
   <h3 class="heading settled" data-level="2.4" id="constraint-wchar_t"><span class="secno">2.4. </span><span class="content">Constraint: <code class="highlight"><c- b>wchar_t</c-></code> is a portability deadend</span><a class="self-link" href="#constraint-wchar_t"></a></h3>
   <p>The wide execution encoding was introduced to provide relief from the constraints of the (typically 8-bit) <code class="highlight"><c- b>char</c-></code> based ordinary execution encodings by enabling a single large character set and trivial encoding that avoided the need for multibyte encoding and ISO-2022 style character set switching escape sequences. Unfortunately, the size of <code class="highlight"><c- b>wchar_t</c-></code>, the character set, and its encoding were all left as implementation defined properties resulting in significant implementation variance. The present situation is that the wide execution encoding is only widely used on Windows where its implementation is actually non-conforming <a href="https://github.com/sg16-unicode/sg16/issues/9">(see https://github.com/sg16-unicode/sg16/issues/9)</a>.</p>
   <h3 class="heading settled" data-level="2.5" id="constraint-char"><span class="secno">2.5. </span><span class="content">Constraint: <code class="highlight"><c- b>char</c-></code> aliases everything</span><a class="self-link" href="#constraint-char"></a></h3>
   <p>Pointers to <code class="highlight"><c- b>char</c-></code> may be used to inspect the underlying representation of objects of any type with the consequence that lvalues of type <code class="highlight"><c- b>char</c-></code> alias with other types. This restricts the ability of the compiler to optimize code that uses <code class="highlight"><c- b>char</c-></code>. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>byte</c-></code> was introduced in C++17 as an alternative type to use when <code class="highlight"><c- b>char</c-></code>'s aliasing abilities are desired, but it will be a long time, if ever, before we can deprecate and remove <code class="highlight"><c- b>char</c-></code>'s aliasing features.</p>
   <h3 class="heading settled" data-level="2.6" id="constraint-nih_syndrome"><span class="secno">2.6. </span><span class="content">Constraint: Implementors cannot afford to rewrite ICU</span><a class="self-link" href="#constraint-nih_syndrome"></a></h3>
   <p>ICU powers Unicode support in most portable C++ programs today due to its long history, impressive feature set, and friendly license. When considering standardizing Unicode related reatures, we must keep in mind that the Unicode standard is a large and complicated specification, and many C++ implementors simply cannot afford to reimplement what ICU provides. In practice this means that we’ll need to ensure that proposals for new Unicode features are implementable using ICU.</p>
   <h3 class="heading settled" data-level="2.7" id="constraint-filenames"><span class="secno">2.7. </span><span class="content">Constraint: File names do not have an associated character encoding</span><a class="self-link" href="#constraint-filenames"></a></h3>
   <p>In general, file names do not have an explicit associated encoding.  The POSIX <sup><a data-link-type="biblio" href="#biblio-posix">[POSIX]</a></sup> <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_170">definition of "filename"</a> is:</p>
   <div class="note" role="note"> A sequence of bytes consisting of 1 to <code class="highlight"><c- p>{</c-><c- n>NAME_MAX</c-><c- p>}</c-></code> bytes used to name a file. The bytes composing the name shall not contain the <em>&lt;NUL></em> or <em>&lt;slash></em> characters. In the context of a pathname, each filename shall be followed by a <em>&lt;slash></em> or a <em>&lt;NUL></em> character; elsewhere, a filename followed by a <em>&lt;NUL></em> character forms a string (but not necessarily a character string). The filenames <strong>dot</strong> and <strong>dot-dot</strong> have special meaning. A filename is sometimes referred to as a "pathname component". See also Pathname. </div>
   <p>and the <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_271">definition of "pathname"</a> contains the following note:</p>
   <div class="note" role="note"> If a pathname consists of only bytes corresponding to characters from the portable filename character set (see Portable Filename Character Set), <em>&lt;slash></em> characters, and a single terminating <em>&lt;NUL></em> character, the pathname will be usable as a character string in all supported locales; otherwise, the pathname might only be a string (rather than a character string). Additionally, since the single-byte encoding of the <em>&lt;slash></em> character is required to be the same across all locales and to not occur within a multi-byte character, references to a <em>&lt;slash></em> character within a pathname are well-defined even when the pathname is not a character string. However, this property does not necessarily hold for the remaining characters within the portable filename character set. </div>
   <p>It is worth emphasizing that POSIX file names constructed using only characters from the portable filename character set are <em>usable</em> in all supported locales, but do not necessarily indicate the same sequence of characters in each locale.  Thus, in general, how file names are displayed depends on locale settings.</p>
   <p>Some operating systems exhibit strong correlation between file names and a particular encoding.  However, it is important to keep in mind that file name restrictions and encoding are determined by both the file system (possibly in conjunction with file system settings and/or mount options) and the operating system, and that observed conventions do not necessarily indicate enforced requirements.  For example, file names on Windows are typically UTF-16 encoded, but NTFS does not enforce well-formed names.  The <a href="https://en.wikipedia.org/wiki/NTFS#Internals">"Internals" section of the Wikipedia entry for NTFS</a> <sup><a data-link-type="biblio" href="#biblio-wikipediantfs">[WikipediaNTFS]</a></sup> states:</p>
   <div class="note" role="note"> NTFS allows any sequence of 16-bit values for name encoding (file names, stream names, index names, etc.) except 0x0000. This means UTF-16 code units are supported, but the file system does not check whether a sequence is valid UTF-16 (it allows any sequence of short values, not restricted to those in the Unicode standard).  ... </div>
   <p>This leniency means that valid NTFS file names may contain unpaired surrogate code points and therefore might not be representable as UTF-16, nor therefore be successfully transcodeable to UTF-8.  The lack of such restrictions prompted the creation of the <a href="https://simonsapin.github.io/wtf-8">WTF-8 encoding</a> <sup><a data-link-type="biblio" href="#biblio-wtf8">[WTF8]</a></sup>.</p>
   <p>Windows also natively supports file systems that do not use "wide" file names, for example exFAT, ISO-9660, and NFS.  As with POSIX, interpretation of file names on these file systems is locale sensitive.</p>
   <p>Unlike POSIX, Windows does not guarantee that the path separator character ('\' U+005C Backslash) exists in all supported locale dependent character sets.  As a result, Windows installations configured for Japanese locales will display path separators using the ¥ (U+00A5 Yen) character.  Also unlike POSIX, Windows supports "ANSI" encodings that allow 0x5C to appear as a trailing code unit in file names which means that a simple search for the backslash character is insufficient to identify path separators in an "ANSI" encoded file name.</p>
   <p>Apple’s APFS and HFS+ filesystems require well-formed UTF-8 file names.  Additionally, they both support normalization-insensitive file names.  APFS stores normalization-preserved file names with an associated hash of the Unicode 9.0 NFD form of the name thereby enabling the file to be opened with a name that doesn’t match the original normalization.  HFS+ stores file names in Unicode 3.2 NFD form and normalizes when comparing file names.  Since the normalization forms used by these filesystems are tied to specific Unicode versions, it is possible for names normalized according to a different Unicode version to fail to match as intended.  More information can be found in the <a href="https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/APFS_Guide/FAQ/FAQ.html#//apple_ref/doc/uid/TP40016999-CH6-DontLinkElementID_3">"Frequently Asked Questions - Implementation" section of the Apple File System Guide</a> <sup><a data-link-type="biblio" href="#biblio-applefsg">[AppleFSG]</a></sup>.</p>
   <p>It is common for C++ programs to produce output that contains file names.  It is likewise commonly expected for programs or computer users to be able to extract file names from such output and to be able to open the indicated file directly using the provided name.  The requirement to represent file names accurately has profound implications for text processing.  It means that, output that is otherwise well-formed text, may be correct, but not well-formed from a text encoding perspective if it contains file names.  Likewise, if the output of a program is well-formed text, but is transformed in some way, perhaps transcoded to another encoding or Unicode normalization form, then file names within the text may be damaged.  This places limits on what an implementation can assume about the output of a program.</p>
   <h2 class="heading settled" data-level="3" id="guidelines"><span class="secno">3. </span><span class="content">Guidelines: Keep your eyes on the road, your hands upon the wheel</span><a class="self-link" href="#guidelines"></a></h2>
   <p>Mistakes happen and will continue to happen. Following a few common guidelines will help to ensure we don’t stray too far off course and help to minimize mistakes. The guidelines here are in no way specific to Unicode or text processing, but represent areas where mistakes would be easy to make.</p>
   <h3 class="heading settled" data-level="3.1" id="guideline-practices"><span class="secno">3.1. </span><span class="content">Guideline: Avoid excessive inventiveness; look for existing practice</span><a class="self-link" href="#guideline-practices"></a></h3>
   <p>C++ has some catching up to do when it comes to Unicode support. This means that there is ample opportunity to investigate and learn from features added to other languages. A great example of following this guideline is found in the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1097r1.html">P1097R1</a> <sup><a data-link-type="biblio" href="#biblio-p1097r1">[P1097R1]</a></sup> proposal to add named character escapes to character and string literals.</p>
   <h3 class="heading settled" data-level="3.2" id="guideline-inline"><span class="secno">3.2. </span><span class="content">Guideline: Avoid gratuitous departure from C</span><a class="self-link" href="#guideline-inline"></a></h3>
   <p>C and C++ continue to diverge and that is ok when there is good reason for it (e.g., to enable better type safety and overloading). However, gratuitous departure creates unnecessary interoperability and software composition challenges. Where it makes sense, proposing features that are applicable for C to WG14 will help to keep the common subset of the languages as large as it can reasonably be. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1041r1.html">P1041R1</a> <sup><a data-link-type="biblio" href="#biblio-p1041r1">[P1041R1]</a></sup> and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1097r1.html">P1097R1</a> <sup><a data-link-type="biblio" href="#biblio-p1097r1">[P1097R1]</a></sup> are great examples of features that would be appropriate to propose for inclusion in C.</p>
   <h2 class="heading settled" data-level="4" id="direction"><span class="secno">4. </span><span class="content">Direction: Designing for where we want to be and how to get there</span><a class="self-link" href="#direction"></a></h2>
   <p>Given the constraints above, how can we best integrate support for Unicode following time honored traditions of C++ design including the zero overhead principle, ensuring a transition path, and enabling software composition? How do we ensure a design that programmers will want to use? The following explores design considerations that SG16 participants have been discussing.</p>
   <p>The ordinary and wide execution encodings are not going away; they will remain the bridge that text must cross when interfacing with the operating system and with users. Unless otherwise specified, I/O performed using <code class="highlight"><c- b>char</c-></code> and <code class="highlight"><c- b>wchar_t</c-></code> based interfaces in portable programs must abide by the encodings indicated by locale settings. But internally, it is desirable to work with a limited number of encodings (preferably only one) that are known at compile time, and optimized for accordingly. This suggests a design in which transcoding is performed from dynamically determined external encodings to a statically known internal encoding at program boundaries; when reading files, standard input/output streams, command line options, environment variables, etc... This is standard practice today.  When the internal encoding is a Unicode encoding, this external/internal design is sometimes referred to as the <a href="https://nedbatchelder.com/text/unipain/unipain.html#35">Unicode sandwich</a>.</p>
   <p>There are two primary candidates for use as internal encodings today: UTF-8 and UTF-16. The former is commonly used on POSIX based platforms while the latter remains the primary system encoding on Windows. There is no encoding that is the best internal encoding for all programs, nor necessarily even for the same program on different platforms. We face a choice here: do we design for a single well known (though possibly implementation defined) internal encoding? Or do we continue the current practice of each program choosing its own internal encoding(s)? Active SG16 participants have not yet reached consensus on these questions.</p>
   <p>Use of the type system to ensure that transcoding is properly performed at program boundaries helps to prevent errors that lead to mojibake. Such errors can be subtle and only manifest in relatively rare situations, making them difficult to discover in testing. For example, failure to correctly transcode input from ISO-8859-1 to UTF-8 only results in negative symptoms when the input contains characters outside the ASCII range.</p>
   <p>This is where <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r5.html">the char8_t proposal</a> <sup><a data-link-type="biblio" href="#biblio-p0482r5">[P0482R5]</a></sup> comes in to play. Having a distinct type for UTF-8 text, like we do for UTF-16 and UTF-32, enables use of any of UTF-8, UTF-16, or UTF-32 as a statically known internal encoding, without the implementation defined signedness and aliasing concerns of <code class="highlight"><c- b>char</c-></code>, and with protection against accidental interchange with <code class="highlight"><c- b>char</c-></code> or <code class="highlight"><c- b>wchar_t</c-></code> based interfaces without proper transcoding having been performed first. Solid support in the type system, combined with statically known encodings, provides the flexibility needed to design safe and generic text handling interfaces, including ones that can support constexpr evaluation. Why might constexpr evaluation be interesting? Consider <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1040r1.html">the std::embed proposal</a> <sup><a data-link-type="biblio" href="#biblio-p1040r1">[P1040R1]</a></sup> and the ability to process a text file loaded at compile time.</p>
   <p>Distinct code unit types (<code class="highlight"><c- n>char8_t</c-></code>, <code class="highlight"><c- b>char16_t</c-></code>, <code class="highlight"><c- b>char32_t</c-></code>) enable statically known internal encodings, but not without some cost. Existing code that works with UTF-8 today is written using <code class="highlight"><c- b>char</c-></code>, <code class="highlight"><c- b>unsigned</c-> <c- b>char</c-></code>, or <code class="highlight"><c- b>uint8_t</c-></code>. Likewise, existing code that works with UTF-16 today is written using <code class="highlight"><c- b>char16_t</c-></code>, <code class="highlight"><c- b>wchar_t</c-></code>, <code class="highlight"><c- b>unsigned</c-> <c- b>short</c-></code>, or <code class="highlight"><c- b>uint16_t</c-></code>. ICU supports customization of its internal code unit type, but <code class="highlight"><c- b>char16_t</c-></code> is used by default, following ICU’s adoption of C++11. Prior to the switch to C++11, the default varied by platform. The switch to <code class="highlight"><c- b>char16_t</c-></code> created friction with existing code by, for example, requiring that ICU data passed to Windows <code class="highlight"><c- b>wchar_t</c-></code> interfaces be copied or <code class="highlight"><c- k>reinterpret_cast</c-></code>. Similar friction will occur with <code class="highlight"><c- n>char8_t</c-></code>. ICU dealt with this by providing interfaces that, for at least some cases, encapsulate uses of <code class="highlight"><c- k>reinterpret_cast</c-></code> and handling of the resulting aliasing issues.</p>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>basic_string</c-></code> isn’t a great foundation for working with Unicode text due to its operations all working at the code unit level as opposed to code point or grapheme cluster levels. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0244r2.html">The text_view proposal</a> <sup><a data-link-type="biblio" href="#biblio-p0244r2">[P0244R2]</a></sup> provides a method for layering encoding aware code point support on top of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>basic_string</c-></code> or any other string like type that provides a range of code units. SG16 has been discussing the addition of a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>text</c-></code> family of types that provide similar capabilities, but that also own the underlying data. Zach Laine has been prototyping such a type in his <a href="https://tzlaine.github.io/text/doc/html/index.html">Boost.Text library</a>.</p>
   <p>Introducing new types that potentially compete with <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string_view</c-></code> creates a possible problem for software composition. How do components that traffic in <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code> vs <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>text</c-></code> interact? Discussions in SG16 have identified several strategies for dealing with this:</p>
   <ol>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>text</c-></code> could be convertible to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string_view</c-></code> and, potentially, <code class="highlight"><c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- o>&amp;</c-></code> if it holds an actual <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code> object, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>text</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code> could allow their buffers to be transferred back and forth (and potentially to other string types).</p>
   </ol>
   <p>New text containers and views help to address support for UTF encoding and decoding, but Unicode provides far more than a large character set and methods for encoding it. Unicode algorithms provide support for enumerating grapheme clusters, word breaks, line breaks, performing language sensitive collation, handling bidirectional text, case mapping, and more. Exposing interfaces for these algorithms is necessary to claim complete Unicode support. Exposing these in a generic form that allows their use with the large number of string types used in practice is necessary to enable their adoption. Enabling them to be used with segmented data types (e.g., ropes) is a desirable feature.</p>
   <h2 class="heading settled" data-level="5" id="directives"><span class="secno">5. </span><span class="content">Directives: Do or do not, there is no try</span><a class="self-link" href="#directives"></a></h2>
   <p>Per the general design discussion above, the following directives identify activities for SG16 to focus on. Papers exploring and proposing features within their scope are encouraged.</p>
   <h3 class="heading settled" data-level="5.1" id="directive-encoding_aware"><span class="secno">5.1. </span><span class="content">Directive: Standardize new encoding aware text container and view types</span><a class="self-link" href="#directive-encoding_aware"></a></h3>
   <p>This is the topic that SG16 participants have so far spent the most time discussing, but we do not yet have papers that explore or propose particular designs.</p>
   <p>We have general consensus on the following design directions:</p>
   <ul>
    <li data-md>
     <p>A new <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>text</c-></code> type that is an owning string type with a statically known character encoding.</p>
    <li data-md>
     <p>A new <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>text_view</c-></code> type that is a non-owning string type with a statically known character encoding.</p>
    <li data-md>
     <p>These types will not have the large interface exposed by std::string.</p>
    <li data-md>
     <p>These types will encourage processing of code points and grapheme clusters while permitting efficient access to code units.</p>
   </ul>
   <p>Discussion continues for questions such as:</p>
   <ul>
    <li data-md>
     <p>Should these types be ranges and, if so, should their value_type reflect code points or extended grapheme clusters? Or, should these types provide access to distinct ranges (e.g., via <code class="highlight"><c- n>as_code_points</c-><c- p>()</c-></code> and <code class="highlight"><c- n>as_graphemes</c-><c- p>()</c-></code> member functions) that require the programmer to explicitly choose a level of abstraction to work at?</p>
    <li data-md>
     <p>Can these types satsify the complexity requirements for ranges? Ranges require O(1) for calls to <code class="highlight"><c- n>begin</c-><c- p>()</c-></code> and <code class="highlight"><c- n>end</c-><c- p>()</c-></code>, but iteration by code point or grapheme cluster may consume an arbitrary number of code units due to ill-formed code unit sequences or arbitrary numbers of combining code points.</p>
    <li data-md>
     <p>Should these types be comparable via standard operators? If so, should comparison be lexicographical (fast, but surprising if text is not normalized) or be based on canonical equivalence (slower, but consistent results regardless of normalization)? Should a specialization of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>less</c-></code> be provided that performs a fast comparison suitable for storing these types in containers?</p>
    <li data-md>
     <p>Should these types enforce well-formed encoded text? Should validation be performed on each mutation? How should errors be handled?</p>
    <li data-md>
     <p>Should these types support a single fixed encoding (UTF-8)? Or should multiple encodings be supported as proposed in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0244r2.html">the text_view proposal</a> <sup><a data-link-type="biblio" href="#biblio-p0244r2">[P0244R2]</a></sup>?</p>
    <li data-md>
     <p>Should these types enforce a normalization form on UTF encoded text?</p>
    <li data-md>
     <p>Should these types include allocator support?</p>
    <li data-md>
     <p>Should these types replace use of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string_view</c-></code> in most text/string processing code?</p>
   </ul>
   <p>There is much existing practice to consider here. Historically, most string classes have either provided code unit access (like <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code> or code point access (possibly with means for code unit access as well). Swift took the bold move of making extended grapheme clusters the basic element of Swift strings. There are many design options and tradeoffs to consider. Papers exploring the design options are strongly encouraged.</p>
   <h3 class="heading settled" data-level="5.2" id="directive-generic_algorithms"><span class="secno">5.2. </span><span class="content">Directive: Standardize generic interfaces for Unicode algorithms</span><a class="self-link" href="#directive-generic_algorithms"></a></h3>
   <p>SG16 participants have not yet spent much time discussing interfaces to Unicode algorithms, though Zach Laine has blazed a trail by implementing support for all of them in his <a href="https://tzlaine.github.io/text/doc/html/index.html">Boost.Text library</a>. Papers exploring requirements would be helpful here. Some questions to explore:</p>
   <ul>
    <li data-md>
     <p>Is it reasonable for these interfaces to be range based over code points? Or are contiguous iterators and ranges over code units needed to achieve acceptable performance?</p>
    <li data-md>
     <p>Can these interfaces accommodate segmented data structures such as ropes?</p>
    <li data-md>
     <p>Many Unicode algorithms require additional context such as the language of the text (Russian, German, etc...). How should this information be supplied? The existing facilities exposed via <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>locale</c-></code> are more oriented towards abstracting operations than providing this type of information.</p>
   </ul>
   <h3 class="heading settled" data-level="5.3" id="directives-other_useful"><span class="secno">5.3. </span><span class="content">Directive: Standarize useful features from other languages</span><a class="self-link" href="#directives-other_useful"></a></h3>
   <p>We’ve got a start on this with <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1097r1.html">Named Character Escapes</a> <sup><a data-link-type="biblio" href="#biblio-p1097r1">[P1097R1]</a></sup>, but there are no doubt many text handling features in other languages that would be desirable in C++. Papers welcome.</p>
   <h3 class="heading settled" data-level="5.4" id="directive-transcoding"><span class="secno">5.4. </span><span class="content">Directive: Improve support for transcoding at program boundaries</span><a class="self-link" href="#directive-transcoding"></a></h3>
   <p>C++ currently includes interfaces for transcoding between the ordinary and wide execution encodings and between the UTF-8, UTF-16, and UTF-32 encodings, but not between these two sets of encodings. This poses a challenge for support of the external/internal encoding model.</p>
   <p>Portably handling command line arguments (that may include file names that are not well formed for the current locale encoding) and environment variables (likewise) accurately can be challenging. The design employed for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>filesystem</c-><c- o>::</c-><c- n>path</c-></code> to provide access to native data as well as access to that data transcoded to various encodings could be applied to solve portability issues with command line arguments and environment variables.</p>
   <p>An open question is whether transcoding between external and internal encodings should be performed implicitly (convenient, but hidden costs) or explicitly (less convenient, but with apparent costs).</p>
   <h3 class="heading settled" data-level="5.5" id="directive-wording"><span class="secno">5.5. </span><span class="content">Directive: Propose resolutions for existing issues and wording improvements opportunistically</span><a class="self-link" href="#directive-wording"></a></h3>
   <p>While not an SG16 priority, it will sometimes be necessary to resolve existing issues or improve wording to accommodate new features. Issues that pertain to SG16 are currently tracked in our github repo at <a href="https://github.com/sg16-unicode/sg16/issues">https://github.com/sg16-unicode/sg16/issues</a>.</p>
   <h2 class="heading settled" data-level="6" id="non-directives"><span class="secno">6. </span><span class="content">Non-directives: Thanks, but No Thanks</span><a class="self-link" href="#non-directives"></a></h2>
   <p>The C++ standard currently lacks the necessary foundations for obtaining or displaying Unicode text through human interface devices. Until that changes, addressing user input and graphical rendering of text will remain out of scope for SG16.</p>
   <h3 class="heading settled" data-level="6.1" id="non-directive-ui"><span class="secno">6.1. </span><span class="content">Non-directive: User input</span><a class="self-link" href="#non-directive-ui"></a></h3>
   <p>Keyboard scan codes, key mapping, and methods of character composition entry are all fantastically interesting subjects, but require lower level device access than are currently provided by standard C++.  SG16’s scope begins at the point where text is presented in memory as an encoded sequence of "characters".</p>
   <h3 class="heading settled" data-level="6.2" id="non-directive-graphics"><span class="secno">6.2. </span><span class="content">Non-directive: Fonts, graphical text rendering</span><a class="self-link" href="#non-directive-graphics"></a></h3>
   <p>What Unicode provides and what fonts and graphical text rendering facilities need are two related but distinct problems.  SG16’s scope ends at the point where text is handed off to code capable of interacting with output devices like screens, speech readers, and brail terminals.</p>
   <h2 class="heading settled" data-level="7" id="acknowledgements"><span class="secno">7. </span><span class="content">Acknowledgements</span><a class="self-link" href="#acknowledgements"></a></h2>
   <p>SG16 would not exist if not for early and kind encouragement by Beman Dawes.</p>
   <p>Thank you to all 18 individuals who have attended at least one SG16 teleconference and have thereby contributed to the discussions shaping our future direction.</p>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

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

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

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

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

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

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


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

    tocNav.appendChild(toggle);
  }

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

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

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

})();
</script>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-applefsg">[AppleFSG]
   <dd>Apple Inc. <a href="https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/APFS_Guide/Introduction/Introduction.html">Apple File System Guide</a>. 2018. URL: <a href="https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/APFS_Guide/Introduction/Introduction.html">https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/APFS_Guide/Introduction/Introduction.html</a>
   <dt id="biblio-clangonz">[ClangOnZ]
   <dd>Geoff Wozniak. <a href="https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20170508/004572.html">[swift-dev] z/OS, Swift, and encodings</a>. 2017. URL: <a href="https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20170508/004572.html">https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20170508/004572.html</a>
   <dt id="biblio-p0244r2">[P0244R2]
   <dd>Tom Honermann. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0244r2.html">text_view: A C++ Concepts and Range based Character Encoding and Code Point Enumeration Library</a>. 2017. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0244r2.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0244r2.html</a>
   <dt id="biblio-p0482r5">[P0482R5]
   <dd>Tom Honermann. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r5.html">char8_t: A type for UTF-8 characters and strings (Revision 5)</a>. 2018. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r5.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r5.html</a>
   <dt id="biblio-p1025r1">[P1025R1]
   <dd>Steve Downey, et al.. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1025r1.html">Update The Reference To The Unicode Standard</a>. 2018. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1025r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1025r1.html</a>
   <dt id="biblio-p1040r1">[P1040R1]
   <dd>JeanHeyd Meneide. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1040r1.html">std::embed</a>. 2018. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1040r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1040r1.html</a>
   <dt id="biblio-p1041r1">[P1041R1]
   <dd>Martinho Fernandes. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1041r1.html">Make char16_t/char32_t String Literals be UTF-16/32</a>. 2018. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1041r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1041r1.html</a>
   <dt id="biblio-p1072r0">[P1072R0]
   <dd>Chris Kennelly; Mark Zeren. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1072r0.html">Default Initialization for basic_string</a>. 2018. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1072r0.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1072r0.html</a>
   <dt id="biblio-p1097r1">[P1097R1]
   <dd>Martinho Fernandes. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1097r1.html">Named Character Escapes</a>. 2018. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1097r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1097r1.html</a>
   <dt id="biblio-p1238r0">[P1238R0]
   <dd>Tom Honermann, et al.. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1238r0.html">SG16: Unicode Direction</a>. 2018. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1238r0.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1238r0.html</a>
   <dt id="biblio-posix">[POSIX]
   <dd>IEEE and The Open Group. <a href="http://pubs.opengroup.org/onlinepubs/9699919799/">The Open Group Base Specifications Issue 7, 2018 edition, IEEE Std 1003.1-2017</a>. 2018. URL: <a href="http://pubs.opengroup.org/onlinepubs/9699919799/">http://pubs.opengroup.org/onlinepubs/9699919799/</a>
   <dt id="biblio-swiftonz">[SwiftOnZ]
   <dd>IBM. <a href="https://developer.ibm.com/mainframe/products/ibm-toolkit-swift-z-os">IBM Toolkit for Swift on z/OS</a>. 2017. URL: <a href="https://developer.ibm.com/mainframe/products/ibm-toolkit-swift-z-os">https://developer.ibm.com/mainframe/products/ibm-toolkit-swift-z-os</a>
   <dt id="biblio-w3techs">[W3Techs]
   <dd>W3Techs. <a href="https://w3techs.com/technologies/details/en-utf8/all/all">Usage of UTF-8 for websites</a>. 2017. URL: <a href="https://w3techs.com/technologies/details/en-utf8/all/all">https://w3techs.com/technologies/details/en-utf8/all/all</a>
   <dt id="biblio-wg14-n2226">[WG14-N2226]
   <dd>Florian Weimer. <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2226.htm">Optional thread storage duration for the program's locale</a>. 2018. URL: <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2226.htm">http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2226.htm</a>
   <dt id="biblio-wikipediantfs">[WikipediaNTFS]
   <dd><a href="https://en.wikipedia.org/wiki/NTFS">NTFS</a>. 2019. URL: <a href="https://en.wikipedia.org/wiki/NTFS">https://en.wikipedia.org/wiki/NTFS</a>
   <dt id="biblio-wtf8">[WTF8]
   <dd>Simon Sapin. <a href="https://simonsapin.github.io/wtf-8/">The WTF-8 encoding</a>. 2018. URL: <a href="https://simonsapin.github.io/wtf-8/">https://simonsapin.github.io/wtf-8/</a>
  </dl>