// Written in the D programming language.

/++
    Encode and decode UTF-8, UTF-16 and UTF-32 strings.

    UTF character support is restricted to
    $(D '\u0000' &lt;= character &lt;= '\U0010FFFF').

$(SCRIPT inhibitQuickIndex = 1;)
$(DIVC quickindex,
$(BOOKTABLE,
$(TR $(TH Category) $(TH Functions))
$(TR $(TD Decode) $(TD
    $(LREF decode)
    $(LREF decodeFront)
))
$(TR $(TD Lazy decode) $(TD
    $(LREF byCodeUnit)
    $(LREF byChar)
    $(LREF byWchar)
    $(LREF byDchar)
    $(LREF byUTF)
))
$(TR $(TD Encode) $(TD
    $(LREF encode)
    $(LREF toUTF8)
    $(LREF toUTF16)
    $(LREF toUTF32)
    $(LREF toUTFz)
    $(LREF toUTF16z)
))
$(TR $(TD Length) $(TD
    $(LREF codeLength)
    $(LREF count)
    $(LREF stride)
    $(LREF strideBack)
))
$(TR $(TD Index) $(TD
    $(LREF toUCSindex)
    $(LREF toUTFindex)
))
$(TR $(TD Validation) $(TD
    $(LREF isValidDchar)
    $(LREF isValidCodepoint)
    $(LREF validate)
))
$(TR $(TD Miscellaneous) $(TD
    $(LREF replacementDchar)
    $(LREF UseReplacementDchar)
    $(LREF UTFException)
))
))
    See_Also:
        $(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia)<br>
        $(LINK http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8)<br>
        $(LINK https://web.archive.org/web/20100113043530/https://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335)
    Copyright: Copyright The D Language Foundation 2000 - 2012.
    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
    Authors:   $(HTTP digitalmars.com, Walter Bright) and
               $(HTTP jmdavisprog.com, Jonathan M Davis)
    Source:    $(PHOBOSSRC std/utf.d)
   +/
module std.utf;

import std.exception : basicExceptionCtors;
import core.exception : UnicodeException;
import std.meta : AliasSeq;
import std.range;
import std.traits : isAutodecodableString, isConvertibleToString,
    isSomeChar, isSomeString, isStaticArray, Unqual;
import std.typecons : Flag, Yes, No;


/++
    Exception thrown on errors in std.utf functions.
  +/
class UTFException : UnicodeException
{
    import core.internal.string : unsignedToTempString, UnsignedStringBuf;

    uint[4] sequence;
    size_t  len;

    @safe pure nothrow @nogc
    UTFException setSequence(scope uint[] data...) return
    {
        assert(data.length <= 4);

        len = data.length < 4 ? data.length : 4;
        sequence[0 .. len] = data[0 .. len];

        return this;
    }

    // FIXME: Use std.exception.basicExceptionCtors here once
    // https://issues.dlang.org/show_bug.cgi?id=11500 is fixed

    /**
    Standard exception constructors.
     */
    this(string msg, string file = __FILE__, size_t line = __LINE__,
         Throwable next = null) @nogc @safe pure nothrow
    {
        super(msg, 0, file, line, next);
    }
    /// ditto
    this(string msg, size_t index, string file = __FILE__,
         size_t line = __LINE__, Throwable next = null) @safe pure nothrow
    {
        UnsignedStringBuf buf = void;
        msg ~= " (at index " ~ unsignedToTempString(index, buf) ~ ")";
        super(msg, index, file, line, next);
    }

    /**
    Returns:
        A `string` detailing the invalid UTF sequence.
     */
    override string toString() const
    {
        if (len == 0)
        {
            /* Exception.toString() is not marked as const, although
             * it is const-compatible.
             */
            //return super.toString();
            auto e = () @trusted { return cast(Exception) super; } ();
            return e.toString();
        }

        string result = "Invalid UTF sequence:";

        foreach (i; sequence[0 .. len])
        {
            UnsignedStringBuf buf = void;
            result ~= ' ';
            auto h = unsignedToTempString!16(i, buf);
            if (h.length == 1)
                result ~= '0';
            result ~= h;
            result ~= 'x';
        }

        if (super.msg.length > 0)
        {
            result ~= " - ";
            result ~= super.msg;
        }

        return result;
    }
}

///
@safe unittest
{
    import std.exception : assertThrown;

    char[4] buf;
    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));
}

/*
   Provide array of invalidly encoded UTF strings. Useful for testing.

   Params:
        Char = char, wchar, or dchar

   Returns:
        an array of invalidly encoded UTF strings
 */

package auto invalidUTFstrings(Char)() @safe pure @nogc nothrow
if (isSomeChar!Char)
{
    static if (is(Char == char))
    {
        enum x = 0xDC00;         // invalid surrogate value
        enum y = 0x110000;       // out of range

        static immutable string[8] result =
        [
            "\x80",             // not a start byte
            "\xC0",             // truncated
            "\xC0\xC0",         // invalid continuation
            "\xF0\x82\x82\xAC", // overlong
            [
              0xE0 | (x >> 12),
              0x80 | ((x >> 6) & 0x3F),
              0x80 | (x & 0x3F)
            ],
            [
              cast(char)(0xF0 | (y >> 18)),
              cast(char)(0x80 | ((y >> 12) & 0x3F)),
              cast(char)(0x80 | ((y >> 6) & 0x3F)),
              cast(char)(0x80 | (y & 0x3F))
            ],
            [
              cast(char)(0xF8 | 3),     // 5 byte encoding
              cast(char)(0x80 | 3),
              cast(char)(0x80 | 3),
              cast(char)(0x80 | 3),
              cast(char)(0x80 | 3),
            ],
            [
              cast(char)(0xFC | 3),     // 6 byte encoding
              cast(char)(0x80 | 3),
              cast(char)(0x80 | 3),
              cast(char)(0x80 | 3),
              cast(char)(0x80 | 3),
              cast(char)(0x80 | 3),
            ],
        ];

        return result[];
    }
    else static if (is(Char == wchar))
    {
        static immutable wstring[5] result =
        [
            [
              cast(wchar) 0xDC00,
            ],
            [
              cast(wchar) 0xDFFF,
            ],
            [
              cast(wchar) 0xDBFF,
              cast(wchar) 0xDBFF,
            ],
            [
              cast(wchar) 0xDBFF,
              cast(wchar) 0xE000,
            ],
            [
              cast(wchar) 0xD800,
            ],
        ];

        return result[];
    }
    else static if (is(Char == dchar))
    {
        static immutable dstring[3] result =
        [
            [ cast(dchar) 0x110000 ],
            [ cast(dchar) 0x00D800 ],
            [ cast(dchar) 0x00DFFF ],
        ];

        return result;
    }
    else
        static assert(0);
}

/++
    Check whether the given Unicode code point is valid.

    Params:
        c = code point to check

    Returns:
        `true` if and only if `c` is a valid Unicode code point

    Note:
    `'\uFFFE'` and `'\uFFFF'` are considered valid by `isValidDchar`,
    as they are permitted for internal use by an application, but they are
    not allowed for interchange by the Unicode standard.
  +/
bool isValidDchar(dchar c) pure nothrow @safe @nogc
{
    return c < 0xD800 || (c > 0xDFFF && c <= 0x10FFFF);
}

///
@safe @nogc pure nothrow unittest
{
    assert( isValidDchar(cast(dchar) 0x41));
    assert( isValidDchar(cast(dchar) 0x00));
    assert(!isValidDchar(cast(dchar) 0xD800));
    assert(!isValidDchar(cast(dchar) 0x11FFFF));
}

pure nothrow @safe @nogc unittest
{
    import std.exception;

    assertCTFEable!(
    {
    assert( isValidDchar(cast(dchar)'a') == true);
    assert( isValidDchar(cast(dchar) 0x1FFFFF) == false);

    assert(!isValidDchar(cast(dchar) 0x00D800));
    assert(!isValidDchar(cast(dchar) 0x00DBFF));
    assert(!isValidDchar(cast(dchar) 0x00DC00));
    assert(!isValidDchar(cast(dchar) 0x00DFFF));
    assert( isValidDchar(cast(dchar) 0x00FFFE));
    assert( isValidDchar(cast(dchar) 0x00FFFF));
    assert( isValidDchar(cast(dchar) 0x01FFFF));
    assert( isValidDchar(cast(dchar) 0x10FFFF));
    assert(!isValidDchar(cast(dchar) 0x110000));
    });
}

/**
Checks if a single character forms a valid code point.

When standing alone, some characters are invalid code points. For
example the `wchar` `0xD800` is a so called high surrogate, which can
only be interpreted together with a low surrogate following it. As a
standalone character it is considered invalid.

See $(LINK2 http://www.unicode.org/versions/Unicode13.0.0/,
Unicode Standard, D90, D91 and D92) for more details.

Params:
    c = character to test
    Char = character type of `c`

Returns:
    `true`, if `c` forms a valid code point.
 */
bool isValidCodepoint(Char)(Char c)
if (isSomeChar!Char)
{
    alias UChar = typeof(cast() c);
    static if (is(UChar == char))
    {
        return c <= 0x7F;
    }
    else static if (is(UChar == wchar))
    {
        return c <= 0xD7FF || c >= 0xE000;
    }
    else static if (is(UChar == dchar))
    {
        return isValidDchar(c);
    }
    else
        static assert(false, "unknown character type: `" ~ Char.stringof ~ "`");
}

///
@safe pure nothrow unittest
{
    assert( isValidCodepoint(cast(char) 0x40));
    assert(!isValidCodepoint(cast(char) 0x80));
    assert( isValidCodepoint(cast(wchar) 0x1234));
    assert(!isValidCodepoint(cast(wchar) 0xD800));
    assert( isValidCodepoint(cast(dchar) 0x0010FFFF));
    assert(!isValidCodepoint(cast(dchar) 0x12345678));
}

/++
    Calculate the length of the UTF sequence starting at `index`
    in `str`.

    Params:
        str = $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
        of UTF code units. Must be random access if `index` is passed
        index = starting index of UTF sequence (default: `0`)

    Returns:
        The number of code units in the UTF sequence. For UTF-8, this is a
        value between 1 and 4 (as per $(HTTP tools.ietf.org/html/rfc3629#section-3, RFC 3629$(COMMA) section 3)).
        For UTF-16, it is either 1 or 2. For UTF-32, it is always 1.

    Throws:
        May throw a `UTFException` if `str[index]` is not the start of a
        valid UTF sequence.

    Note:
        `stride` will only analyze the first `str[index]` element. It
        will not fully verify the validity of the UTF sequence, nor even verify
        the presence of the sequence: it will not actually guarantee that
        $(D index + stride(str, index) <= str.length).
  +/
uint stride(S)(auto ref S str, size_t index)
if (is(S : const char[]) ||
    (isRandomAccessRange!S && is(immutable ElementType!S == immutable char)))
{
    static if (is(typeof(str.length) : ulong))
        assert(index < str.length, "Past the end of the UTF-8 sequence");
    immutable c = str[index];

    if (c < 0x80)
        return 1;
    else
        return strideImpl(c, index);
}

/// Ditto
uint stride(S)(auto ref S str)
if (is(S : const char[]) ||
    (isInputRange!S && is(immutable ElementType!S == immutable char)))
{
    static if (is(S : const char[]))
        immutable c = str[0];
    else
        immutable c = str.front;

    if (c < 0x80)
        return 1;
    else
        return strideImpl(c, 0);
}

@system unittest
{
    import core.exception : AssertError;
    import std.conv : to;
    import std.exception;
    import std.string : format;
    import std.traits : FunctionAttribute, functionAttributes, isSafe;
    static void test(string s, dchar c, size_t i = 0, size_t line = __LINE__)
    {
        enforce(stride(s, i) == codeLength!char(c),
                new AssertError(format("Unit test failure string: %s", s), __FILE__, line));

        enforce(stride(RandomCU!char(s), i) == codeLength!char(c),
                new AssertError(format("Unit test failure range: %s", s), __FILE__, line));

        auto refRandom = new RefRandomCU!char(s);
        immutable randLen = refRandom.length;
        enforce(stride(refRandom, i) == codeLength!char(c),
                new AssertError(format("Unit test failure rand ref range: %s", s), __FILE__, line));
        enforce(refRandom.length == randLen,
                new AssertError(format("Unit test failure rand ref range length: %s", s), __FILE__, line));

        if (i == 0)
        {
            enforce(stride(s) == codeLength!char(c),
                    new AssertError(format("Unit test failure string 0: %s", s), __FILE__, line));

            enforce(stride(InputCU!char(s)) == codeLength!char(c),
                    new AssertError(format("Unit test failure range 0: %s", s), __FILE__, line));

            auto refBidir = new RefBidirCU!char(s);
            immutable bidirLen = refBidir.length;
            enforce(stride(refBidir) == codeLength!char(c),
                    new AssertError(format("Unit test failure bidir ref range code length: %s", s), __FILE__, line));
            enforce(refBidir.length == bidirLen,
                    new AssertError(format("Unit test failure bidir ref range length: %s", s), __FILE__, line));
        }
    }

    assertCTFEable!(
    {
    test("a", 'a');
    test(" ", ' ');
    test("\u2029", '\u2029'); //paraSep
    test("\u0100", '\u0100');
    test("\u0430", '\u0430');
    test("\U00010143", '\U00010143');
    test("abcdefcdef", 'a');
    test("hello\U00010143\u0100\U00010143", 'h', 0);
    test("hello\U00010143\u0100\U00010143", 'e', 1);
    test("hello\U00010143\u0100\U00010143", 'l', 2);
    test("hello\U00010143\u0100\U00010143", 'l', 3);
    test("hello\U00010143\u0100\U00010143", 'o', 4);
    test("hello\U00010143\u0100\U00010143", '\U00010143', 5);
    test("hello\U00010143\u0100\U00010143", '\u0100', 9);
    test("hello\U00010143\u0100\U00010143", '\U00010143', 11);

    foreach (S; AliasSeq!(char[], const char[], string))
    {
        enum str = to!S("hello world");
        static assert(isSafe!({ stride(str, 0); }));
        static assert(isSafe!({ stride(str);    }));
        static assert((functionAttributes!({ stride(str, 0); }) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!({ stride(str);    }) & FunctionAttribute.pure_) != 0);
    }
    });
}

@safe unittest // invalid start bytes
{
    import std.exception : assertThrown;
    immutable char[] invalidStartBytes = [
        0b1111_1000, // indicating a sequence length of 5
        0b1111_1100, // 6
        0b1111_1110, // 7
        0b1111_1111, // 8
        0b1000_0000, // continuation byte
    ];
    foreach (c; invalidStartBytes)
        assertThrown!UTFException(stride([c]));
}

/// Ditto
uint stride(S)(auto ref S str, size_t index)
if (is(S : const wchar[]) ||
    (isRandomAccessRange!S && is(immutable ElementType!S == immutable wchar)))
{
    static if (is(typeof(str.length) : ulong))
        assert(index < str.length, "Past the end of the UTF-16 sequence");
    immutable uint u = str[index];
    return 1 + (u >= 0xD800 && u <= 0xDBFF);
}

/// Ditto
uint stride(S)(auto ref S str) @safe pure
if (is(S : const wchar[]))
{
    return stride(str, 0);
}

/// Ditto
uint stride(S)(auto ref S str)
if (isInputRange!S && is(immutable ElementType!S == immutable wchar) &&
    !is(S : const wchar[]))
{
    assert(!str.empty, "UTF-16 sequence is empty");
    immutable uint u = str.front;
    return 1 + (u >= 0xD800 && u <= 0xDBFF);
}

@system unittest
{
    import core.exception : AssertError;
    import std.conv : to;
    import std.exception;
    import std.string : format;
    import std.traits : FunctionAttribute, functionAttributes, isSafe;
    static void test(wstring s, dchar c, size_t i = 0, size_t line = __LINE__)
    {
        enforce(stride(s, i) == codeLength!wchar(c),
                new AssertError(format("Unit test failure string: %s", s), __FILE__, line));

        enforce(stride(RandomCU!wchar(s), i) == codeLength!wchar(c),
                new AssertError(format("Unit test failure range: %s", s), __FILE__, line));

        auto refRandom = new RefRandomCU!wchar(s);
        immutable randLen = refRandom.length;
        enforce(stride(refRandom, i) == codeLength!wchar(c),
                new AssertError(format("Unit test failure rand ref range: %s", s), __FILE__, line));
        enforce(refRandom.length == randLen,
                new AssertError(format("Unit test failure rand ref range length: %s", s), __FILE__, line));

        if (i == 0)
        {
            enforce(stride(s) == codeLength!wchar(c),
                    new AssertError(format("Unit test failure string 0: %s", s), __FILE__, line));

            enforce(stride(InputCU!wchar(s)) == codeLength!wchar(c),
                    new AssertError(format("Unit test failure range 0: %s", s), __FILE__, line));

            auto refBidir = new RefBidirCU!wchar(s);
            immutable bidirLen = refBidir.length;
            enforce(stride(refBidir) == codeLength!wchar(c),
                    new AssertError(format("Unit test failure bidir ref range code length: %s", s), __FILE__, line));
            enforce(refBidir.length == bidirLen,
                    new AssertError(format("Unit test failure bidir ref range length: %s", s), __FILE__, line));
        }
    }

    assertCTFEable!(
    {
    test("a", 'a');
    test(" ", ' ');
    test("\u2029", '\u2029'); //paraSep
    test("\u0100", '\u0100');
    test("\u0430", '\u0430');
    test("\U00010143", '\U00010143');
    test("abcdefcdef", 'a');
    test("hello\U00010143\u0100\U00010143", 'h', 0);
    test("hello\U00010143\u0100\U00010143", 'e', 1);
    test("hello\U00010143\u0100\U00010143", 'l', 2);
    test("hello\U00010143\u0100\U00010143", 'l', 3);
    test("hello\U00010143\u0100\U00010143", 'o', 4);
    test("hello\U00010143\u0100\U00010143", '\U00010143', 5);
    test("hello\U00010143\u0100\U00010143", '\u0100', 7);
    test("hello\U00010143\u0100\U00010143", '\U00010143', 8);

    foreach (S; AliasSeq!(wchar[], const wchar[], wstring))
    {
        enum str = to!S("hello world");
        static assert(isSafe!(() => stride(str, 0)));
        static assert(isSafe!(() => stride(str)   ));
        static assert((functionAttributes!(() => stride(str, 0)) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!(() => stride(str)   ) & FunctionAttribute.pure_) != 0);
    }
    });
}

/// Ditto
uint stride(S)(auto ref S str, size_t index = 0)
if (is(S : const dchar[]) ||
    (isInputRange!S && is(immutable ElementEncodingType!S == immutable dchar)))
{
    static if (is(typeof(str.length) : ulong))
        assert(index < str.length, "Past the end of the UTF-32 sequence");
    else
        assert(!str.empty, "UTF-32 sequence is empty.");
    return 1;
}

///
@safe unittest
{
    assert("a".stride == 1);
    assert("λ".stride == 2);
    assert("aλ".stride == 1);
    assert("aλ".stride(1) == 2);
    assert("𐐷".stride == 4);
}

@system unittest
{
    import core.exception : AssertError;
    import std.conv : to;
    import std.exception;
    import std.string : format;
    import std.traits : FunctionAttribute, functionAttributes, isSafe;
    static void test(dstring s, dchar c, size_t i = 0, size_t line = __LINE__)
    {
        enforce(stride(s, i) == codeLength!dchar(c),
                new AssertError(format("Unit test failure string: %s", s), __FILE__, line));

        enforce(stride(RandomCU!dchar(s), i) == codeLength!dchar(c),
                new AssertError(format("Unit test failure range: %s", s), __FILE__, line));

        auto refRandom = new RefRandomCU!dchar(s);
        immutable randLen = refRandom.length;
        enforce(stride(refRandom, i) == codeLength!dchar(c),
                new AssertError(format("Unit test failure rand ref range: %s", s), __FILE__, line));
        enforce(refRandom.length == randLen,
                new AssertError(format("Unit test failure rand ref range length: %s", s), __FILE__, line));

        if (i == 0)
        {
            enforce(stride(s) == codeLength!dchar(c),
                    new AssertError(format("Unit test failure string 0: %s", s), __FILE__, line));

            enforce(stride(InputCU!dchar(s)) == codeLength!dchar(c),
                    new AssertError(format("Unit test failure range 0: %s", s), __FILE__, line));

            auto refBidir = new RefBidirCU!dchar(s);
            immutable bidirLen = refBidir.length;
            enforce(stride(refBidir) == codeLength!dchar(c),
                    new AssertError(format("Unit test failure bidir ref range code length: %s", s), __FILE__, line));
            enforce(refBidir.length == bidirLen,
                    new AssertError(format("Unit test failure bidir ref range length: %s", s), __FILE__, line));
        }
    }

    assertCTFEable!(
    {
    test("a", 'a');
    test(" ", ' ');
    test("\u2029", '\u2029'); //paraSep
    test("\u0100", '\u0100');
    test("\u0430", '\u0430');
    test("\U00010143", '\U00010143');
    test("abcdefcdef", 'a');
    test("hello\U00010143\u0100\U00010143", 'h', 0);
    test("hello\U00010143\u0100\U00010143", 'e', 1);
    test("hello\U00010143\u0100\U00010143", 'l', 2);
    test("hello\U00010143\u0100\U00010143", 'l', 3);
    test("hello\U00010143\u0100\U00010143", 'o', 4);
    test("hello\U00010143\u0100\U00010143", '\U00010143', 5);
    test("hello\U00010143\u0100\U00010143", '\u0100', 6);
    test("hello\U00010143\u0100\U00010143", '\U00010143', 7);

    foreach (S; AliasSeq!(dchar[], const dchar[], dstring))
    {
        enum str = to!S("hello world");
        static assert(isSafe!(() => stride(str, 0)));
        static assert(isSafe!(() => stride(str)   ));
        static assert((functionAttributes!(() => stride(str, 0)) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!(() => stride(str)   ) & FunctionAttribute.pure_) != 0);
    }
    });
}

private uint strideImpl(char c, size_t index) @trusted pure
in { assert(c & 0x80); }
do
{
    import core.bitop : bsr;
    immutable msbs = 7 - bsr((~uint(c)) & 0xFF);
    if (c == 0xFF || msbs < 2 || msbs > 4)
        throw new UTFException("Invalid UTF-8 sequence", index);
    return msbs;
}

/++
    Calculate the length of the UTF sequence ending one code unit before
    `index` in `str`.

    Params:
        str = bidirectional range of UTF code units. Must be random access if
        `index` is passed
        index = index one past end of UTF sequence (default: `str.length`)

    Returns:
        The number of code units in the UTF sequence. For UTF-8, this is a
        value between 1 and 4 (as per $(HTTP tools.ietf.org/html/rfc3629#section-3, RFC 3629$(COMMA) section 3)).
        For UTF-16, it is either 1 or 2. For UTF-32, it is always 1.

    Throws:
        May throw a `UTFException` if `str[index]` is not one past the
        end of a valid UTF sequence.

    Note:
        `strideBack` will only analyze the element at $(D str[index - 1])
        element. It will not fully verify the validity of the UTF sequence, nor
        even verify the presence of the sequence: it will not actually
        guarantee that $(D strideBack(str, index) <= index).
  +/
uint strideBack(S)(auto ref S str, size_t index)
if (is(S : const char[]) ||
    (isRandomAccessRange!S && is(immutable ElementType!S == immutable char)))
{
    static if (is(typeof(str.length) : ulong))
        assert(index <= str.length, "Past the end of the UTF-8 sequence");
    assert(index > 0, "Not the end of the UTF-8 sequence");

    if ((str[index-1] & 0b1100_0000) != 0b1000_0000)
        return 1;

    if (index >= 4) //single verification for most common case
    {
        static foreach (i; 2 .. 5)
        {
            if ((str[index-i] & 0b1100_0000) != 0b1000_0000)
                return i;
        }
    }
    else
    {
        static foreach (i; 2 .. 4)
        {
            if (index >= i && (str[index-i] & 0b1100_0000) != 0b1000_0000)
                return i;
        }
    }
    throw new UTFException("Not the end of the UTF sequence", index);
}

/// Ditto
uint strideBack(S)(auto ref S str)
if (is(S : const char[]) ||
    (isRandomAccessRange!S && hasLength!S && is(immutable ElementType!S == immutable char)))
{
    return strideBack(str, str.length);
}

/// Ditto
uint strideBack(S)(auto ref S str)
if (isBidirectionalRange!S && is(immutable ElementType!S == immutable char) && !isRandomAccessRange!S)
{
    assert(!str.empty, "Past the end of the UTF-8 sequence");
    auto temp = str.save;
    foreach (i; AliasSeq!(1, 2, 3, 4))
    {
        if ((temp.back & 0b1100_0000) != 0b1000_0000)
            return i;
        temp.popBack();
        if (temp.empty)
            break;
    }
    throw new UTFException("The last code unit is not the end of the UTF-8 sequence");
}

@system unittest
{
    import core.exception : AssertError;
    import std.conv : to;
    import std.exception;
    import std.string : format;
    import std.traits : FunctionAttribute, functionAttributes, isSafe;
    static void test(string s, dchar c, size_t i = size_t.max, size_t line = __LINE__)
    {
        enforce(strideBack(s, i == size_t.max ? s.length : i) == codeLength!char(c),
                new AssertError(format("Unit test failure string: %s", s), __FILE__, line));

        enforce(strideBack(RandomCU!char(s), i == size_t.max ? s.length : i) == codeLength!char(c),
                new AssertError(format("Unit test failure range: %s", s), __FILE__, line));

        auto refRandom = new RefRandomCU!char(s);
        immutable randLen = refRandom.length;
        enforce(strideBack(refRandom, i == size_t.max ? s.length : i) == codeLength!char(c),
                new AssertError(format("Unit test failure rand ref range: %s", s), __FILE__, line));
        enforce(refRandom.length == randLen,
                new AssertError(format("Unit test failure rand ref range length: %s", s), __FILE__, line));

        if (i == size_t.max)
        {
            enforce(strideBack(s) == codeLength!char(c),
                    new AssertError(format("Unit test failure string code length: %s", s), __FILE__, line));

            enforce(strideBack(BidirCU!char(s)) == codeLength!char(c),
                    new AssertError(format("Unit test failure range code length: %s", s), __FILE__, line));

            auto refBidir = new RefBidirCU!char(s);
            immutable bidirLen = refBidir.length;
            enforce(strideBack(refBidir) == codeLength!char(c),
                    new AssertError(format("Unit test failure bidir ref range code length: %s", s), __FILE__, line));
            enforce(refBidir.length == bidirLen,
                    new AssertError(format("Unit test failure bidir ref range length: %s", s), __FILE__, line));
        }
    }

    assertCTFEable!(
    {
    test("a", 'a');
    test(" ", ' ');
    test("\u2029", '\u2029'); //paraSep
    test("\u0100", '\u0100');
    test("\u0430", '\u0430');
    test("\U00010143", '\U00010143');
    test("abcdefcdef", 'f');
    test("\U00010143\u0100\U00010143hello", 'o', 15);
    test("\U00010143\u0100\U00010143hello", 'l', 14);
    test("\U00010143\u0100\U00010143hello", 'l', 13);
    test("\U00010143\u0100\U00010143hello", 'e', 12);
    test("\U00010143\u0100\U00010143hello", 'h', 11);
    test("\U00010143\u0100\U00010143hello", '\U00010143', 10);
    test("\U00010143\u0100\U00010143hello", '\u0100', 6);
    test("\U00010143\u0100\U00010143hello", '\U00010143', 4);

    foreach (S; AliasSeq!(char[], const char[], string))
    {
        enum str = to!S("hello world");
        static assert(isSafe!({ strideBack(str, 0); }));
        static assert(isSafe!({ strideBack(str);    }));
        static assert((functionAttributes!({ strideBack(str, 0); }) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!({ strideBack(str);    }) & FunctionAttribute.pure_) != 0);
    }
    });
}

//UTF-16 is self synchronizing: The length of strideBack can be found from
//the value of a single wchar
/// Ditto
uint strideBack(S)(auto ref S str, size_t index)
if (is(S : const wchar[]) ||
    (isRandomAccessRange!S && is(immutable ElementType!S == immutable wchar)))
{
    static if (is(typeof(str.length) : ulong))
        assert(index <= str.length, "Past the end of the UTF-16 sequence");
    assert(index > 0, "Not the end of a UTF-16 sequence");

    immutable c2 = str[index-1];
    return 1 + (0xDC00 <= c2 && c2 < 0xE000);
}

/// Ditto
uint strideBack(S)(auto ref S str)
if (is(S : const wchar[]) ||
    (isBidirectionalRange!S && is(immutable ElementType!S == immutable wchar)))
{
    assert(!str.empty, "UTF-16 sequence is empty");

    static if (is(S : const(wchar)[]))
        immutable c2 = str[$ - 1];
    else
        immutable c2 = str.back;

    return 1 + (0xDC00 <= c2 && c2 <= 0xE000);
}

@system unittest
{
    import core.exception : AssertError;
    import std.conv : to;
    import std.exception;
    import std.string : format;
    import std.traits : FunctionAttribute, functionAttributes, isSafe;
    static void test(wstring s, dchar c, size_t i = size_t.max, size_t line = __LINE__)
    {
        enforce(strideBack(s, i == size_t.max ? s.length : i) == codeLength!wchar(c),
                new AssertError(format("Unit test failure string: %s", s), __FILE__, line));

        enforce(strideBack(RandomCU!wchar(s), i == size_t.max ? s.length : i) == codeLength!wchar(c),
                new AssertError(format("Unit test failure range: %s", s), __FILE__, line));

        auto refRandom = new RefRandomCU!wchar(s);
        immutable randLen = refRandom.length;
        enforce(strideBack(refRandom, i == size_t.max ? s.length : i) == codeLength!wchar(c),
                new AssertError(format("Unit test failure rand ref range: %s", s), __FILE__, line));
        enforce(refRandom.length == randLen,
                new AssertError(format("Unit test failure rand ref range length: %s", s), __FILE__, line));

        if (i == size_t.max)
        {
            enforce(strideBack(s) == codeLength!wchar(c),
                    new AssertError(format("Unit test failure string code length: %s", s), __FILE__, line));

            enforce(strideBack(BidirCU!wchar(s)) == codeLength!wchar(c),
                    new AssertError(format("Unit test failure range code length: %s", s), __FILE__, line));

            auto refBidir = new RefBidirCU!wchar(s);
            immutable bidirLen = refBidir.length;
            enforce(strideBack(refBidir) == codeLength!wchar(c),
                    new AssertError(format("Unit test failure bidir ref range code length: %s", s), __FILE__, line));
            enforce(refBidir.length == bidirLen,
                    new AssertError(format("Unit test failure bidir ref range length: %s", s), __FILE__, line));
        }
    }

    assertCTFEable!(
    {
    test("a", 'a');
    test(" ", ' ');
    test("\u2029", '\u2029'); //paraSep
    test("\u0100", '\u0100');
    test("\u0430", '\u0430');
    test("\U00010143", '\U00010143');
    test("abcdefcdef", 'f');
    test("\U00010143\u0100\U00010143hello", 'o', 10);
    test("\U00010143\u0100\U00010143hello", 'l', 9);
    test("\U00010143\u0100\U00010143hello", 'l', 8);
    test("\U00010143\u0100\U00010143hello", 'e', 7);
    test("\U00010143\u0100\U00010143hello", 'h', 6);
    test("\U00010143\u0100\U00010143hello", '\U00010143', 5);
    test("\U00010143\u0100\U00010143hello", '\u0100', 3);
    test("\U00010143\u0100\U00010143hello", '\U00010143', 2);

    foreach (S; AliasSeq!(wchar[], const wchar[], wstring))
    {
        enum str = to!S("hello world");
        static assert(isSafe!(() => strideBack(str, 0)));
        static assert(isSafe!(() => strideBack(str)   ));
        static assert((functionAttributes!(() => strideBack(str, 0)) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!(() => strideBack(str)   ) & FunctionAttribute.pure_) != 0);
    }
    });
}

/// Ditto
uint strideBack(S)(auto ref S str, size_t index)
if (isRandomAccessRange!S && is(immutable ElementEncodingType!S == immutable dchar))
{
    static if (is(typeof(str.length) : ulong))
        assert(index <= str.length, "Past the end of the UTF-32 sequence");
    assert(index > 0, "Not the end of the UTF-32 sequence");
    return 1;
}

/// Ditto
uint strideBack(S)(auto ref S str)
if (isBidirectionalRange!S && is(immutable ElementEncodingType!S == immutable dchar))
{
    assert(!str.empty, "Empty UTF-32 sequence");
    return 1;
}

///
@safe unittest
{
    assert("a".strideBack == 1);
    assert("λ".strideBack == 2);
    assert("aλ".strideBack == 2);
    assert("aλ".strideBack(1) == 1);
    assert("𐐷".strideBack == 4);
}

@system unittest
{
    import core.exception : AssertError;
    import std.conv : to;
    import std.exception;
    import std.string : format;
    import std.traits : FunctionAttribute, functionAttributes, isSafe;
    static void test(dstring s, dchar c, size_t i = size_t.max, size_t line = __LINE__)
    {
        enforce(strideBack(s, i == size_t.max ? s.length : i) == codeLength!dchar(c),
                new AssertError(format("Unit test failure string: %s", s), __FILE__, line));

        enforce(strideBack(RandomCU!dchar(s), i == size_t.max ? s.length : i) == codeLength!dchar(c),
                new AssertError(format("Unit test failure range: %s", s), __FILE__, line));

        auto refRandom = new RefRandomCU!dchar(s);
        immutable randLen = refRandom.length;
        enforce(strideBack(refRandom, i == size_t.max ? s.length : i) == codeLength!dchar(c),
                new AssertError(format("Unit test failure rand ref range: %s", s), __FILE__, line));
        enforce(refRandom.length == randLen,
                new AssertError(format("Unit test failure rand ref range length: %s", s), __FILE__, line));

        if (i == size_t.max)
        {
            enforce(strideBack(s) == codeLength!dchar(c),
                    new AssertError(format("Unit test failure string code length: %s", s), __FILE__, line));

            enforce(strideBack(BidirCU!dchar(s)) == codeLength!dchar(c),
                    new AssertError(format("Unit test failure range code length: %s", s), __FILE__, line));

            auto refBidir = new RefBidirCU!dchar(s);
            immutable bidirLen = refBidir.length;
            enforce(strideBack(refBidir) == codeLength!dchar(c),
                    new AssertError(format("Unit test failure bidir ref range code length: %s", s), __FILE__, line));
            enforce(refBidir.length == bidirLen,
                    new AssertError(format("Unit test failure bidir ref range length: %s", s), __FILE__, line));
        }
    }

    assertCTFEable!(
    {
    test("a", 'a');
    test(" ", ' ');
    test("\u2029", '\u2029'); //paraSep
    test("\u0100", '\u0100');
    test("\u0430", '\u0430');
    test("\U00010143", '\U00010143');
    test("abcdefcdef", 'f');
    test("\U00010143\u0100\U00010143hello", 'o', 8);
    test("\U00010143\u0100\U00010143hello", 'l', 7);
    test("\U00010143\u0100\U00010143hello", 'l', 6);
    test("\U00010143\u0100\U00010143hello", 'e', 5);
    test("\U00010143\u0100\U00010143hello", 'h', 4);
    test("\U00010143\u0100\U00010143hello", '\U00010143', 3);
    test("\U00010143\u0100\U00010143hello", '\u0100', 2);
    test("\U00010143\u0100\U00010143hello", '\U00010143', 1);

    foreach (S; AliasSeq!(dchar[], const dchar[], dstring))
    {
        enum str = to!S("hello world");
        static assert(isSafe!(() => strideBack(str, 0)));
        static assert(isSafe!(() => strideBack(str)   ));
        static assert((functionAttributes!(() => strideBack(str, 0)) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!(() => strideBack(str)   ) & FunctionAttribute.pure_) != 0);
    }
    });
}


/++
    Given `index` into `str` and assuming that `index` is at the start
    of a UTF sequence, `toUCSindex` determines the number of UCS characters
    up to `index`. So, `index` is the index of a code unit at the
    beginning of a code point, and the return value is how many code points into
    the string that that code point is.
  +/
size_t toUCSindex(C)(const(C)[] str, size_t index) @safe pure
if (isSomeChar!C)
{
    static if (is(immutable C == immutable dchar))
        return index;
    else
    {
        size_t n = 0;
        size_t j = 0;

        for (; j < index; ++n)
            j += stride(str, j);

        if (j > index)
        {
            static if (is(immutable C == immutable char))
                throw new UTFException("Invalid UTF-8 sequence", index);
            else
                throw new UTFException("Invalid UTF-16 sequence", index);
        }

        return n;
    }
}

///
@safe unittest
{
    assert(toUCSindex(`hello world`, 7) == 7);
    assert(toUCSindex(`hello world`w, 7) == 7);
    assert(toUCSindex(`hello world`d, 7) == 7);

    assert(toUCSindex(`Ma Chérie`, 7) == 6);
    assert(toUCSindex(`Ma Chérie`w, 7) == 7);
    assert(toUCSindex(`Ma Chérie`d, 7) == 7);

    assert(toUCSindex(`さいごの果実 / ミツバチと科学者`, 9) == 3);
    assert(toUCSindex(`さいごの果実 / ミツバチと科学者`w, 9) == 9);
    assert(toUCSindex(`さいごの果実 / ミツバチと科学者`d, 9) == 9);
}


/++
    Given a UCS index `n` into `str`, returns the UTF index.
    So, `n` is how many code points into the string the code point is, and
    the array index of the code unit is returned.
  +/
size_t toUTFindex(C)(const(C)[] str, size_t n) @safe pure
if (isSomeChar!C)
{
    static if (is(immutable C == immutable dchar))
    {
        return n;
    }
    else
    {
        size_t i;
        while (n--)
        {
            i += stride(str, i);
        }
        return i;
    }
}

///
@safe unittest
{
    assert(toUTFindex(`hello world`, 7) == 7);
    assert(toUTFindex(`hello world`w, 7) == 7);
    assert(toUTFindex(`hello world`d, 7) == 7);

    assert(toUTFindex(`Ma Chérie`, 6) == 7);
    assert(toUTFindex(`Ma Chérie`w, 7) == 7);
    assert(toUTFindex(`Ma Chérie`d, 7) == 7);

    assert(toUTFindex(`さいごの果実 / ミツバチと科学者`, 3) == 9);
    assert(toUTFindex(`さいごの果実 / ミツバチと科学者`w, 9) == 9);
    assert(toUTFindex(`さいごの果実 / ミツバチと科学者`d, 9) == 9);
}


/* =================== Decode ======================= */

/// Whether or not to replace invalid UTF with $(LREF replacementDchar)
alias UseReplacementDchar = Flag!"useReplacementDchar";

/++
    Decodes and returns the code point starting at `str[index]`. `index`
    is advanced to one past the decoded code point. If the code point is not
    well-formed, then a `UTFException` is thrown and `index` remains
    unchanged.

    decode will only work with strings and random access ranges of code units
    with length and slicing, whereas $(LREF decodeFront) will work with any
    input range of code units.

    Params:
        useReplacementDchar = if invalid UTF, return replacementDchar rather than throwing
        str = input string or indexable Range
        index = starting index into s[]; incremented by number of code units processed

    Returns:
        decoded character

    Throws:
        $(LREF UTFException) if `str[index]` is not the start of a valid UTF
        sequence and useReplacementDchar is `No.useReplacementDchar`
  +/
dchar decode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(auto ref S str, ref size_t index)
if (!isSomeString!S &&
    isRandomAccessRange!S && hasSlicing!S && hasLength!S && isSomeChar!(ElementType!S))
in
{
    assert(index < str.length, "Attempted to decode past the end of a string");
}
out (result)
{
    assert(isValidDchar(result));
}
do
{
    if (str[index] < codeUnitLimit!S)
        return str[index++];
    else
        return decodeImpl!(true, useReplacementDchar)(str, index);
}

/// ditto
dchar decode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(
auto ref scope S str, ref size_t index) @trusted pure
if (isSomeString!S)
in
{
    assert(index < str.length, "Attempted to decode past the end of a string");
}
out (result)
{
    assert(isValidDchar(result));
}
do
{
    if (str[index] < codeUnitLimit!S)
        return str[index++];
    else static if (is(immutable S == immutable C[], C))
        return decodeImpl!(true, useReplacementDchar)(cast(const(C)[]) str, index);
}

///
@safe pure unittest
{
    size_t i;

    assert("a".decode(i) == 'a' && i == 1);
    i = 0;
    assert("å".decode(i) == 'å' && i == 2);
    i = 1;
    assert("aå".decode(i) == 'å' && i == 3);
    i = 0;
    assert("å"w.decode(i) == 'å' && i == 1);

    // ë as a multi-code point grapheme
    i = 0;
    assert("e\u0308".decode(i) == 'e' && i == 1);
    // ë as a single code point grapheme
    i = 0;
    assert("ë".decode(i) == 'ë' && i == 2);
    i = 0;
    assert("ë"w.decode(i) == 'ë' && i == 1);
}

@safe pure unittest // https://issues.dlang.org/show_bug.cgi?id=22867
{
    import std.conv : hexString;
    string data = hexString!"f787a598";
    size_t offset = 0;
    try data.decode(offset);
    catch (UTFException ex) assert(offset == 0);
}

/++
    `decodeFront` is a variant of $(LREF decode) which specifically decodes
    the first code point. Unlike $(LREF decode), `decodeFront` accepts any
    $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    of code units (rather than just a string or random access
    range). It also takes the range by `ref` and pops off the elements as it
    decodes them. If `numCodeUnits` is passed in, it gets set to the number
    of code units which were in the code point which was decoded.

    Params:
        useReplacementDchar = if invalid UTF, return replacementDchar rather than throwing
        str = input string or indexable Range
        numCodeUnits = set to number of code units processed

    Returns:
        decoded character

    Throws:
        $(LREF UTFException) if `str.front` is not the start of a valid UTF
        sequence. If an exception is thrown, then there is no guarantee as to
        the number of code units which were popped off, as it depends on the
        type of range being used and how many code units had to be popped off
        before the code point was determined to be invalid.
  +/
dchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(
ref S str, out size_t numCodeUnits)
if (!isSomeString!S && isInputRange!S && isSomeChar!(ElementType!S))
in
{
    assert(!str.empty);
}
out (result)
{
    assert(isValidDchar(result));
}
do
{
    immutable fst = str.front;

    if (fst < codeUnitLimit!S)
    {
        str.popFront();
        numCodeUnits = 1;
        return fst;
    }
    else
    {
        // https://issues.dlang.org/show_bug.cgi?id=14447 forces canIndex to be
        // done outside of decodeImpl, which is undesirable, since not all
        // overloads of decodeImpl need it. So, it should be moved back into
        // decodeImpl once https://issues.dlang.org/show_bug.cgi?id=8521
        // has been fixed.
        enum canIndex = is(S : const char[]) || isRandomAccessRange!S && hasSlicing!S && hasLength!S;
        immutable retval = decodeImpl!(canIndex, useReplacementDchar)(str, numCodeUnits);

        // The other range types were already popped by decodeImpl.
        static if (isRandomAccessRange!S && hasSlicing!S && hasLength!S)
            str = str[numCodeUnits .. str.length];

        return retval;
    }
}

/// ditto
dchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(
ref scope S str, out size_t numCodeUnits) @trusted pure
if (isSomeString!S)
in
{
    assert(!str.empty);
}
out (result)
{
    assert(isValidDchar(result));
}
do
{
    if (str[0] < codeUnitLimit!S)
    {
        numCodeUnits = 1;
        immutable retval = str[0];
        str = str[1 .. $];
        return retval;
    }
    else static if (is(immutable S == immutable C[], C))
    {
        immutable retval = decodeImpl!(true, useReplacementDchar)(cast(const(C)[]) str, numCodeUnits);
        str = str[numCodeUnits .. $];
        return retval;
    }
}

/++ Ditto +/
dchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str)
if (isInputRange!S && isSomeChar!(ElementType!S))
{
    size_t numCodeUnits;
    return decodeFront!useReplacementDchar(str, numCodeUnits);
}

///
@safe pure unittest
{
    import std.range.primitives;
    string str = "Hello, World!";

    assert(str.decodeFront == 'H' && str == "ello, World!");
    str = "å";
    assert(str.decodeFront == 'å' && str.empty);
    str = "å";
    size_t i;
    assert(str.decodeFront(i) == 'å' && i == 2 && str.empty);
}

/++
    `decodeBack` is a variant of $(LREF decode) which specifically decodes
    the last code point. Unlike $(LREF decode), `decodeBack` accepts any
    bidirectional range of code units (rather than just a string or random access
    range). It also takes the range by `ref` and pops off the elements as it
    decodes them. If `numCodeUnits` is passed in, it gets set to the number
    of code units which were in the code point which was decoded.

    Params:
        useReplacementDchar = if invalid UTF, return `replacementDchar` rather than throwing
        str = input string or bidirectional Range
        numCodeUnits = gives the number of code units processed

    Returns:
        A decoded UTF character.

    Throws:
        $(LREF UTFException) if `str.back` is not the end of a valid UTF
        sequence. If an exception is thrown, the `str` itself remains unchanged,
        but there is no guarantee as to the value of `numCodeUnits` (when passed).
  +/
dchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(
    ref S str, out size_t numCodeUnits)
if (isSomeString!S)
in
{
    assert(!str.empty);
}
out (result)
{
    assert(isValidDchar(result));
}
do
{
    if (str[$ - 1] < codeUnitLimit!S)
    {
        numCodeUnits = 1;
        immutable retval = str[$ - 1];
        str = str[0 .. $ - 1];
        return retval;
    }
    else static if (is(immutable S == immutable C[], C))
    {
        numCodeUnits = strideBack(str);
        immutable newLength = str.length - numCodeUnits;
        size_t index = newLength;
        immutable retval = decodeImpl!(true, useReplacementDchar)(cast(const(C)[]) str, index);
        str = str[0 .. newLength];
        return retval;
    }
}

/++ Ditto +/
dchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(
    ref S str, out size_t numCodeUnits)
if (!isSomeString!S && isSomeChar!(ElementType!S) && isBidirectionalRange!S
    && ((isRandomAccessRange!S && hasLength!S) || !isRandomAccessRange!S))
in
{
    assert(!str.empty);
}
out (result)
{
    assert(isValidDchar(result));
}
do
{
    if (str.back < codeUnitLimit!S)
    {
        numCodeUnits = 1;
        immutable retval = str.back;
        str.popBack();
        return retval;
    }
    else
    {
        numCodeUnits = strideBack(str);
        static if (isRandomAccessRange!S)
        {
            size_t index = str.length - numCodeUnits;
            immutable retval = decodeImpl!(true, useReplacementDchar)(str, index);
            str.popBackExactly(numCodeUnits);
            return retval;
        }
        else
        {
            alias Char = typeof(cast() ElementType!S.init);
            Char[4] codeUnits = void;
            S tmp = str.save;
            for (size_t i = numCodeUnits; i > 0; )
            {
                codeUnits[--i] = tmp.back;
                tmp.popBack();
            }
            const Char[] codePoint = codeUnits[0 .. numCodeUnits];
            size_t index = 0;
            immutable retval = decodeImpl!(true, useReplacementDchar)(codePoint, index);
            str = tmp;
            return retval;
        }
    }
}

/++ Ditto +/
dchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str)
if (isSomeString!S
    || (isRandomAccessRange!S && hasLength!S && isSomeChar!(ElementType!S))
    || (!isRandomAccessRange!S && isBidirectionalRange!S && isSomeChar!(ElementType!S)))
in
{
    assert(!str.empty);
}
out (result)
{
    assert(isValidDchar(result));
}
do
{
    size_t numCodeUnits;
    return decodeBack!useReplacementDchar(str, numCodeUnits);
}

///
@system pure unittest
{
    import std.range.primitives;
    string str = "Hello, World!";

    assert(str.decodeBack == '!' && str == "Hello, World");
    str = "å";
    assert(str.decodeBack == 'å' && str.empty);
    str = "å";
    size_t i;
    assert(str.decodeBack(i) == 'å' && i == 2 && str.empty);
}

// For the given range, code unit values less than this
// are guaranteed to be valid single-codepoint encodings.
package template codeUnitLimit(S)
if (isSomeChar!(ElementEncodingType!S))
{
    static if (is(immutable ElementEncodingType!S == immutable char))
        enum char codeUnitLimit = 0x80;
    else static if (is(immutable ElementEncodingType!S == immutable wchar))
        enum wchar codeUnitLimit = 0xD800;
    else
        enum dchar codeUnitLimit = 0xD800;
}

/*
 * For strings, this function does its own bounds checking to give a
 * more useful error message when attempting to decode past the end of a string.
 * Subsequently it uses a pointer instead of an array to avoid
 * redundant bounds checking.
 *
 * The three overloads of this operate on chars, wchars, and dchars.
 *
 * Params:
 *      canIndex = if S is indexable
 *      useReplacementDchar = if invalid UTF, return replacementDchar rather than throwing
 *      str = input string or Range
 *      index = starting index into s[]; incremented by number of code units processed
 *
 * Returns:
 *      decoded character
 */
private dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(
    auto ref S str, ref size_t index)
if (
    is(S : const char[]) || (isInputRange!S && is(immutable ElementEncodingType!S == immutable char)))
{
    /* The following encodings are valid, except for the 5 and 6 byte
     * combinations:
     *  0xxxxxxx
     *  110xxxxx 10xxxxxx
     *  1110xxxx 10xxxxxx 10xxxxxx
     *  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
     *  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
     *  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
     */

    /* Dchar bitmask for different numbers of UTF-8 code units.
     */
    alias bitMask = AliasSeq!((1 << 7) - 1, (1 << 11) - 1, (1 << 16) - 1, (1 << 21) - 1);

    static if (is(S : const char[]))
        auto pstr = str.ptr + index;    // this is what makes decodeImpl() @system code
    else static if (isRandomAccessRange!S && hasSlicing!S && hasLength!S)
        auto pstr = str[index .. str.length];
    else
        alias pstr = str;

    // https://issues.dlang.org/show_bug.cgi?id=14447 forces this to be done
    // outside of decodeImpl
    //enum canIndex = is(S : const char[]) || (isRandomAccessRange!S && hasSlicing!S && hasLength!S);

    static if (canIndex)
    {
        immutable length = str.length - index;
        ubyte fst = pstr[0];
    }
    else
    {
        ubyte fst = pstr.front;
        pstr.popFront();
    }

    static if (!useReplacementDchar)
    {
        static if (canIndex)
        {
            static UTFException exception(S)(S str, string msg)
            {
                uint[4] sequence = void;
                size_t i;

                do
                {
                    sequence[i] = str[i];
                } while (++i < str.length && i < 4 && (str[i] & 0xC0) == 0x80);

                return new UTFException(msg, i).setSequence(sequence[0 .. i]);
            }
        }

        UTFException invalidUTF()
        {
            static if (canIndex)
               return exception(pstr[0 .. length], "Invalid UTF-8 sequence");
            else
            {
                //We can't include the invalid sequence with input strings without
                //saving each of the code units along the way, and we can't do it with
                //forward ranges without saving the entire range. Both would incur a
                //cost for the decoding of every character just to provide a better
                //error message for the (hopefully) rare case when an invalid UTF-8
                //sequence is encountered, so we don't bother trying to include the
                //invalid sequence here, unlike with strings and sliceable ranges.
               return new UTFException("Invalid UTF-8 sequence");
            }
        }

        UTFException outOfBounds()
        {
            static if (canIndex)
               return exception(pstr[0 .. length], "Attempted to decode past the end of a string");
            else
               return new UTFException("Attempted to decode past the end of a string");
        }
    }

    if ((fst & 0b1100_0000) != 0b1100_0000)
    {
        static if (useReplacementDchar)
        {
            ++index;            // always consume bad input to avoid infinite loops
            return replacementDchar;
        }
        else
            throw invalidUTF(); // starter must have at least 2 first bits set
    }
    ubyte tmp = void;
    dchar d = fst; // upper control bits are masked out later
    fst <<= 1;

    foreach (i; AliasSeq!(1, 2, 3))
    {

        static if (canIndex)
        {
            if (i == length)
            {
                static if (useReplacementDchar)
                {
                    index += i;
                    return replacementDchar;
                }
                else
                    throw outOfBounds();
            }
        }
        else
        {
            if (pstr.empty)
            {
                static if (useReplacementDchar)
                {
                    index += i;
                    return replacementDchar;
                }
                else
                    throw outOfBounds();
            }
        }

        static if (canIndex)
            tmp = pstr[i];
        else
        {
            tmp = pstr.front;
            pstr.popFront();
        }

        if ((tmp & 0xC0) != 0x80)
        {
            static if (useReplacementDchar)
            {
                index += i + 1;
                return replacementDchar;
            }
            else
                throw invalidUTF();
        }

        d = (d << 6) | (tmp & 0x3F);
        fst <<= 1;

        if (!(fst & 0x80)) // no more bytes
        {
            d &= bitMask[i]; // mask out control bits

            // overlong, could have been encoded with i bytes
            if ((d & ~bitMask[i - 1]) == 0)
            {
                static if (useReplacementDchar)
                {
                    index += i + 1;
                    return replacementDchar;
                }
                else
                    throw invalidUTF();
            }

            // check for surrogates only needed for 3 bytes
            static if (i == 2)
            {
                if (!isValidDchar(d))
                {
                    static if (useReplacementDchar)
                    {
                        index += i + 1;
                        return replacementDchar;
                    }
                    else
                        throw invalidUTF();
                }
            }

            static if (i == 3)
            {
                if (d > dchar.max)
                {
                    static if (useReplacementDchar)
                        d = replacementDchar;
                    else
                        throw invalidUTF();
                }
            }

            index += i + 1;
            return d;
        }
    }

    static if (useReplacementDchar)
    {
        index += 4;             // read 4 chars by now
        return replacementDchar;
    }
    else
        throw invalidUTF();
}

@safe pure @nogc nothrow
unittest
{
    // Add tests for useReplacemendDchar == yes path

    static struct R
    {
      @safe pure @nogc nothrow:
        this(string s) { this.s = s; }
        @property bool empty() { return idx == s.length; }
        @property char front() { return s[idx]; }
        void popFront() { ++idx; }
        size_t idx;
        string s;
    }

    foreach (s; invalidUTFstrings!char())
    {
        auto r = R(s);
        size_t index;
        dchar dc = decodeImpl!(false, Yes.useReplacementDchar)(r, index);
        assert(dc == replacementDchar);
        assert(1 <= index && index <= s.length);
    }
}

private dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)
(auto ref S str, ref size_t index)
if (is(S : const wchar[]) || (isInputRange!S && is(immutable ElementEncodingType!S == immutable wchar)))
{
    static if (is(S : const wchar[]))
        auto pstr = str.ptr + index;
    else static if (isRandomAccessRange!S && hasSlicing!S && hasLength!S)
        auto pstr = str[index .. str.length];
    else
        alias pstr = str;

    // https://issues.dlang.org/show_bug.cgi?id=14447 forces this to be done
    // outside of decodeImpl
    //enum canIndex = is(S : const wchar[]) || (isRandomAccessRange!S && hasSlicing!S && hasLength!S);

    static if (canIndex)
    {
        immutable length = str.length - index;
        uint u = pstr[0];
    }
    else
    {
        uint u = pstr.front;
        pstr.popFront();
    }

    static if (!useReplacementDchar)
    {
        UTFException exception(string msg)
        {
            static if (canIndex)
                return new UTFException(msg).setSequence(pstr[0]);
            else
                return new UTFException(msg);
        }
    }

    // The < case must be taken care of before decodeImpl is called.
    assert(u >= 0xD800);

    if (u <= 0xDBFF)
    {
        static if (canIndex)
            immutable onlyOneCodeUnit = length == 1;
        else
            immutable onlyOneCodeUnit = pstr.empty;

        if (onlyOneCodeUnit)
        {
            static if (useReplacementDchar)
            {
                ++index;
                return replacementDchar;
            }
            else
                throw exception("surrogate UTF-16 high value past end of string");
        }

        static if (canIndex)
            immutable uint u2 = pstr[1];
        else
        {
            immutable uint u2 = pstr.front;
            pstr.popFront();
        }

        if (u2 < 0xDC00 || u2 > 0xDFFF)
        {
            static if (useReplacementDchar)
                u = replacementDchar;
            else
                throw exception("surrogate UTF-16 low value out of range");
        }
        else
            u = ((u - 0xD7C0) << 10) + (u2 - 0xDC00);
        ++index;
    }
    else if (u >= 0xDC00 && u <= 0xDFFF)
    {
        static if (useReplacementDchar)
            u = replacementDchar;
        else
            throw exception("unpaired surrogate UTF-16 value");
    }
    ++index;

    // Note: u+FFFE and u+FFFF are specifically permitted by the
    // Unicode standard for application internal use (see isValidDchar)

    return cast(dchar) u;
}

@safe pure @nogc nothrow
unittest
{
    // Add tests for useReplacemendDchar == true path

    static struct R
    {
      @safe pure @nogc nothrow:
        this(wstring s) { this.s = s; }
        @property bool empty() { return idx == s.length; }
        @property wchar front() { return s[idx]; }
        void popFront() { ++idx; }
        size_t idx;
        wstring s;
    }

    foreach (s; invalidUTFstrings!wchar())
    {
        auto r = R(s);
        size_t index;
        dchar dc = decodeImpl!(false, Yes.useReplacementDchar)(r, index);
        assert(dc == replacementDchar);
        assert(1 <= index && index <= s.length);
    }
}

private dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(
    auto ref S str, ref size_t index)
if (is(S : const dchar[]) || (isInputRange!S && is(immutable ElementEncodingType!S == immutable dchar)))
{
    static if (is(S : const dchar[]))
        auto pstr = str.ptr;
    else
        alias pstr = str;

    static if (is(S : const dchar[]) || isRandomAccessRange!S)
    {
        dchar dc = pstr[index];
        if (!isValidDchar(dc))
        {
            static if (useReplacementDchar)
                dc = replacementDchar;
            else
                throw new UTFException("Invalid UTF-32 value").setSequence(dc);
        }
        ++index;
        return dc;
    }
    else
    {
        dchar dc = pstr.front;
        if (!isValidDchar(dc))
        {
            static if (useReplacementDchar)
                dc = replacementDchar;
            else
                throw new UTFException("Invalid UTF-32 value").setSequence(dc);
        }
        ++index;
        pstr.popFront();
        return dc;
    }
}

@safe pure @nogc nothrow
unittest
{
    // Add tests for useReplacemendDchar == true path

    static struct R
    {
      @safe pure @nogc nothrow:
        this(dstring s) { this.s = s; }
        @property bool empty() { return idx == s.length; }
        @property dchar front() { return s[idx]; }
        void popFront() { ++idx; }
        size_t idx;
        dstring s;
    }

    foreach (s; invalidUTFstrings!dchar())
    {
        auto r = R(s);
        size_t index;
        dchar dc = decodeImpl!(false, Yes.useReplacementDchar)(r, index);
        assert(dc == replacementDchar);
        assert(1 <= index && index <= s.length);
    }
}


version (StdUnittest) private void testDecode(R)(R range,
                                             size_t index,
                                             dchar expectedChar,
                                             size_t expectedIndex,
                                             size_t line = __LINE__)
{
    import core.exception : AssertError;
    import std.exception : enforce;
    import std.string : format;
    import std.traits : isNarrowString;

    static if (hasLength!R)
        immutable lenBefore = range.length;

    static if (isRandomAccessRange!R && !isNarrowString!R)
    {
        {
            immutable result = decode(range, index);
            enforce(result == expectedChar,
                    new AssertError(format("decode: Wrong character: %s", result), __FILE__, line));
            enforce(index == expectedIndex,
                    new AssertError(format("decode: Wrong index: %s", index), __FILE__, line));
            static if (hasLength!R)
            {
                enforce(range.length == lenBefore,
                        new AssertError(format("decode: length changed: %s", range.length), __FILE__, line));
            }
        }
    }
}

version (StdUnittest) private void testDecodeFront(R)(ref R range,
                                                  dchar expectedChar,
                                                  size_t expectedNumCodeUnits,
                                                  size_t line = __LINE__)
{
    import core.exception : AssertError;
    import std.exception : enforce;
    import std.string : format;

    static if (hasLength!R)
        immutable lenBefore = range.length;

    size_t numCodeUnits;
    immutable result = decodeFront(range, numCodeUnits);
    enforce(result == expectedChar,
            new AssertError(format("decodeFront: Wrong character: %s", result), __FILE__, line));
    enforce(numCodeUnits == expectedNumCodeUnits,
            new AssertError(format("decodeFront: Wrong numCodeUnits: %s", numCodeUnits), __FILE__, line));

    static if (hasLength!R)
    {
        enforce(range.length == lenBefore - numCodeUnits,
                new AssertError(format("decodeFront: wrong length: %s", range.length), __FILE__, line));
    }
}

version (StdUnittest) private void testDecodeBack(R)(ref R range,
                                                 dchar expectedChar,
                                                 size_t expectedNumCodeUnits,
                                                 size_t line = __LINE__)
{
    // This condition is to allow unit testing all `decode` functions together
    static if (!isBidirectionalRange!R)
        return;
    else
    {
        import core.exception : AssertError;
        import std.exception : enforce;
        import std.string : format;

        static if (hasLength!R)
            immutable lenBefore = range.length;

        size_t numCodeUnits;
        immutable result = decodeBack(range, numCodeUnits);
        enforce(result == expectedChar,
                new AssertError(format("decodeBack: Wrong character: %s", result), __FILE__, line));
        enforce(numCodeUnits == expectedNumCodeUnits,
                new AssertError(format("decodeBack: Wrong numCodeUnits: %s", numCodeUnits), __FILE__, line));

        static if (hasLength!R)
        {
            enforce(range.length == lenBefore - numCodeUnits,
                    new AssertError(format("decodeBack: wrong length: %s", range.length), __FILE__, line));
        }
    }
}

version (StdUnittest) private void testAllDecode(R)(R range,
                                                dchar expectedChar,
                                                size_t expectedIndex,
                                                size_t line = __LINE__)
{
    testDecode(range, 0, expectedChar, expectedIndex, line);
    static if (isBidirectionalRange!R)
    {
        auto rangeCopy = range.save;
        testDecodeBack(rangeCopy, expectedChar, expectedIndex, line);
    }
    testDecodeFront(range, expectedChar, expectedIndex, line);
}

version (StdUnittest) private void testBadDecode(R)(R range, size_t index, size_t line = __LINE__)
{
    import core.exception : AssertError;
    import std.exception : assertThrown, enforce;
    import std.string : format;

    immutable initialIndex = index;

    static if (hasLength!R)
        immutable lenBefore = range.length;

    static if (isRandomAccessRange!R)
    {
        assertThrown!UTFException(decode(range, index), null, __FILE__, line);
        enforce(index == initialIndex,
                new AssertError(format("decode: Wrong index: %s", index), __FILE__, line));
        static if (hasLength!R)
        {
            enforce(range.length == lenBefore,
                    new AssertError(format("decode: length changed:", range.length), __FILE__, line));
        }
    }

    if (initialIndex == 0)
        assertThrown!UTFException(decodeFront(range, index), null, __FILE__, line);
}

version (StdUnittest) private void testBadDecodeBack(R)(R range, size_t line = __LINE__)
{
    // This condition is to allow unit testing all `decode` functions together
    static if (!isBidirectionalRange!R)
        return;
    else
    {
        import core.exception : AssertError;
        import std.exception : assertThrown, enforce;
        import std.string : format;

        static if (hasLength!R)
            immutable lenBefore = range.length;

        static if (isRandomAccessRange!R)
        {
            assertThrown!UTFException(decodeBack(range), null, __FILE__, line);
            static if (hasLength!R)
            {
                enforce(range.length == lenBefore,
                        new AssertError(format("decodeBack: length changed:", range.length), __FILE__, line));
            }
        }
    }
}

@system unittest
{
    import std.conv : to;
    import std.exception;

    assertCTFEable!(
    {
    foreach (S; AliasSeq!(to!string, InputCU!char, RandomCU!char,
                          (string s) => new RefBidirCU!char(s),
                          (string s) => new RefRandomCU!char(s)))
    {
        enum sHasLength = hasLength!(typeof(S("abcd")));

        {
            auto range = S("abcd");
            testDecode(range, 0, 'a', 1);
            testDecode(range, 1, 'b', 2);
            testDecodeFront(range, 'a', 1);
            testDecodeFront(range, 'b', 1);
            assert(decodeFront(range) == 'c');
            assert(decodeFront(range) == 'd');
        }

        {
            auto range = S("ウェブサイト");
            testDecode(range, 0, 'ウ', 3);
            testDecode(range, 3, 'ェ', 6);
            testDecodeFront(range, 'ウ', 3);
            testDecodeFront(range, 'ェ', 3);
            assert(decodeFront(range) == 'ブ');
            assert(decodeFront(range) == 'サ');
        }

        {
            auto range = S("abcd");
            testDecodeBack(range, 'd', 1);
            testDecodeBack(range, 'c', 1);
            testDecodeBack(range, 'b', 1);
            testDecodeBack(range, 'a', 1);
        }

        {
            auto range = S("ウェブサイト");
            testDecodeBack(range, 'ト', 3);
            testDecodeBack(range, 'イ', 3);
            testDecodeBack(range, 'サ', 3);
            testDecodeBack(range, 'ブ', 3);
        }

        testAllDecode(S("\xC2\xA9"), '\u00A9', 2);
        testAllDecode(S("\xE2\x89\xA0"), '\u2260', 3);

        foreach (str; ["\xE2\x89", // too short
                       "\xC0\x8A",
                       "\xE0\x80\x8A",
                       "\xF0\x80\x80\x8A",
                       "\xF8\x80\x80\x80\x8A",
                       "\xFC\x80\x80\x80\x80\x8A"])
        {
            testBadDecode(S(str), 0);
            testBadDecode(S(str), 1);
            testBadDecodeBack(S(str));
        }

        //Invalid UTF-8 sequence where the first code unit is valid.
        testAllDecode(S("\xEF\xBF\xBE"), cast(dchar) 0xFFFE, 3);
        testAllDecode(S("\xEF\xBF\xBF"), cast(dchar) 0xFFFF, 3);

        //Invalid UTF-8 sequence where the first code unit isn't valid.
        foreach (str; ["\xED\xA0\x80",
                       "\xED\xAD\xBF",
                       "\xED\xAE\x80",
                       "\xED\xAF\xBF",
                       "\xED\xB0\x80",
                       "\xED\xBE\x80",
                       "\xED\xBF\xBF"])
        {
            testBadDecode(S(str), 0);
            testBadDecodeBack(S(str));
        }
    }
    });
}

@system unittest
{
    import std.exception;
    assertCTFEable!(
    {
    foreach (S; AliasSeq!((wstring s) => s, InputCU!wchar, RandomCU!wchar,
                          (wstring s) => new RefBidirCU!wchar(s),
                          (wstring s) => new RefRandomCU!wchar(s)))
    {
        testAllDecode(S([cast(wchar) 0x1111]), cast(dchar) 0x1111, 1);
        testAllDecode(S([cast(wchar) 0xD800, cast(wchar) 0xDC00]), cast(dchar) 0x10000, 2);
        testAllDecode(S([cast(wchar) 0xDBFF, cast(wchar) 0xDFFF]), cast(dchar) 0x10FFFF, 2);
        testAllDecode(S([cast(wchar) 0xFFFE]), cast(dchar) 0xFFFE, 1);
        testAllDecode(S([cast(wchar) 0xFFFF]), cast(dchar) 0xFFFF, 1);

        testBadDecode(S([ cast(wchar) 0xD801 ]), 0);
        testBadDecode(S([ cast(wchar) 0xD800, cast(wchar) 0x1200 ]), 0);

        testBadDecodeBack(S([ cast(wchar) 0xD801 ]));
        testBadDecodeBack(S([ cast(wchar) 0x0010, cast(wchar) 0xD800 ]));

        {
            auto range = S("ウェブサイト");
            testDecode(range, 0, 'ウ', 1);
            testDecode(range, 1, 'ェ', 2);
            testDecodeFront(range, 'ウ', 1);
            testDecodeFront(range, 'ェ', 1);
            assert(decodeFront(range) == 'ブ');
            assert(decodeFront(range) == 'サ');
        }

        {
            auto range = S("ウェブサイト");
            testDecodeBack(range, 'ト', 1);
            testDecodeBack(range, 'イ', 1);
            testDecodeBack(range, 'サ', 1);
            testDecodeBack(range, 'ブ', 1);
        }
    }

    foreach (S; AliasSeq!((wchar[] s) => s.idup, RandomCU!wchar, (wstring s) => new RefRandomCU!wchar(s)))
    {
        auto str = S([cast(wchar) 0xD800, cast(wchar) 0xDC00,
                      cast(wchar) 0x1400,
                      cast(wchar) 0xDAA7, cast(wchar) 0xDDDE]);
        testDecode(str, 0, cast(dchar) 0x10000, 2);
        testDecode(str, 2, cast(dchar) 0x1400, 3);
        testDecode(str, 3, cast(dchar) 0xB9DDE, 5);
        testDecodeBack(str, cast(dchar) 0xB9DDE, 2);
        testDecodeBack(str, cast(dchar) 0x1400, 1);
        testDecodeBack(str, cast(dchar) 0x10000, 2);
    }
    });
}

@system unittest
{
    import std.exception;
    assertCTFEable!(
    {
    foreach (S; AliasSeq!((dstring s) => s, RandomCU!dchar, InputCU!dchar,
                          (dstring s) => new RefBidirCU!dchar(s),
                          (dstring s) => new RefRandomCU!dchar(s)))
    {
        testAllDecode(S([cast(dchar) 0x1111]), cast(dchar) 0x1111, 1);
        testAllDecode(S([cast(dchar) 0x10000]), cast(dchar) 0x10000, 1);
        testAllDecode(S([cast(dchar) 0x10FFFF]), cast(dchar) 0x10FFFF, 1);
        testAllDecode(S([cast(dchar) 0xFFFE]), cast(dchar) 0xFFFE, 1);
        testAllDecode(S([cast(dchar) 0xFFFF]), cast(dchar) 0xFFFF, 1);

        testBadDecode(S([cast(dchar) 0xD800]), 0);
        testBadDecode(S([cast(dchar) 0xDFFE]), 0);
        testBadDecode(S([cast(dchar) 0x110000]), 0);

        testBadDecodeBack(S([cast(dchar) 0xD800]));
        testBadDecodeBack(S([cast(dchar) 0xDFFE]));
        testBadDecodeBack(S([cast(dchar) 0x110000]));

        {
            auto range = S("ウェブサイト");
            testDecode(range, 0, 'ウ', 1);
            testDecode(range, 1, 'ェ', 2);
            testDecodeFront(range, 'ウ', 1);
            testDecodeFront(range, 'ェ', 1);
            assert(decodeFront(range) == 'ブ');
            assert(decodeFront(range) == 'サ');
        }

        {
            auto range = S("ウェブサイト");
            testDecodeBack(range, 'ト', 1);
            testDecodeBack(range, 'イ', 1);
            testDecodeBack(range, 'サ', 1);
            testDecodeBack(range, 'ブ', 1);
        }
    }

    foreach (S; AliasSeq!((dchar[] s) => s.idup, RandomCU!dchar, (dstring s) => new RefRandomCU!dchar(s)))
    {
        auto str = S([cast(dchar) 0x10000, cast(dchar) 0x1400, cast(dchar) 0xB9DDE]);
        testDecode(str, 0, 0x10000, 1);
        testDecode(str, 1, 0x1400, 2);
        testDecode(str, 2, 0xB9DDE, 3);
        testDecodeBack(str, cast(dchar) 0xB9DDE, 1);
        testDecodeBack(str, cast(dchar) 0x1400, 1);
        testDecodeBack(str, cast(dchar) 0x10000, 1);
    }
    });
}

@safe unittest
{
    import std.exception;
    import std.traits : FunctionAttribute, functionAttributes, isSafe;
    assertCTFEable!(
    {
    foreach (S; AliasSeq!( char[], const( char)[],  string,
                          wchar[], const(wchar)[], wstring,
                          dchar[], const(dchar)[], dstring))
    {
        static assert(isSafe!({ S str; size_t i = 0; decode(str, i);      }));
        static assert(isSafe!({ S str; size_t i = 0; decodeFront(str, i); }));
        static assert(isSafe!({ S str; decodeFront(str); }));
        static assert((functionAttributes!({ S str; size_t i = 0; decode(str, i); }) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!({
            S str; size_t i = 0; decodeFront(str, i);
        }) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!({ S str; decodeFront(str); }) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!({
            S str; size_t i = 0; decodeBack(str, i);
        }) & FunctionAttribute.pure_) != 0);
        static assert((functionAttributes!({ S str; decodeBack(str); }) & FunctionAttribute.pure_) != 0);
    }
    });
}

@safe unittest
{
    import std.exception;
    char[4] val;
    val[0] = 0b1111_0111;
    val[1] = 0b1011_1111;
    val[2] = 0b1011_1111;
    val[3] = 0b1011_1111;
    size_t i = 0;
    assertThrown!UTFException((){ dchar ch = decode(val[], i); }());
}
/* =================== Encode ======================= */

private dchar _utfException(UseReplacementDchar useReplacementDchar)(string msg, dchar c)
{
    static if (useReplacementDchar)
        return replacementDchar;
    else
        throw new UTFException(msg).setSequence(c);
}

/++
    Encodes `c` into the static array, `buf`, and returns the actual
    length of the encoded character (a number between `1` and `4` for
    `char[4]` buffers and a number between `1` and `2` for
    `wchar[2]` buffers).

    Throws:
        `UTFException` if `c` is not a valid UTF code point.
  +/
size_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(
    out char[4] buf, dchar c) @safe pure
{
    if (c <= 0x7F)
    {
        assert(isValidDchar(c));
        buf[0] = cast(char) c;
        return 1;
    }
    if (c <= 0x7FF)
    {
        assert(isValidDchar(c));
        buf[0] = cast(char)(0xC0 | (c >> 6));
        buf[1] = cast(char)(0x80 | (c & 0x3F));
        return 2;
    }
    if (c <= 0xFFFF)
    {
        if (0xD800 <= c && c <= 0xDFFF)
            c = _utfException!useReplacementDchar("Encoding a surrogate code point in UTF-8", c);

        assert(isValidDchar(c));
    L3:
        buf[0] = cast(char)(0xE0 | (c >> 12));
        buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));
        buf[2] = cast(char)(0x80 | (c & 0x3F));
        return 3;
    }
    if (c <= 0x10FFFF)
    {
        assert(isValidDchar(c));
        buf[0] = cast(char)(0xF0 | (c >> 18));
        buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));
        buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));
        buf[3] = cast(char)(0x80 | (c & 0x3F));
        return 4;
    }

    assert(!isValidDchar(c));
    c = _utfException!useReplacementDchar("Encoding an invalid code point in UTF-8", c);
    goto L3;
}

///
@safe unittest
{
    import std.exception : assertThrown;
    import std.typecons : Yes;

    char[4] buf;

    assert(encode(buf, '\u0000') == 1 && buf[0 .. 1] == "\u0000");
    assert(encode(buf, '\u007F') == 1 && buf[0 .. 1] == "\u007F");
    assert(encode(buf, '\u0080') == 2 && buf[0 .. 2] == "\u0080");
    assert(encode(buf, '\uE000') == 3 && buf[0 .. 3] == "\uE000");
    assert(encode(buf, 0xFFFE) == 3 && buf[0 .. 3] == "\xEF\xBF\xBE");
    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));

    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);
    auto slice = buf[];
    assert(slice.decodeFront == replacementDchar);
}

///
@safe unittest
{
    import std.exception : assertThrown;
    import std.typecons : Yes;

    wchar[2] buf;

    assert(encode(buf, '\u0000') == 1 && buf[0 .. 1] == "\u0000");
    assert(encode(buf, '\uD7FF') == 1 && buf[0 .. 1] == "\uD7FF");
    assert(encode(buf, '\uE000') == 1 && buf[0 .. 1] == "\uE000");
    assert(encode(buf, '\U00010000') == 2 && buf[0 .. 2] == "\U00010000");
    assert(encode(buf, '\U0010FFFF') == 2 && buf[0 .. 2] == "\U0010FFFF");
    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));

    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);
    auto slice = buf[];
    assert(slice.decodeFront == replacementDchar);
}

///
@safe unittest
{
    import std.exception : assertThrown;
    import std.typecons : Yes;

    dchar[1] buf;

    assert(encode(buf, '\u0000') == 1 && buf[0] == '\u0000');
    assert(encode(buf, '\uD7FF') == 1 && buf[0] == '\uD7FF');
    assert(encode(buf, '\uE000') == 1 && buf[0] == '\uE000');
    assert(encode(buf, '\U0010FFFF') == 1 && buf[0] == '\U0010FFFF');
    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));

    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);
    assert(buf[0] == replacementDchar);
}

@safe unittest
{
    import std.exception;
    assertCTFEable!(
    {
    char[4] buf;

    assert(encode(buf, '\u0000') == 1 && buf[0 .. 1] == "\u0000");
    assert(encode(buf, '\u007F') == 1 && buf[0 .. 1] == "\u007F");
    assert(encode(buf, '\u0080') == 2 && buf[0 .. 2] == "\u0080");
    assert(encode(buf, '\u07FF') == 2 && buf[0 .. 2] == "\u07FF");
    assert(encode(buf, '\u0800') == 3 && buf[0 .. 3] == "\u0800");
    assert(encode(buf, '\uD7FF') == 3 && buf[0 .. 3] == "\uD7FF");
    assert(encode(buf, '\uE000') == 3 && buf[0 .. 3] == "\uE000");
    assert(encode(buf, 0xFFFE) == 3 && buf[0 .. 3] == "\xEF\xBF\xBE");
    assert(encode(buf, 0xFFFF) == 3 && buf[0 .. 3] == "\xEF\xBF\xBF");
    assert(encode(buf, '\U00010000') == 4 && buf[0 .. 4] == "\U00010000");
    assert(encode(buf, '\U0010FFFF') == 4 && buf[0 .. 4] == "\U0010FFFF");

    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));

    assert(encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000) == buf.stride);
    enum replacementDcharString = "\uFFFD";
    assert(buf[0 .. replacementDcharString.length] == replacementDcharString);
    });
}


/// Ditto
size_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(
    out wchar[2] buf, dchar c) @safe pure
{
    if (c <= 0xFFFF)
    {
        if (0xD800 <= c && c <= 0xDFFF)
            c = _utfException!useReplacementDchar("Encoding an isolated surrogate code point in UTF-16", c);

        assert(isValidDchar(c));
    L1:
        buf[0] = cast(wchar) c;
        return 1;
    }
    if (c <= 0x10FFFF)
    {
        assert(isValidDchar(c));
        buf[0] = cast(wchar)((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
        buf[1] = cast(wchar)(((c - 0x10000) & 0x3FF) + 0xDC00);
        return 2;
    }

    c = _utfException!useReplacementDchar("Encoding an invalid code point in UTF-16", c);
    goto L1;
}

@safe unittest
{
    import std.exception;
    assertCTFEable!(
    {
    wchar[2] buf;

    assert(encode(buf, '\u0000') == 1 && buf[0 .. 1] == "\u0000");
    assert(encode(buf, '\uD7FF') == 1 && buf[0 .. 1] == "\uD7FF");
    assert(encode(buf, '\uE000') == 1 && buf[0 .. 1] == "\uE000");
    assert(encode(buf, 0xFFFE) == 1 && buf[0] == 0xFFFE);
    assert(encode(buf, 0xFFFF) == 1 && buf[0] == 0xFFFF);
    assert(encode(buf, '\U00010000') == 2 && buf[0 .. 2] == "\U00010000");
    assert(encode(buf, '\U0010FFFF') == 2 && buf[0 .. 2] == "\U0010FFFF");

    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));

    assert(encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000) == buf.stride);
    assert(buf.front == replacementDchar);
    });
}


/// Ditto
size_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(
    out dchar[1] buf, dchar c) @safe pure
{
    if ((0xD800 <= c && c <= 0xDFFF) || 0x10FFFF < c)
        c = _utfException!useReplacementDchar("Encoding an invalid code point in UTF-32", c);
    else
        assert(isValidDchar(c));
    buf[0] = c;
    return 1;
}

@safe unittest
{
    import std.exception;
    assertCTFEable!(
    {
    dchar[1] buf;

    encode(buf, '\u0000'); assert(buf[0] == '\u0000');
    encode(buf, '\uD7FF'); assert(buf[0] == '\uD7FF');
    encode(buf, '\uE000'); assert(buf[0] == '\uE000');
    encode(buf, 0xFFFE); assert(buf[0] == 0xFFFE);
    encode(buf, 0xFFFF); assert(buf[0] == 0xFFFF);
    encode(buf, '\U0010FFFF'); assert(buf[0] == '\U0010FFFF');

    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));

    assert(encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000) == buf.stride);
    assert(buf.front == replacementDchar);
    });
}


/++
    Encodes `c` in `str`'s encoding and appends it to `str`.

    Throws:
        `UTFException` if `c` is not a valid UTF code point.
  +/
void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(
    ref scope char[] str, dchar c) @safe pure
{
    if (c <= 0x7F)
    {
        assert(isValidDchar(c));
        str ~= cast(char) c;
    }
    else
    {
        char[4] buf;
        uint L;

        if (c <= 0x7FF)
        {
            assert(isValidDchar(c));
            buf[0] = cast(char)(0xC0 | (c >> 6));
            buf[1] = cast(char)(0x80 | (c & 0x3F));
            L = 2;
        }
        else if (c <= 0xFFFF)
        {
            if (0xD800 <= c && c <= 0xDFFF)
                c = _utfException!useReplacementDchar("Encoding a surrogate code point in UTF-8", c);

            assert(isValidDchar(c));
        L3:
            buf[0] = cast(char)(0xE0 | (c >> 12));
            buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));
            buf[2] = cast(char)(0x80 | (c & 0x3F));
            L = 3;
        }
        else if (c <= 0x10FFFF)
        {
            assert(isValidDchar(c));
            buf[0] = cast(char)(0xF0 | (c >> 18));
            buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));
            buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));
            buf[3] = cast(char)(0x80 | (c & 0x3F));
            L = 4;
        }
        else
        {
            assert(!isValidDchar(c));
            c = _utfException!useReplacementDchar("Encoding an invalid code point in UTF-8", c);
            goto L3;
        }
        str ~= buf[0 .. L];
    }
}

///
@safe unittest
{
    char[] s = "abcd".dup;
    dchar d1 = 'a';
    dchar d2 = 'ø';

    encode(s, d1);
    assert(s.length == 5);
    assert(s == "abcda");
    encode(s, d2);
    assert(s.length == 7);
    assert(s == "abcdaø");
}

@safe unittest
{
    import std.exception;

    assertCTFEable!(
    {
    char[] s = "abcd".dup;
    encode(s, cast(dchar)'a');
    assert(s.length == 5);
    assert(s == "abcda");

    encode(s, cast(dchar)'\u00A9');
    assert(s.length == 7);
    assert(s == "abcda\xC2\xA9");
    //assert(s == "abcda\u00A9");   // BUG: fix compiler

    encode(s, cast(dchar)'\u2260');
    assert(s.length == 10);
    assert(s == "abcda\xC2\xA9\xE2\x89\xA0");
    });
}

@safe unittest
{
    import std.exception;
    assertCTFEable!(
    {
    char[] buf;

    encode(buf, '\u0000'); assert(buf[0 .. $] == "\u0000");
    encode(buf, '\u007F'); assert(buf[1 .. $] == "\u007F");
    encode(buf, '\u0080'); assert(buf[2 .. $] == "\u0080");
    encode(buf, '\u07FF'); assert(buf[4 .. $] == "\u07FF");
    encode(buf, '\u0800'); assert(buf[6 .. $] == "\u0800");
    encode(buf, '\uD7FF'); assert(buf[9 .. $] == "\uD7FF");
    encode(buf, '\uE000'); assert(buf[12 .. $] == "\uE000");
    encode(buf, 0xFFFE); assert(buf[15 .. $] == "\xEF\xBF\xBE");
    encode(buf, 0xFFFF); assert(buf[18 .. $] == "\xEF\xBF\xBF");
    encode(buf, '\U00010000'); assert(buf[21 .. $] == "\U00010000");
    encode(buf, '\U0010FFFF'); assert(buf[25 .. $] == "\U0010FFFF");

    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));

    enum replacementDcharString = "\uFFFD";
    enum rdcslen = replacementDcharString.length;
    assert(buf[$ - rdcslen .. $] != replacementDcharString);
    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);
    assert(buf[$ - rdcslen .. $] == replacementDcharString);
    });
}

/// ditto
void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(
    ref scope wchar[] str, dchar c) @safe pure
{
    if (c <= 0xFFFF)
    {
        if (0xD800 <= c && c <= 0xDFFF)
            c = _utfException!useReplacementDchar("Encoding an isolated surrogate code point in UTF-16", c);

        assert(isValidDchar(c));
    L1:
        str ~= cast(wchar) c;
    }
    else if (c <= 0x10FFFF)
    {
        wchar[2] buf;

        assert(isValidDchar(c));
        buf[0] = cast(wchar)((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
        buf[1] = cast(wchar)(((c - 0x10000) & 0x3FF) + 0xDC00);
        str ~= buf;
    }
    else
    {
        assert(!isValidDchar(c));
        c = _utfException!useReplacementDchar("Encoding an invalid code point in UTF-16", c);
        goto L1;
    }
}

@safe unittest
{
    import std.exception;
    assertCTFEable!(
    {
    wchar[] buf;

    encode(buf, '\u0000'); assert(buf[0] == '\u0000');
    encode(buf, '\uD7FF'); assert(buf[1] == '\uD7FF');
    encode(buf, '\uE000'); assert(buf[2] == '\uE000');
    encode(buf, 0xFFFE); assert(buf[3] == 0xFFFE);
    encode(buf, 0xFFFF); assert(buf[4] == 0xFFFF);
    encode(buf, '\U00010000'); assert(buf[5 .. $] == "\U00010000");
    encode(buf, '\U0010FFFF'); assert(buf[7 .. $] == "\U0010FFFF");

    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));

    assert(buf.back != replacementDchar);
    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);
    assert(buf.back == replacementDchar);
    });
}

/// ditto
void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(
    ref scope dchar[] str, dchar c) @safe pure
{
    if ((0xD800 <= c && c <= 0xDFFF) || 0x10FFFF < c)
        c = _utfException!useReplacementDchar("Encoding an invalid code point in UTF-32", c);
    else
        assert(isValidDchar(c));
    str ~= c;
}

@safe unittest
{
    import std.exception;
    assertCTFEable!(
    {
    dchar[] buf;

    encode(buf, '\u0000'); assert(buf[0] == '\u0000');
    encode(buf, '\uD7FF'); assert(buf[1] == '\uD7FF');
    encode(buf, '\uE000'); assert(buf[2] == '\uE000');
    encode(buf, 0xFFFE); assert(buf[3] == 0xFFFE);
    encode(buf, 0xFFFF); assert(buf[4] == 0xFFFF);
    encode(buf, '\U0010FFFF'); assert(buf[5] == '\U0010FFFF');

    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));
    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));
    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));

    assert(buf.back != replacementDchar);
    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);
    assert(buf.back == replacementDchar);
    });
}


/++
    Returns the number of code units that are required to encode the code point
    `c` when `C` is the character type used to encode it.
  +/
ubyte codeLength(C)(dchar c) @safe pure nothrow @nogc
if (isSomeChar!C)
{
    static if (C.sizeof == 1)
    {
        if (c <= 0x7F) return 1;
        if (c <= 0x7FF) return 2;
        if (c <= 0xFFFF) return 3;
        if (c <= 0x10FFFF) return 4;
        assert(false);
    }
    else static if (C.sizeof == 2)
    {
        return c <= 0xFFFF ? 1 : 2;
    }
    else
    {
        static assert(C.sizeof == 4);
        return 1;
    }
}

///
@safe pure nothrow @nogc unittest
{
    assert(codeLength!char('a') == 1);
    assert(codeLength!wchar('a') == 1);
    assert(codeLength!dchar('a') == 1);

    assert(codeLength!char('\U0010FFFF') == 4);
    assert(codeLength!wchar('\U0010FFFF') == 2);
    assert(codeLength!dchar('\U0010FFFF') == 1);
}


/++
    Returns the number of code units that are required to encode `str`
    in a string whose character type is `C`. This is particularly useful
    when slicing one string with the length of another and the two string
    types use different character types.

    Params:
        C = the character type to get the encoding length for
        input = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
        to calculate the encoding length from
    Returns:
        The number of code units in `input` when encoded to `C`
  +/
size_t codeLength(C, InputRange)(InputRange input)
if (isSomeFiniteCharInputRange!InputRange)
{
    alias EncType = typeof(cast() ElementEncodingType!InputRange.init);
    static if (isSomeString!InputRange && is(EncType == C) && is(typeof(input.length)))
        return input.length;
    else
    {
        size_t total = 0;

        foreach (c; input.byDchar)
            total += codeLength!C(c);

        return total;
    }
}

///
@safe unittest
{
    assert(codeLength!char("hello world") ==
           "hello world".length);
    assert(codeLength!wchar("hello world") ==
           "hello world"w.length);
    assert(codeLength!dchar("hello world") ==
           "hello world"d.length);

    assert(codeLength!char(`プログラミング`) ==
           `プログラミング`.length);
    assert(codeLength!wchar(`プログラミング`) ==
           `プログラミング`w.length);
    assert(codeLength!dchar(`プログラミング`) ==
           `プログラミング`d.length);

    string haystack = `Être sans la verité, ça, ce ne serait pas bien.`;
    wstring needle = `Être sans la verité`;
    assert(haystack[codeLength!char(needle) .. $] ==
           `, ça, ce ne serait pas bien.`);
}

@safe unittest
{
    import std.algorithm.iteration : filter;
    import std.conv : to;
    import std.exception;

    assertCTFEable!(
    {
    foreach (S; AliasSeq!( char[], const  char[],  string,
                          wchar[], const wchar[], wstring,
                          dchar[], const dchar[], dstring))
    {
        foreach (C; AliasSeq!(char, wchar, dchar))
        {
            assert(codeLength!C(to!S("Walter Bright")) == to!(C[])("Walter Bright").length);
            assert(codeLength!C(to!S(`言語`)) == to!(C[])(`言語`).length);
            assert(codeLength!C(to!S(`ウェブサイト@La_Verité.com`)) ==
                   to!(C[])(`ウェブサイト@La_Verité.com`).length);
            assert(codeLength!C(to!S(`ウェブサイト@La_Verité.com`).filter!(x => true)()) ==
                   to!(C[])(`ウェブサイト@La_Verité.com`).length);
        }
    }
    });
}

/+
Internal helper function:

Returns true if it is safe to search for the Codepoint `c` inside
code units, without decoding.

This is a runtime check that is used an optimization in various functions,
particularly, in `std.string`.
  +/
package bool canSearchInCodeUnits(C)(dchar c)
if (isSomeChar!C)
{
    static if (C.sizeof == 1)
         return c <= 0x7F;
    else static if (C.sizeof == 2)
        return c <= 0xD7FF || (0xE000 <= c && c <= 0xFFFF);
    else static if (C.sizeof == 4)
        return true;
    else
        static assert(0);
}
@safe unittest
{
    assert( canSearchInCodeUnits! char('a'));
    assert( canSearchInCodeUnits!wchar('a'));
    assert( canSearchInCodeUnits!dchar('a'));
    assert(!canSearchInCodeUnits! char('ö')); //Important test: ö <= 0xFF
    assert(!canSearchInCodeUnits! char(cast(char)'ö')); //Important test: ö <= 0xFF
    assert( canSearchInCodeUnits!wchar('ö'));
    assert( canSearchInCodeUnits!dchar('ö'));
    assert(!canSearchInCodeUnits! char('日'));
    assert( canSearchInCodeUnits!wchar('日'));
    assert( canSearchInCodeUnits!dchar('日'));
    assert(!canSearchInCodeUnits!wchar(cast(wchar) 0xDA00));
    assert( canSearchInCodeUnits!dchar(cast(dchar) 0xDA00));
    assert(!canSearchInCodeUnits! char('\U00010001'));
    assert(!canSearchInCodeUnits!wchar('\U00010001'));
    assert( canSearchInCodeUnits!dchar('\U00010001'));
}

/* =================== Validation ======================= */

/++
    Checks to see if `str` is well-formed unicode or not.

    Throws:
        `UTFException` if `str` is not well-formed.
  +/
void validate(S)(in S str) @safe pure
if (isSomeString!S)
{
    immutable len = str.length;
    for (size_t i = 0; i < len; )
    {
        decode(str, i);
    }
}

///
@safe unittest
{
    import std.exception : assertThrown;
    char[] a = [167, 133, 175];
    assertThrown!UTFException(validate(a));
}

// https://issues.dlang.org/show_bug.cgi?id=12923
@safe unittest
{
    import std.exception;
    assertThrown((){
        char[3]a=[167, 133, 175];
        validate(a[]);
    }());
}

/**
 * Encodes the elements of `s` to UTF-8 and returns a newly allocated
 * string of the elements.
 *
 * Params:
 *     s = the string to encode
 * Returns:
 *     A UTF-8 string
 * See_Also:
 *     For a lazy, non-allocating version of these functions, see $(LREF byUTF).
 */
string toUTF8(S)(S s)
if (isSomeFiniteCharInputRange!S)
{
    return toUTFImpl!string(s);
}

///
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    // The ö is represented by two UTF-8 code units
    assert("Hellø"w.toUTF8.equal(['H', 'e', 'l', 'l', 0xC3, 0xB8]));

    // 𐐷 is four code units in UTF-8
    assert("𐐷"d.toUTF8.equal([0xF0, 0x90, 0x90, 0xB7]));
}

@system pure unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : ReferenceInputRange;

    alias RT = ReferenceInputRange!(ElementType!(string));
    auto r1 = new RT("Hellø");
    auto r2 = new RT("𐐷");

    assert(r1.toUTF8.equal(['H', 'e', 'l', 'l', 0xC3, 0xB8]));
    assert(r2.toUTF8.equal([0xF0, 0x90, 0x90, 0xB7]));
}

/**
 * Encodes the elements of `s` to UTF-16 and returns a newly GC allocated
 * `wstring` of the elements.
 *
 * Params:
 *     s = the range to encode
 * Returns:
 *     A UTF-16 string
 * See_Also:
 *     For a lazy, non-allocating version of these functions, see $(LREF byUTF).
 */
wstring toUTF16(S)(S s)
if (isSomeFiniteCharInputRange!S)
{
    return toUTFImpl!wstring(s);
}

///
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    // these graphemes are two code units in UTF-16 and one in UTF-32
    assert("𤭢"d.length == 1);
    assert("𐐷"d.length == 1);

    assert("𤭢"d.toUTF16.equal([0xD852, 0xDF62]));
    assert("𐐷"d.toUTF16.equal([0xD801, 0xDC37]));
}

@system pure unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : ReferenceInputRange;

    alias RT = ReferenceInputRange!(ElementType!(string));
    auto r1 = new RT("𤭢");
    auto r2 = new RT("𐐷");

    assert(r1.toUTF16.equal([0xD852, 0xDF62]));
    assert(r2.toUTF16.equal([0xD801, 0xDC37]));
}


/**
 * Encodes the elements of `s` to UTF-32 and returns a newly GC allocated
 * `dstring` of the elements.
 *
 * Params:
 *     s = the range to encode
 * Returns:
 *     A UTF-32 string
 * See_Also:
 *     For a lazy, non-allocating version of these functions, see $(LREF byUTF).
 */
dstring toUTF32(S)(scope S s)
if (isSomeFiniteCharInputRange!S)
{
    return toUTFImpl!dstring(s);
}

///
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    // these graphemes are two code units in UTF-16 and one in UTF-32
    assert("𤭢"w.length == 2);
    assert("𐐷"w.length == 2);

    assert("𤭢"w.toUTF32.equal([0x00024B62]));
    assert("𐐷"w.toUTF32.equal([0x00010437]));
}

private T toUTFImpl(T, S)(scope S s)
{
    static if (is(S : T))
    {
        return s.idup;
    }
    else
    {
        import std.array : appender;
        auto app = appender!T();

        static if (is(S == C[], C) || hasLength!S)
            app.reserve(s.length);

        ElementEncodingType!T e = void;
        foreach (c; s.byUTF!(typeof(cast() ElementEncodingType!T.init)))
            app.put(c);

        return app.data;
    }
}

/* =================== toUTFz ======================= */

/++
    Returns a C-style zero-terminated string equivalent to `str`. `str`
    must not contain embedded `'\0'`'s as any C function will treat the first
    `'\0'` that it sees as the end of the string. If `str.empty` is
    `true`, then a string containing only `'\0'` is returned.

    `toUTFz` accepts any type of string and is templated on the type of
    character pointer that you wish to convert to. It will avoid allocating a
    new string if it can, but there's a decent chance that it will end up having
    to allocate a new string - particularly when dealing with character types
    other than `char`.

    $(RED Warning 1:) If the result of `toUTFz` equals `str.ptr`, then if
    anything alters the character one past the end of `str` (which is the
    `'\0'` character terminating the string), then the string won't be
    zero-terminated anymore. The most likely scenarios for that are if you
    append to `str` and no reallocation takes place or when `str` is a
    slice of a larger array, and you alter the character in the larger array
    which is one character past the end of `str`. Another case where it could
    occur would be if you had a mutable character array immediately after
    `str` in memory (for example, if they're member variables in a
    user-defined type with one declared right after the other) and that
    character array happened to start with `'\0'`. Such scenarios will never
    occur if you immediately use the zero-terminated string after calling
    `toUTFz` and the C function using it doesn't keep a reference to it.
    Also, they are unlikely to occur even if you save the zero-terminated string
    (the cases above would be among the few examples of where it could happen).
    However, if you save the zero-terminate string and want to be absolutely
    certain that the string stays zero-terminated, then simply append a
    `'\0'` to the string and use its `ptr` property rather than calling
    `toUTFz`.

    $(RED Warning 2:) When passing a character pointer to a C function, and the
    C function keeps it around for any reason, make sure that you keep a
    reference to it in your D code. Otherwise, it may go away during a garbage
    collection cycle and cause a nasty bug when the C code tries to use it.
  +/
template toUTFz(P)
if (is(P == C*, C) && isSomeChar!C)
{
    P toUTFz(S)(S str) @safe pure
    if (isSomeString!S)
    {
        return toUTFzImpl!(P, S)(str);
    }
}

///
@safe pure unittest
{
    auto p1 = toUTFz!(char*)("hello world");
    auto p2 = toUTFz!(const(char)*)("hello world");
    auto p3 = toUTFz!(immutable(char)*)("hello world");
    auto p4 = toUTFz!(char*)("hello world"d);
    auto p5 = toUTFz!(const(wchar)*)("hello world");
    auto p6 = toUTFz!(immutable(dchar)*)("hello world"w);
}

private P toUTFzImpl(P, S)(return scope S str) @safe pure
if (is(immutable typeof(*P.init) == typeof(str[0])))
//immutable(C)[] -> C*, const(C)*, or immutable(C)*
{
    if (str.empty)
    {
        typeof(*P.init)[] retval = ['\0'];

        auto trustedPtr() @trusted { return retval.ptr; }
        return trustedPtr();
    }

    alias C = typeof(cast() ElementEncodingType!S.init);

    //If the P is mutable, then we have to make a copy.
    static if (is(typeof(cast() *P.init) == typeof(*P.init)))
    {
        return toUTFzImpl!(P, const(C)[])(cast(const(C)[])str);
    }
    else
    {
        if (!__ctfe)
        {
            auto trustedPtrAdd(S s) @trusted { return s.ptr + s.length; }
            immutable p = trustedPtrAdd(str);

            // Peek past end of str, if it's 0, no conversion necessary.
            // Note that the compiler will put a 0 past the end of static
            // strings, and the storage allocator will put a 0 past the end
            // of newly allocated char[]'s.
            // Is p dereferenceable? A simple test: if the p points to an
            // address multiple of 4, then conservatively assume the pointer
            // might be pointing to a new block of memory, which might be
            // unreadable. Otherwise, it's definitely pointing to valid
            // memory.
            if ((cast(size_t) p & 3) && *p == '\0')
                return &str[0];
        }

        return toUTFzImpl!(P, const(C)[])(cast(const(C)[])str);
    }
}

private P toUTFzImpl(P, S)(return scope S str) @safe pure
if (is(typeof(str[0]) C) && is(immutable typeof(*P.init) == immutable C) && !is(C == immutable))
//C[] or const(C)[] -> C*, const(C)*, or immutable(C)*
{
    alias InChar   = typeof(str[0]);
    alias UInChar  = typeof(cast() str[0]); // unqualified version of InChar
    alias OutChar  = typeof(*P.init);
    alias UOutChar = typeof(cast() *P.init); // unqualified version

    //const(C)[] -> const(C)* or
    //C[] -> C* or const(C)*
    static if (( is(const(UInChar) == InChar) &&  is(    const(UOutChar) == OutChar)) ||
               (!is(const(UInChar) == InChar) && !is(immutable(UOutChar) == OutChar)))
    {
        if (!__ctfe)
        {
            auto trustedPtrAdd(S s) @trusted { return s.ptr + s.length; }
            auto p = trustedPtrAdd(str);

            if ((cast(size_t) p & 3) && *p == '\0')
                return &str[0];
        }

        str ~= '\0';
        return &str[0];
    }
    //const(C)[] -> C* or immutable(C)* or
    //C[] -> immutable(C)*
    else
    {
        import std.array : uninitializedArray;
        auto copy = uninitializedArray!(UOutChar[])(str.length + 1);
        copy[0 .. $ - 1] = str[];
        copy[$ - 1] = '\0';

        auto trustedCast(typeof(copy) c) @trusted { return cast(P) c.ptr; }
        return trustedCast(copy);
    }
}

private P toUTFzImpl(P, S)(S str) @safe pure
if (!is(immutable typeof(*P.init) == immutable typeof(str[0])))
//C1[], const(C1)[], or immutable(C1)[] -> C2*, const(C2)*, or immutable(C2)*
{
    import std.array : appender;
    auto retval = appender!(typeof(*P.init)[])();

    foreach (dchar c; str)
        retval.put(c);
    retval.put('\0');

    return () @trusted { return cast(P) retval.data.ptr; } ();
}

@safe pure unittest
{
    import core.exception : AssertError;
    import std.algorithm;
    import std.conv : to;
    import std.exception;
    import std.string : format;

    assertCTFEable!(
    {
    foreach (S; AliasSeq!(string, wstring, dstring))
    {
        alias C = Unqual!(ElementEncodingType!S);

        auto s1 = to!S("hello\U00010143\u0100\U00010143");
        auto temp = new C[](s1.length + 1);
        temp[0 .. $ - 1] = s1[0 .. $];
        temp[$ - 1] = '\n';
        --temp.length;
        auto trustedAssumeUnique(T)(T t) @trusted { return assumeUnique(t); }
        auto s2 = trustedAssumeUnique(temp);
        assert(s1 == s2);

        void trustedCStringAssert(P, S)(S s) @trusted
        {
            auto p = toUTFz!P(s);
            assert(p[0 .. s.length] == s);
            assert(p[s.length] == '\0');
        }

        foreach (P; AliasSeq!(C*, const(C)*, immutable(C)*))
        {
            trustedCStringAssert!P(s1);
            trustedCStringAssert!P(s2);
        }
    }
    });

    static void test(P, S)(S s, size_t line = __LINE__) @trusted
    {
        static size_t zeroLen(C)(const(C)* ptr) @trusted
        {
            size_t len = 0;
            while (*ptr != '\0') { ++ptr; ++len; }
            return len;
        }

        auto p = toUTFz!P(s);
        immutable len = zeroLen(p);
        enforce(cmp(s, p[0 .. len]) == 0,
                new AssertError(format("Unit test failed: %s %s", P.stringof, S.stringof),
                                __FILE__, line));
    }

    assertCTFEable!(
    {
    foreach (P; AliasSeq!(wchar*, const(wchar)*, immutable(wchar)*,
                          dchar*, const(dchar)*, immutable(dchar)*))
    {
        test!P("hello\U00010143\u0100\U00010143");
    }
    foreach (P; AliasSeq!( char*, const( char)*, immutable( char)*,
                          dchar*, const(dchar)*, immutable(dchar)*))
    {
        test!P("hello\U00010143\u0100\U00010143"w);
    }
    foreach (P; AliasSeq!( char*, const( char)*, immutable( char)*,
                          wchar*, const(wchar)*, immutable(wchar)*))
    {
        test!P("hello\U00010143\u0100\U00010143"d);
    }
    foreach (S; AliasSeq!( char[], const( char)[],
                          wchar[], const(wchar)[],
                          dchar[], const(dchar)[]))
    {
        auto s = to!S("hello\U00010143\u0100\U00010143");

        foreach (P; AliasSeq!( char*, const( char)*, immutable( char)*,
                              wchar*, const(wchar)*, immutable(wchar)*,
                              dchar*, const(dchar)*, immutable(dchar)*))
        {
            test!P(s);
        }
    }
    });
}


/++
    `toUTF16z` is a convenience function for `toUTFz!(const(wchar)*)`.

    Encodes string `s` into UTF-16 and returns the encoded string.
    `toUTF16z` is suitable for calling the 'W' functions in the Win32 API
    that take an `LPCWSTR` argument.
  +/
const(wchar)* toUTF16z(C)(const(C)[] str) @safe pure
if (isSomeChar!C)
{
    return toUTFz!(const(wchar)*)(str);
}

///
@system unittest
{
    string str = "Hello, World!";
    const(wchar)* p = str.toUTF16z;
    assert(p[str.length] == '\0');
}

@safe pure unittest
{
    import std.conv : to;
    //toUTFz is already thoroughly tested, so this will just verify that
    //toUTF16z compiles properly for the various string types.
    foreach (S; AliasSeq!(string, wstring, dstring))
        assert(toUTF16z(to!S("hello world")) !is null);
}


/* ================================ tests ================================== */

@safe pure unittest
{
    import std.exception;

    assertCTFEable!(
    {
    assert(toUTF16("hello"c) == "hello");
    assert(toUTF32("hello"c) == "hello");
    assert(toUTF8 ("hello"w) == "hello");
    assert(toUTF32("hello"w) == "hello");
    assert(toUTF8 ("hello"d) == "hello");
    assert(toUTF16("hello"d) == "hello");

    assert(toUTF16("hel\u1234o"c) == "hel\u1234o");
    assert(toUTF32("hel\u1234o"c) == "hel\u1234o");
    assert(toUTF8 ("hel\u1234o"w) == "hel\u1234o");
    assert(toUTF32("hel\u1234o"w) == "hel\u1234o");
    assert(toUTF8 ("hel\u1234o"d) == "hel\u1234o");
    assert(toUTF16("hel\u1234o"d) == "hel\u1234o");

    assert(toUTF16("he\U0010AAAAllo"c) == "he\U0010AAAAllo");
    assert(toUTF32("he\U0010AAAAllo"c) == "he\U0010AAAAllo");
    assert(toUTF8 ("he\U0010AAAAllo"w) == "he\U0010AAAAllo");
    assert(toUTF32("he\U0010AAAAllo"w) == "he\U0010AAAAllo");
    assert(toUTF8 ("he\U0010AAAAllo"d) == "he\U0010AAAAllo");
    assert(toUTF16("he\U0010AAAAllo"d) == "he\U0010AAAAllo");
    });
}


/++
    Returns the total number of code points encoded in `str`.

    Supercedes: This function supercedes $(LREF toUCSindex).

    Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252

    Throws:
        `UTFException` if `str` is not well-formed.
  +/
size_t count(C)(const(C)[] str) @safe pure nothrow @nogc
if (isSomeChar!C)
{
    return walkLength(str.byDchar);
}

///
@safe pure nothrow @nogc unittest
{
    assert(count("") == 0);
    assert(count("a") == 1);
    assert(count("abc") == 3);
    assert(count("\u20AC100") == 4);
}

@safe pure nothrow @nogc unittest
{
    import std.exception;
    assertCTFEable!(
    {
    assert(count("") == 0);
    assert(count("a") == 1);
    assert(count("abc") == 3);
    assert(count("\u20AC100") == 4);
    });
}


// Ranges of code units for testing.
version (StdUnittest)
{
private:
    struct InputCU(C)
    {
        import std.conv : to;
        @property bool empty() { return _str.empty; }
        @property C front() { return _str[0]; }
        void popFront() { _str = _str[1 .. $]; }

        this(inout(C)[] str)
        {
            _str = to!(C[])(str);
        }

        C[] _str;
    }

    struct BidirCU(C)
    {
        import std.conv : to;
        @property bool empty() { return _str.empty; }
        @property C front() { return _str[0]; }
        void popFront() { _str = _str[1 .. $]; }
        @property C back() { return _str[$ - 1]; }
        void popBack() { _str = _str[0 .. $ - 1]; }
        @property auto save() { return BidirCU(_str); }
        @property size_t length() { return _str.length; }

        this(inout(C)[] str)
        {
            _str = to!(C[])(str);
        }

        C[] _str;
    }

    struct RandomCU(C)
    {
        import std.conv : to;
        @property bool empty() { return _str.empty; }
        @property C front() { return _str[0]; }
        void popFront() { _str = _str[1 .. $]; }
        @property C back() { return _str[$ - 1]; }
        void popBack() { _str = _str[0 .. $ - 1]; }
        @property auto save() { return RandomCU(_str); }
        @property size_t length() { return _str.length; }
        C opIndex(size_t i) { return _str[i]; }
        auto opSlice(size_t i, size_t j) { return RandomCU(_str[i .. j]); }

        this(inout(C)[] str)
        {
            _str = to!(C[])(str);
        }

        C[] _str;
    }

    class RefBidirCU(C)
    {
        import std.conv : to;
        @property bool empty() { return _str.empty; }
        @property C front() { return _str[0]; }
        void popFront() { _str = _str[1 .. $]; }
        @property C back() { return _str[$ - 1]; }
        void popBack() { _str = _str[0 .. $ - 1]; }
        @property auto save() { return new RefBidirCU(_str); }
        @property size_t length() { return _str.length; }

        this(inout(C)[] str)
        {
            _str = to!(C[])(str);
        }

        C[] _str;
    }

    class RefRandomCU(C)
    {
        import std.conv : to;
        @property bool empty() { return _str.empty; }
        @property C front() { return _str[0]; }
        void popFront() { _str = _str[1 .. $]; }
        @property C back() { return _str[$ - 1]; }
        void popBack() { _str = _str[0 .. $ - 1]; }
        @property auto save() { return new RefRandomCU(_str); }
        @property size_t length() { return _str.length; }
        C opIndex(size_t i) { return _str[i]; }
        auto opSlice(size_t i, size_t j) { return new RefRandomCU(_str[i .. j]); }

        this(inout(C)[] str)
        {
            _str = to!(C[])(str);
        }

        C[] _str;
    }
}


/**
 * Inserted in place of invalid UTF sequences.
 *
 * References:
 *      $(LINK http://en.wikipedia.org/wiki/Replacement_character#Replacement_character)
 */
enum dchar replacementDchar = '\uFFFD';

/********************************************
 * Iterate a range of char, wchar, or dchars by code unit.
 *
 * The purpose is to bypass the special case decoding that
 * $(REF front, std,range,primitives) does to character arrays. As a result,
 * using ranges with `byCodeUnit` can be `nothrow` while
 * $(REF front, std,range,primitives) throws when it encounters invalid Unicode
 * sequences.
 *
 * A code unit is a building block of the UTF encodings. Generally, an
 * individual code unit does not represent what's perceived as a full
 * character (a.k.a. a grapheme cluster in Unicode terminology). Many characters
 * are encoded with multiple code units. For example, the UTF-8 code units for
 * `ø` are `0xC3 0xB8`. That means, an individual element of `byCodeUnit`
 * often does not form a character on its own. Attempting to treat it as
 * one while iterating over the resulting range will give nonsensical results.
 *
 * Params:
 *      r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
 *      of characters (including strings) or a type that implicitly converts to a string type.
 * Returns:
 *      If `r` is not an auto-decodable string (i.e. a narrow string or a
 *      user-defined type that implicitly converts to a string type), then `r`
 *      is returned.
 *
 *      Otherwise, `r` is converted to its corresponding string type (if it's
 *      not already a string) and wrapped in a random-access range where the
 *      element encoding type of the string (its code unit) is the element type
 *      of the range, and that range returned. The range has slicing.
 *
 *      If `r` is quirky enough to be a struct or class which is an input range
 *      of characters on its own (i.e. it has the input range API as member
 *      functions), $(I and) it's implicitly convertible to a string type, then
 *      `r` is returned, and no implicit conversion takes place.
 *
 *      If `r` is wrapped in a new range, then that range has a `source`
 *      property for returning the string that's currently contained within that
 *      range.
 *
 * See_Also:
 *      Refer to the $(MREF std, uni) docs for a reference on Unicode
 *      terminology.
 *
 *      For a range that iterates by grapheme cluster (written character) see
 *      $(REF byGrapheme, std,uni).
 */
auto byCodeUnit(R)(R r)
if ((isConvertibleToString!R && !isStaticArray!R) ||
    (isInputRange!R && isSomeChar!(ElementEncodingType!R)))
{
    import std.traits : StringTypeOf;
    static if (// This would be cleaner if we had a way to check whether a type
               // was a range without any implicit conversions.
               (isAutodecodableString!R && !__traits(hasMember, R, "empty") &&
                !__traits(hasMember, R, "front") && !__traits(hasMember, R, "popFront")))
    {
        static struct ByCodeUnitImpl
        {
        @safe pure nothrow @nogc:

            @property bool empty() const     { return source.length == 0; }
            @property auto ref front() inout { return source[0]; }
            void popFront()                  { source = source[1 .. $]; }

            @property auto save() { return ByCodeUnitImpl(source.save); }

            @property auto ref back() inout { return source[$ - 1]; }
            void popBack()                  { source = source[0 .. $-1]; }

            auto ref opIndex(size_t index) inout     { return source[index]; }
            auto opSlice(size_t lower, size_t upper) { return ByCodeUnitImpl(source[lower .. upper]); }

            @property size_t length() const { return source.length; }
            alias opDollar = length;

            StringTypeOf!R source;
        }

        static assert(isRandomAccessRange!ByCodeUnitImpl);

        return ByCodeUnitImpl(r);
    }
    else static if (!isInputRange!R ||
                    (is(R : const dchar[]) && !__traits(hasMember, R, "empty") &&
                    !__traits(hasMember, R, "front") && !__traits(hasMember, R, "popFront")))
    {
        return cast(StringTypeOf!R) r;
    }
    else
    {
        // byCodeUnit for ranges and dchar[] is a no-op
        return r;
    }
}

///
@safe unittest
{
    import std.range.primitives;
    import std.traits : isAutodecodableString;

    auto r = "Hello, World!".byCodeUnit();
    static assert(hasLength!(typeof(r)));
    static assert(hasSlicing!(typeof(r)));
    static assert(isRandomAccessRange!(typeof(r)));
    static assert(is(ElementType!(typeof(r)) == immutable char));

    // contrast with the range capabilities of standard strings (with or
    // without autodecoding enabled).
    auto s = "Hello, World!";
    static assert(isBidirectionalRange!(typeof(r)));
    static if (isAutodecodableString!(typeof(s)))
    {
        // with autodecoding enabled, strings are non-random-access ranges of
        // dchar.
        static assert(is(ElementType!(typeof(s)) == dchar));
        static assert(!isRandomAccessRange!(typeof(s)));
        static assert(!hasSlicing!(typeof(s)));
        static assert(!hasLength!(typeof(s)));
    }
    else
    {
        // without autodecoding, strings are normal arrays.
        static assert(is(ElementType!(typeof(s)) == immutable char));
        static assert(isRandomAccessRange!(typeof(s)));
        static assert(hasSlicing!(typeof(s)));
        static assert(hasLength!(typeof(s)));
    }
}

/// `byCodeUnit` does no Unicode decoding
@safe unittest
{
    string noel1 = "noe\u0308l"; // noël using e + combining diaeresis
    assert(noel1.byCodeUnit[2] != 'ë');
    assert(noel1.byCodeUnit[2] == 'e');

    string noel2 = "no\u00EBl"; // noël using a precomposed ë character
    // Because string is UTF-8, the code unit at index 2 is just
    // the first of a sequence that encodes 'ë'
    assert(noel2.byCodeUnit[2] != 'ë');
}

/// `byCodeUnit` exposes a `source` property when wrapping narrow strings.
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : popFrontN;
    import std.traits : isAutodecodableString;
    {
        auto range = byCodeUnit("hello world");
        range.popFrontN(3);
        assert(equal(range.save, "lo world"));
        static if (isAutodecodableString!string) // only enabled with autodecoding
        {
            string str = range.source;
            assert(str == "lo world");
        }
    }
    // source only exists if the range was wrapped
    {
        auto range = byCodeUnit("hello world"d);
        static assert(!__traits(compiles, range.source));
    }
}

@safe pure nothrow @nogc unittest
{
    import std.range;
    {
        enum testStr = "𐁄𐂌𐃯 hello ディラン";
        char[testStr.length] s;
        int i;
        foreach (c; testStr.byCodeUnit().byCodeUnit())
        {
            s[i++] = c;
        }
        assert(s == testStr);
    }
    {
        enum testStr = "𐁄𐂌𐃯 hello ディラン"w;
        wchar[testStr.length] s;
        int i;
        foreach (c; testStr.byCodeUnit().byCodeUnit())
        {
            s[i++] = c;
        }
        assert(s == testStr);
    }
    {
        enum testStr = "𐁄𐂌𐃯 hello ディラン"d;
        dchar[testStr.length] s;
        int i;
        foreach (c; testStr.byCodeUnit().byCodeUnit())
        {
            s[i++] = c;
        }
        assert(s == testStr);
    }
    {
        auto bcu = "hello".byCodeUnit();
        assert(bcu.length == 5);
        assert(bcu[3] == 'l');
        assert(bcu[2 .. 4][1] == 'l');
    }
    {
        char[5] orig = "hello";
        auto bcu = orig[].byCodeUnit();
        bcu.front = 'H';
        assert(bcu.front == 'H');
        bcu[1] = 'E';
        assert(bcu[1] == 'E');
    }
    {
        auto bcu = "hello".byCodeUnit().byCodeUnit();
        static assert(isForwardRange!(typeof(bcu)));
        static assert(is(typeof(bcu) == struct) == isAutodecodableString!string);
        auto s = bcu.save;
        bcu.popFront();
        assert(s.front == 'h');
    }
    {
        auto bcu = "hello".byCodeUnit();
        static assert(hasSlicing!(typeof(bcu)));
        static assert(isBidirectionalRange!(typeof(bcu)));
        static assert(is(typeof(bcu) == struct) == isAutodecodableString!string);
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        auto ret = bcu.retro;
        assert(ret.front == 'o');
        ret.popFront();
        assert(ret.front == 'l');
    }
    {
        auto bcu = "κόσμε"w.byCodeUnit();
        static assert(hasSlicing!(typeof(bcu)));
        static assert(isBidirectionalRange!(typeof(bcu)));
        static assert(is(typeof(bcu) == struct) == isAutodecodableString!wstring);
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        auto ret = bcu.retro;
        assert(ret.front == 'ε');
        ret.popFront();
        assert(ret.front == 'μ');
    }
    {
        static struct Stringish
        {
            string s;
            alias s this;
        }

        auto orig = Stringish("\U0010fff8 𐁊 foo 𐂓");
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == struct));
        static assert(!is(typeof(bcu) == Stringish) == isAutodecodableString!Stringish);
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == immutable char));
        assert(bcu.front == cast(char) 244);
    }
    {
        static struct WStringish
        {
            wstring s;
            alias s this;
        }

        auto orig = WStringish("\U0010fff8 𐁊 foo 𐂓"w);
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == struct));
        static assert(!is(typeof(bcu) == WStringish) == isAutodecodableString!WStringish);
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == immutable wchar));
        assert(bcu.front == cast(wchar) 56319);
    }
    {
        static struct DStringish
        {
            dstring s;
            alias s this;
        }

        auto orig = DStringish("\U0010fff8 𐁊 foo 𐂓"d);
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == dstring));
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == immutable dchar));
        assert(bcu.front == cast(dchar) 1114104);
    }
    {
        static struct FuncStringish
        {
            string str;
            string s() pure nothrow @nogc { return str; }
            alias s this;
        }

        auto orig = FuncStringish("\U0010fff8 𐁊 foo 𐂓");
        auto bcu = orig.byCodeUnit();
        static if (isAutodecodableString!FuncStringish)
            static assert(is(typeof(bcu) == struct));
        else
            static assert(is(typeof(bcu) == string));
        static assert(!is(typeof(bcu) == FuncStringish));
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == immutable char));
        assert(bcu.front == cast(char) 244);
    }
    {
        static struct Range
        {
            string data;
            bool empty() pure nothrow @nogc { return data.empty; }
            char front() pure nothrow @nogc { return data[0]; }
            void popFront() pure nothrow @nogc { data = data[1 .. $]; }
        }

        auto orig = Range("\U0010fff8 𐁊 foo 𐂓");
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == Range));
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == char));
        assert(bcu.front == cast(char) 244);
    }
    {
        static struct WRange
        {
            wstring data;
            bool empty() pure nothrow @nogc { return data.empty; }
            wchar front() pure nothrow @nogc { return data[0]; }
            void popFront() pure nothrow @nogc { data = data[1 .. $]; }
        }

        auto orig = WRange("\U0010fff8 𐁊 foo 𐂓"w);
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == WRange));
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == wchar));
        assert(bcu.front == 56319);
    }
    {
        static struct DRange
        {
            dstring data;
            bool empty() pure nothrow @nogc { return data.empty; }
            dchar front() pure nothrow @nogc { return data[0]; }
            void popFront() pure nothrow @nogc { data = data[1 .. $]; }
        }

        auto orig = DRange("\U0010fff8 𐁊 foo 𐂓"d);
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == DRange));
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == dchar));
        assert(bcu.front == 1114104);
    }
    {
        static struct RangeAndStringish
        {
            bool empty() pure nothrow @nogc { return data.empty; }
            char front() pure nothrow @nogc { return data[0]; }
            void popFront() pure nothrow @nogc { data = data[1 .. $]; }

            string data;
            string s;
            alias s this;
        }

        auto orig = RangeAndStringish("test.d", "other");
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == RangeAndStringish));
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == char));
        assert(bcu.front == 't');
    }
    {
        static struct WRangeAndStringish
        {
            bool empty() pure nothrow @nogc { return data.empty; }
            wchar front() pure nothrow @nogc { return data[0]; }
            void popFront() pure nothrow @nogc { data = data[1 .. $]; }

            wstring data;
            wstring s;
            alias s this;
        }

        auto orig = WRangeAndStringish("test.d"w, "other"w);
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == WRangeAndStringish));
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == wchar));
        assert(bcu.front == 't');
    }
    {
        static struct DRangeAndStringish
        {
            bool empty() pure nothrow @nogc { return data.empty; }
            dchar front() pure nothrow @nogc { return data[0]; }
            void popFront() pure nothrow @nogc { data = data[1 .. $]; }

            dstring data;
            dstring s;
            alias s this;
        }

        auto orig = DRangeAndStringish("test.d"d, "other"d);
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == DRangeAndStringish));
        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));
        static assert(is(ElementType!(typeof(bcu)) == dchar));
        assert(bcu.front == 't');
    }
    {
        enum Enum : string { a = "test.d" }

        auto orig = Enum.a;
        auto bcu = orig.byCodeUnit();
        static assert(!is(typeof(bcu) == Enum));
        static if (isAutodecodableString!Enum)
            static assert(is(typeof(bcu) == struct));
        else
            static assert(is(typeof(bcu) == string));
        static assert(is(ElementType!(typeof(bcu)) == immutable char));
        assert(bcu.front == 't');
    }
    {
        enum WEnum : wstring { a = "test.d"w }

        auto orig = WEnum.a;
        auto bcu = orig.byCodeUnit();
        static assert(!is(typeof(bcu) == WEnum));
        static if (isAutodecodableString!WEnum)
            static assert(is(typeof(bcu) == struct));
        else
            static assert(is(typeof(bcu) == wstring));
        static assert(is(ElementType!(typeof(bcu)) == immutable wchar));
        assert(bcu.front == 't');
    }
    {
        enum DEnum : dstring { a = "test.d"d }

        auto orig = DEnum.a;
        auto bcu = orig.byCodeUnit();
        static assert(is(typeof(bcu) == dstring));
        static assert(is(ElementType!(typeof(bcu)) == immutable dchar));
        assert(bcu.front == 't');
    }

    static if (autodecodeStrings)
    {
        static assert(!is(typeof(byCodeUnit("hello")) == string));
        static assert(!is(typeof(byCodeUnit("hello"w)) == wstring));
    }
    else
    {
        static assert(is(typeof(byCodeUnit("hello")) == string));
        static assert(is(typeof(byCodeUnit("hello"w)) == wstring));
    }
    static assert(is(typeof(byCodeUnit("hello"d)) == dstring));

    static assert(!__traits(compiles, byCodeUnit((char[5]).init)));
    static assert(!__traits(compiles, byCodeUnit((wchar[5]).init)));
    static assert(!__traits(compiles, byCodeUnit((dchar[5]).init)));

    enum SEnum : char[5] { a = "hello" }
    enum WSEnum : wchar[5] { a = "hello"w }
    enum DSEnum : dchar[5] { a = "hello"d }

    static assert(!__traits(compiles, byCodeUnit(SEnum.a)));
    static assert(!__traits(compiles, byCodeUnit(WSEnum.a)));
    static assert(!__traits(compiles, byCodeUnit(DSEnum.a)));
}

/****************************
 * Iterate an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
 * of characters by char, wchar, or dchar.
 * These aliases simply forward to $(LREF byUTF) with the
 * corresponding C argument.
 *
 * Params:
 *      r = input range of characters, or array of characters
 */
alias byChar = byUTF!char;

/// Ditto
alias byWchar = byUTF!wchar;

/// Ditto
alias byDchar = byUTF!dchar;

@safe pure nothrow @nogc unittest
{
  {
    char[5] s;
    int i;
    foreach (c; "hello".byChar.byChar())
    {
        //writefln("[%d] '%c'", i, c);
        s[i++] = c;
    }
    assert(s == "hello");
  }
  {
    char[5+2+3+4+3+3] s;
    int i;
    dchar[10] a;
    a[0 .. 8] = "hello\u07FF\uD7FF\U0010FFFF"d;
    a[8] = 0xD800;   // invalid
    a[9] = cast(dchar) 0x110000; // invalid
    foreach (c; a[].byChar())
    {
        //writefln("[%d] '%c'", i, c);
        s[i++] = c;
    }
    assert(s == "hello\u07FF\uD7FF\U0010FFFF\uFFFD\uFFFD");
  }
  {
    auto r = "hello"w.byChar();
    r.popFront();
    r.popFront();
    assert(r.front == 'l');
  }
  {
    auto r = "hello"d.byChar();
    r.popFront();
    r.popFront();
    assert(r.front == 'l');
  }
  {
    auto r = "hello"d.byChar();
    assert(isForwardRange!(typeof(r)));
    auto s = r.save;
    r.popFront();
    assert(s.front == 'h');
  }
}

@safe pure nothrow @nogc unittest
{
  {
    wchar[11] s;
    int i;
    dchar[10] a;
    a[0 .. 8] = "hello\u07FF\uD7FF\U0010FFFF"d;
    a[8] = 0xD800;   // invalid
    a[9] = cast(dchar) 0x110000; // invalid
    foreach (c; a[].byWchar())
    {
        //writefln("[%d] '%c' x%x", i, c, c);
        s[i++] = c;
    }
    foreach (j, wchar c; "hello\u07FF\uD7FF\U0010FFFF\uFFFD\uFFFD"w)
    {
        //writefln("[%d] '%c' x%x", j, c, c);
    }
    assert(s == "hello\u07FF\uD7FF\U0010FFFF\uFFFD\uFFFD"w);
  }

  {
    auto r = "hello".byWchar();
    r.popFront();
    r.popFront();
    assert(r.front == 'l');
  }
  {
    auto r = "hello"d.byWchar();
    r.popFront();
    r.popFront();
    assert(r.front == 'l');
  }
  {
    auto r = "hello"d.byWchar();
    assert(isForwardRange!(typeof(r)));
    auto s = r.save;
    r.popFront();
    assert(s.front == 'h');
  }
}

@safe pure nothrow @nogc unittest
{
  {
    dchar[9] s;
    int i;
    string a = "hello\u07FF\uD7FF\U00010000\U0010FFFF"; // 1,2,3,4 byte sequences
    foreach (c; a.byDchar())
    {
        s[i++] = c;
    }
    assert(s == "hello\u07FF\uD7FF\U00010000\U0010FFFF"d);
  }
  {
    foreach (s; invalidUTFstrings!char())
    {
        auto r = s.byDchar();
        assert(!r.empty);
        assert(r.front == r.front);
        dchar c = r.front;
        assert(c == replacementDchar);
    }
  }
  {
    auto r = "hello".byDchar();
    r.popFront();
    r.popFront();
    assert(r.front == 'l');
  }

  {
    dchar[8] s;
    int i;
    wstring a = "hello\u07FF\uD7FF\U0010FFFF"w;
    foreach (c; a.byDchar())
    {
        //writefln("[%d] '%c' x%x", i, c, c);
        s[i++] = c;
    }
    assert(s == "hello\u07FF\uD7FF\U0010FFFF"d);
  }
  {
    foreach (s; invalidUTFstrings!wchar())
    {
        auto r = s.byDchar();
        assert(!r.empty);
        assert(r.front == r.front);
        dchar c = r.front;
        assert(c == replacementDchar);
    }
  }
  {
    wchar[2] ws;
    ws[0] = 0xD800;
    ws[1] = 0xDD00;             // correct surrogate pair
    auto r = ws[].byDchar();
    assert(!r.empty);
    assert(r.front == r.front);
    dchar c = r.front;
    assert(c == '\U00010100');
  }
  {
    auto r = "hello"w.byDchar();
    r.popFront();
    r.popFront();
    assert(r.front == 'l');
  }

  {
    dchar[5] s;
    int i;
    dstring a = "hello"d;
    foreach (c; a.byDchar.byDchar())
    {
        //writefln("[%d] '%c' x%x", i, c, c);
        s[i++] = c;
    }
    assert(s == "hello"d);
  }
  {
    auto r = "hello".byDchar();
    assert(isForwardRange!(typeof(r)));
    auto s = r.save;
    r.popFront();
    assert(s.front == 'h');
  }
  {
    auto r = "hello"w.byDchar();
    assert(isForwardRange!(typeof(r)));
    auto s = r.save;
    r.popFront();
    assert(s.front == 'h');
  }
}

// test pure, @safe, nothrow, @nogc correctness of byChar/byWchar/byDchar,
// which needs to support ranges with and without those attributes

pure @safe nothrow @nogc unittest
{
    dchar[5] s = "hello"d;
    foreach (c; s[].byChar())  { }
    foreach (c; s[].byWchar()) { }
    foreach (c; s[].byDchar()) { }
}

version (StdUnittest)
private int impureVariable;

@system unittest
{
    static struct ImpureThrowingSystemRange(Char)
    {
        @property bool empty() const { return true; }
        @property Char front() const { return Char.init; }
        void popFront()
        {
            impureVariable++;
            throw new Exception("only for testing nothrow");
        }
    }

    foreach (Char; AliasSeq!(char, wchar, dchar))
    {
        ImpureThrowingSystemRange!Char range;
        foreach (c; range.byChar())  { }
        foreach (c; range.byWchar()) { }
        foreach (c; range.byDchar()) { }
    }
}

/****************************
 * Iterate an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
 * of characters by char type `C` by encoding the elements of the range.
 *
 * UTF sequences that cannot be converted to the specified encoding are either
 * replaced by U+FFFD per "5.22 Best Practice for U+FFFD Substitution"
 * of the Unicode Standard 6.2 or result in a thrown UTFException.
 *  Hence byUTF is not symmetric.
 * This algorithm is lazy, and does not allocate memory.
 * `@nogc`, `pure`-ity, `nothrow`, and `@safe`-ty are inferred from the
 * `r` parameter.
 *
 * Params:
 *      C = `char`, `wchar`, or `dchar`
 *      useReplacementDchar = UseReplacementDchar.yes means replace invalid UTF with `replacementDchar`,
 *                            UseReplacementDchar.no means throw `UTFException` for invalid UTF
 *
 * Throws:
 *      `UTFException` if invalid UTF sequence and `useReplacementDchar` is set to `UseReplacementDchar.no`
 *
 * GC:
 *      Does not use GC if `useReplacementDchar` is set to `UseReplacementDchar.yes`
 *
 * Returns:
 *      A bidirectional range if `R` is a bidirectional range and not auto-decodable,
 *      as defined by $(REF isAutodecodableString, std, traits).
 *
 *      A forward range if `R` is a forward range and not auto-decodable.
 *
 *      Or, if `R` is a range and it is auto-decodable and
 *      `is(ElementEncodingType!typeof(r) == C)`, then the range is passed
 *      to $(LREF byCodeUnit).
 *
 *      Otherwise, an input range of characters.
 */
template byUTF(C, UseReplacementDchar useReplacementDchar = Yes.useReplacementDchar)
if (isSomeChar!C)
{
    static if (is(immutable C == immutable UC, UC) && !is(C == UC))
        alias byUTF = byUTF!UC;
    else:

    auto ref byUTF(R)(R r)
    if (isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
    {
        return byUTF(r.byCodeUnit());
    }

    auto ref byUTF(R)(R r)
    if (!isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
    {
        static if (is(immutable ElementEncodingType!R == immutable RC, RC) && is(RC == C))
        {
            return r.byCodeUnit();
        }
        else static if (is(C == dchar))
        {
            static struct Result
            {
                enum Empty = uint.max;  // range is empty or just constructed

                this(return scope R r)
                {
                    this.r = r;
                }

                this(return scope R r, uint buff)
                {
                    this.r = r;
                    this.buff = buff;
                }

                static if (isBidirectionalRange!R)
                {
                    this(return scope R r, uint frontBuff, uint backBuff)
                    {
                        this.r = r;
                        this.buff = frontBuff;
                        this.backBuff = backBuff;
                    }
                }

                @property bool empty()
                {
                    static if (isBidirectionalRange!R)
                        return buff == Empty && backBuff == Empty && r.empty;
                    else
                        return buff == Empty && r.empty;
                }

                @property dchar front() scope // 'scope' required by call to decodeFront() below
                {
                    if (buff == Empty)
                    {
                        auto c = r.front;

                        static if (is(RC == wchar))
                            enum firstMulti = 0xD800; // First high surrogate.
                        else
                            enum firstMulti = 0x80; // First non-ASCII.
                        if (c < firstMulti)
                        {
                            r.popFront;
                            buff = cast(dchar) c;
                        }
                        else
                        {
                            buff = () @trusted { return decodeFront!(useReplacementDchar)(r); }();
                        }
                    }
                    return cast(dchar) buff;
                }

                void popFront()
                {
                    if (buff == Empty)
                        front();
                    buff = Empty;
                }

                static if (isForwardRange!R)
                {
                    @property auto save()
                    {
                        static if (isBidirectionalRange!R)
                        {
                            return Result(r.save, buff, backBuff);
                        }
                        else
                        {
                            return Result(r.save, buff);
                        }
                    }
                }

                static if (isBidirectionalRange!R)
                {
                    @property dchar back() scope // 'scope' required by call to decodeBack() below
                    {
                        if (backBuff != Empty)
                            return cast(dchar) backBuff;

                        auto c = r.back;
                        static if (is(RC == wchar))
                            enum firstMulti = 0xD800; // First high surrogate.
                        else
                            enum firstMulti = 0x80; // First non-ASCII.
                        if (c < firstMulti)
                        {
                            r.popBack;
                            backBuff = cast(dchar) c;
                        }
                        else
                        {
                            backBuff = () @trusted { return decodeBack!useReplacementDchar(r); }();
                        }
                        return cast(dchar) backBuff;

                    }

                    void popBack()
                    {
                        if (backBuff == Empty)
                            back();
                        backBuff = Empty;
                    }
                }

            private:

                R r;
                uint buff = Empty;      // one character lookahead buffer
                static if (isBidirectionalRange!R)
                    uint backBuff = Empty;
            }

            return Result(r);
        }
        else
        {
            static struct Result
            {
                this(return scope R r)
                {
                    this.r = r;
                }

                this(return scope R r, ushort pos, ushort fill, C[4 / C.sizeof] buf)
                {
                    this.r = r;
                    this.pos = pos;
                    this.fill = fill;
                    this.buf = buf;
                }

                static if (isBidirectionalRange!R)
                {
                    this(return scope R r, ushort frontPos, ushort frontFill,
                         ushort backPos, ushort backFill, C[4 / C.sizeof] buf)
                    {
                        this.r = r;
                        this.pos = frontPos;
                        this.fill = frontFill;
                        this.backPos = backPos;
                        this.backFill = backFill;
                        this.buf = buf;
                    }
                }

                @property bool empty()
                {
                    static if (isBidirectionalRange!R)
                        return pos == fill && backPos == backFill && r.empty;
                    else
                        return pos == fill && r.empty;
                }

                @property auto front() scope // 'scope' required by call to decodeFront() below
                {
                    if (pos == fill)
                    {
                        pos = 0;
                        auto c = r.front;

                        static if (C.sizeof >= 2 && RC.sizeof >= 2)
                            enum firstMulti = 0xD800; // First high surrogate.
                        else
                            enum firstMulti = 0x80; // First non-ASCII.
                        if (c < firstMulti)
                        {
                            fill = 1;
                            r.popFront;
                            buf[pos] = cast(C) c;
                        }
                        else
                        {
                            static if (is(RC == dchar))
                            {
                                r.popFront;
                                dchar dc = c;
                            }
                            else
                                dchar dc = () @trusted { return decodeFront!(useReplacementDchar)(r); }();
                            fill = cast(ushort) encode!(useReplacementDchar)(buf, dc);
                        }
                    }
                    return buf[pos];
                }

                void popFront()
                {
                    if (pos == fill)
                        front;
                    ++pos;
                }

                static if (isForwardRange!R)
                {
                    @property auto save()
                    {
                        static if (isBidirectionalRange!R)
                        {
                            return Result(r.save, pos, fill, backPos, backFill, buf);
                        }
                        else
                        {
                            return Result(r.save, pos, fill, buf);
                        }
                    }
                }

                static if (isBidirectionalRange!R)
                {
                    @property auto back() scope // 'scope' required by call to decodeBack() below
                    {
                        if (backPos != backFill)
                            return buf[cast(ushort) (backFill - backPos - 1)];

                        backPos = 0;
                        auto c = r.back;
                        static if (C.sizeof >= 2 && RC.sizeof >= 2)
                            enum firstMulti = 0xD800; // First high surrogate.
                        else
                            enum firstMulti = 0x80; // First non-ASCII.
                        if (c < firstMulti)
                        {
                            backFill = 1;
                            r.popBack;
                            buf[cast(ushort) (backFill - backPos - 1)] = cast(C) c;
                        }
                        else
                        {
                            static if (is(RC == dchar))
                            {
                                r.popBack;
                                dchar dc = c;
                            }
                            else
                                dchar dc = () @trusted { return decodeBack!(useReplacementDchar)(r); }();
                            backFill = cast(ushort) encode!(useReplacementDchar)(buf, dc);
                        }
                        return buf[cast(ushort) (backFill - backPos - 1)];
                    }

                    void popBack()
                    {
                        if (backPos == backFill)
                            back;
                        ++backPos;
                    }
                }

            private:

                R r;
                ushort pos, fill;
                static if (isBidirectionalRange!R)
                    ushort backPos, backFill;
                C[4 / C.sizeof] buf = void;
            }

            return Result(r);
        }
    }
}

///
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;

    // hellö as a range of `char`s, which are UTF-8
    assert("hell\u00F6".byUTF!char().equal(['h', 'e', 'l', 'l', 0xC3, 0xB6]));

    // `wchar`s are able to hold the ö in a single element (UTF-16 code unit)
    assert("hell\u00F6".byUTF!wchar().equal(['h', 'e', 'l', 'l', 'ö']));

    // 𐐷 is four code units in UTF-8, two in UTF-16, and one in UTF-32
    assert("𐐷".byUTF!char().equal([0xF0, 0x90, 0x90, 0xB7]));
    assert("𐐷".byUTF!wchar().equal([0xD801, 0xDC37]));
    assert("𐐷".byUTF!dchar().equal([0x00010437]));
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.exception : assertThrown;

    assert("hello\xF0betty".byChar.byUTF!(dchar, UseReplacementDchar.yes).equal("hello\uFFFDetty"));
    assertThrown!UTFException("hello\xF0betty".byChar.byUTF!(dchar, UseReplacementDchar.no).equal("hello betty"));
}

@safe unittest
{
    {
        wchar[] s = ['a', 'b', 0x219];
        auto r = s.byUTF!char;
        assert(isBidirectionalRange!(typeof(r)));
        assert(r.back == 0x99);
        r.popBack;
        assert(r.back == 0xc8);
        r.popBack;
        assert(r.back == 'b');

    }

    {
        wchar[] s = ['a', 'b', 0x219];
        auto r = s.byUTF!wchar;
        uint i;
        assert(isBidirectionalRange!(typeof(r)));
        assert(r.back == 0x219);
        r.popBack;
        assert(r.back == 'b');
    }

    {
        wchar[] s = ['a', 'b', 0x219];
        auto r = s.byUTF!dchar;
        assert(isBidirectionalRange!(typeof(r)));
        assert(r.back == 0x219);
        r.popBack;
        assert(r.back == 'b');
    }

    {
        dchar[] s = ['𐐷', '😁'];
        auto r = s.byUTF!wchar;
        assert(r.back == 0xde01);
        r.popBack;
        assert(r.back == 0xd83d);
        r.popBack;
        assert(r.back == 0xdc37);
        r.popBack;
        assert(r.back == 0xd801);
    }

    {
        dchar[] s = ['𐐷', '😁'];
        auto r = s.byUTF!char;
        char[] res;
        while (!r.empty)
        {
            res ~= r.back;
            r.popBack;
        }
        import std.algorithm.comparison : equal;
        assert(res.equal([0x81, 0x98, 0x9f, 0xf0, 0xb7, 0x90, 0x90, 0xf0]));
    }

    {
        dchar[] res;
        auto r = ['a', 'b', 'c', 'd', 'e'].byUTF!dchar;
        while (!r.empty)
        {
            res ~= r.back;
            r.popBack;
        }
        import std.algorithm.comparison : equal;
        assert(res.equal(['e', 'd', 'c', 'b', 'a']));
    }

    {
        //testing the save() function
        wchar[] s = ['Ă','ț'];

        auto rc = s.byUTF!char;
        rc.popBack;
        auto rcCopy = rc.save;
        assert(rc.back == rcCopy.back);
        assert(rcCopy.back == 0xc8);

        auto rd = s.byUTF!dchar;
        rd.popBack;
        auto rdCopy = rd.save;
        assert(rd.back == rdCopy.back);
        assert(rdCopy.back == 'Ă');
    }
}

///
@safe pure nothrow unittest
{
    import std.range.primitives;
    wchar[] s = ['ă', 'î'];

    auto rc = s.byUTF!char;
    static assert(isBidirectionalRange!(typeof(rc)));
    assert(rc.back == 0xae);
    rc.popBack;
    assert(rc.back == 0xc3);
    rc.popBack;
    assert(rc.back == 0x83);
    rc.popBack;
    assert(rc.back == 0xc4);

    auto rw = s.byUTF!wchar;
    static assert(isBidirectionalRange!(typeof(rw)));
    assert(rw.back == 'î');
    rw.popBack;
    assert(rw.back == 'ă');

    auto rd = s.byUTF!dchar;
    static assert(isBidirectionalRange!(typeof(rd)));
    assert(rd.back == 'î');
    rd.popBack;
    assert(rd.back == 'ă');
}
