text:
// Warning! This file is autogenerated.
#include <boost/text/bidirectional.hpp>

#include "bidi_tests.hpp"

#include <gtest/gtest.h>

#include <algorithm>

std::vector<int> expected_levels;
std::vector<int> expected_reordered_indices;

TEST(bidi, bidi_891_000)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // CS ET RLI EN; 4 ('RTL') (line 445501)
        std::vector<uint32_t> const cps = { 0x002C, 0x0023, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS ET RLI AN; 4 ('RTL') (line 445502)
        std::vector<uint32_t> const cps = { 0x002C, 0x0023, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS ET FSI AN; 4 ('RTL') (line 445503)
        std::vector<uint32_t> const cps = { 0x002C, 0x0023, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS CS LRI AN; 4 ('RTL') (line 445504)
        std::vector<uint32_t> const cps = { 0x002C, 0x002C, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS CS RLI L; 4 ('RTL') (line 445505)
        std::vector<uint32_t> const cps = { 0x002C, 0x002C, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS CS RLI EN; 4 ('RTL') (line 445506)
        std::vector<uint32_t> const cps = { 0x002C, 0x002C, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS CS RLI AN; 4 ('RTL') (line 445507)
        std::vector<uint32_t> const cps = { 0x002C, 0x002C, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS CS FSI AN; 4 ('RTL') (line 445508)
        std::vector<uint32_t> const cps = { 0x002C, 0x002C, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS NSM LRI AN; 4 ('RTL') (line 445509)
        std::vector<uint32_t> const cps = { 0x002C, 0x0300, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS NSM RLI L; 4 ('RTL') (line 445510)
        std::vector<uint32_t> const cps = { 0x002C, 0x0300, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_001)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // CS NSM RLI EN; 4 ('RTL') (line 445511)
        std::vector<uint32_t> const cps = { 0x002C, 0x0300, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS NSM RLI AN; 4 ('RTL') (line 445512)
        std::vector<uint32_t> const cps = { 0x002C, 0x0300, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS NSM FSI AN; 4 ('RTL') (line 445513)
        std::vector<uint32_t> const cps = { 0x002C, 0x0300, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS S LRI AN; 4 ('RTL') (line 445514)
        std::vector<uint32_t> const cps = { 0x002C, 0x0009, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS S RLI L; 4 ('RTL') (line 445515)
        std::vector<uint32_t> const cps = { 0x002C, 0x0009, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS S RLI EN; 4 ('RTL') (line 445516)
        std::vector<uint32_t> const cps = { 0x002C, 0x0009, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS S RLI AN; 4 ('RTL') (line 445517)
        std::vector<uint32_t> const cps = { 0x002C, 0x0009, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS S FSI AN; 4 ('RTL') (line 445518)
        std::vector<uint32_t> const cps = { 0x002C, 0x0009, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS WS LRI AN; 4 ('RTL') (line 445519)
        std::vector<uint32_t> const cps = { 0x002C, 0x0020, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS WS RLI L; 4 ('RTL') (line 445520)
        std::vector<uint32_t> const cps = { 0x002C, 0x0020, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_002)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // CS WS RLI EN; 4 ('RTL') (line 445521)
        std::vector<uint32_t> const cps = { 0x002C, 0x0020, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS WS RLI AN; 4 ('RTL') (line 445522)
        std::vector<uint32_t> const cps = { 0x002C, 0x0020, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS WS FSI AN; 4 ('RTL') (line 445523)
        std::vector<uint32_t> const cps = { 0x002C, 0x0020, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS ON LRI AN; 4 ('RTL') (line 445524)
        std::vector<uint32_t> const cps = { 0x002C, 0x0021, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS ON RLI L; 4 ('RTL') (line 445525)
        std::vector<uint32_t> const cps = { 0x002C, 0x0021, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS ON RLI EN; 4 ('RTL') (line 445526)
        std::vector<uint32_t> const cps = { 0x002C, 0x0021, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS ON RLI AN; 4 ('RTL') (line 445527)
        std::vector<uint32_t> const cps = { 0x002C, 0x0021, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS ON FSI AN; 4 ('RTL') (line 445528)
        std::vector<uint32_t> const cps = { 0x002C, 0x0021, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS LRI S AN; 4 ('RTL') (line 445529)
        std::vector<uint32_t> const cps = { 0x002C, 0x2066, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS RLI S L; 4 ('RTL') (line 445530)
        std::vector<uint32_t> const cps = { 0x002C, 0x2067, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_003)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // CS RLI S EN; 4 ('RTL') (line 445531)
        std::vector<uint32_t> const cps = { 0x002C, 0x2067, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS RLI S AN; 4 ('RTL') (line 445532)
        std::vector<uint32_t> const cps = { 0x002C, 0x2067, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS FSI S AN; 4 ('RTL') (line 445533)
        std::vector<uint32_t> const cps = { 0x002C, 0x2068, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS PDI LRI AN; 4 ('RTL') (line 445534)
        std::vector<uint32_t> const cps = { 0x002C, 0x2069, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS PDI RLI L; 4 ('RTL') (line 445535)
        std::vector<uint32_t> const cps = { 0x002C, 0x2069, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS PDI RLI EN; 4 ('RTL') (line 445536)
        std::vector<uint32_t> const cps = { 0x002C, 0x2069, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS PDI RLI AN; 4 ('RTL') (line 445537)
        std::vector<uint32_t> const cps = { 0x002C, 0x2069, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // CS PDI FSI AN; 4 ('RTL') (line 445538)
        std::vector<uint32_t> const cps = { 0x002C, 0x2069, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM R LRI AN; 5 ('auto') (line 445539)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM R LRI AN; 5 ('RTL') (line 445539)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM R RLI L; 5 ('auto') (line 445540)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM R RLI L; 5 ('RTL') (line 445540)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_004)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // NSM R RLI EN; 5 ('auto') (line 445541)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM R RLI EN; 5 ('RTL') (line 445541)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM R RLI AN; 5 ('auto') (line 445542)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM R RLI AN; 5 ('RTL') (line 445542)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM R FSI AN; 5 ('auto') (line 445543)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM R FSI AN; 5 ('RTL') (line 445543)
        std::vector<uint32_t> const cps = { 0x0300, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL LRI AN; 5 ('auto') (line 445544)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL LRI AN; 5 ('RTL') (line 445544)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL RLI L; 5 ('auto') (line 445545)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL RLI L; 5 ('RTL') (line 445545)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL RLI EN; 5 ('auto') (line 445546)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL RLI EN; 5 ('RTL') (line 445546)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL RLI AN; 5 ('auto') (line 445547)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL RLI AN; 5 ('RTL') (line 445547)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL FSI AN; 5 ('auto') (line 445548)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM AL FSI AN; 5 ('RTL') (line 445548)
        std::vector<uint32_t> const cps = { 0x0300, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ES LRI AN; 4 ('RTL') (line 445549)
        std::vector<uint32_t> const cps = { 0x0300, 0x002B, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ES RLI L; 4 ('RTL') (line 445550)
        std::vector<uint32_t> const cps = { 0x0300, 0x002B, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_005)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // NSM ES RLI EN; 4 ('RTL') (line 445551)
        std::vector<uint32_t> const cps = { 0x0300, 0x002B, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ES RLI AN; 4 ('RTL') (line 445552)
        std::vector<uint32_t> const cps = { 0x0300, 0x002B, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ES FSI AN; 4 ('RTL') (line 445553)
        std::vector<uint32_t> const cps = { 0x0300, 0x002B, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ET LRI AN; 4 ('RTL') (line 445554)
        std::vector<uint32_t> const cps = { 0x0300, 0x0023, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ET RLI L; 4 ('RTL') (line 445555)
        std::vector<uint32_t> const cps = { 0x0300, 0x0023, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ET RLI EN; 4 ('RTL') (line 445556)
        std::vector<uint32_t> const cps = { 0x0300, 0x0023, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ET RLI AN; 4 ('RTL') (line 445557)
        std::vector<uint32_t> const cps = { 0x0300, 0x0023, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ET FSI AN; 4 ('RTL') (line 445558)
        std::vector<uint32_t> const cps = { 0x0300, 0x0023, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM CS LRI AN; 4 ('RTL') (line 445559)
        std::vector<uint32_t> const cps = { 0x0300, 0x002C, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM CS RLI L; 4 ('RTL') (line 445560)
        std::vector<uint32_t> const cps = { 0x0300, 0x002C, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_006)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // NSM CS RLI EN; 4 ('RTL') (line 445561)
        std::vector<uint32_t> const cps = { 0x0300, 0x002C, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM CS RLI AN; 4 ('RTL') (line 445562)
        std::vector<uint32_t> const cps = { 0x0300, 0x002C, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM CS FSI AN; 4 ('RTL') (line 445563)
        std::vector<uint32_t> const cps = { 0x0300, 0x002C, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM NSM LRI AN; 4 ('RTL') (line 445564)
        std::vector<uint32_t> const cps = { 0x0300, 0x0300, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM NSM RLI L; 4 ('RTL') (line 445565)
        std::vector<uint32_t> const cps = { 0x0300, 0x0300, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM NSM RLI EN; 4 ('RTL') (line 445566)
        std::vector<uint32_t> const cps = { 0x0300, 0x0300, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM NSM RLI AN; 4 ('RTL') (line 445567)
        std::vector<uint32_t> const cps = { 0x0300, 0x0300, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM NSM FSI AN; 4 ('RTL') (line 445568)
        std::vector<uint32_t> const cps = { 0x0300, 0x0300, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM S LRI AN; 4 ('RTL') (line 445569)
        std::vector<uint32_t> const cps = { 0x0300, 0x0009, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM S RLI L; 4 ('RTL') (line 445570)
        std::vector<uint32_t> const cps = { 0x0300, 0x0009, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_007)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // NSM S RLI EN; 4 ('RTL') (line 445571)
        std::vector<uint32_t> const cps = { 0x0300, 0x0009, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM S RLI AN; 4 ('RTL') (line 445572)
        std::vector<uint32_t> const cps = { 0x0300, 0x0009, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM S FSI AN; 4 ('RTL') (line 445573)
        std::vector<uint32_t> const cps = { 0x0300, 0x0009, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM WS LRI AN; 4 ('RTL') (line 445574)
        std::vector<uint32_t> const cps = { 0x0300, 0x0020, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM WS RLI L; 4 ('RTL') (line 445575)
        std::vector<uint32_t> const cps = { 0x0300, 0x0020, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM WS RLI EN; 4 ('RTL') (line 445576)
        std::vector<uint32_t> const cps = { 0x0300, 0x0020, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM WS RLI AN; 4 ('RTL') (line 445577)
        std::vector<uint32_t> const cps = { 0x0300, 0x0020, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM WS FSI AN; 4 ('RTL') (line 445578)
        std::vector<uint32_t> const cps = { 0x0300, 0x0020, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ON LRI AN; 4 ('RTL') (line 445579)
        std::vector<uint32_t> const cps = { 0x0300, 0x0021, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ON RLI L; 4 ('RTL') (line 445580)
        std::vector<uint32_t> const cps = { 0x0300, 0x0021, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_008)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // NSM ON RLI EN; 4 ('RTL') (line 445581)
        std::vector<uint32_t> const cps = { 0x0300, 0x0021, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ON RLI AN; 4 ('RTL') (line 445582)
        std::vector<uint32_t> const cps = { 0x0300, 0x0021, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM ON FSI AN; 4 ('RTL') (line 445583)
        std::vector<uint32_t> const cps = { 0x0300, 0x0021, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM LRI S AN; 4 ('RTL') (line 445584)
        std::vector<uint32_t> const cps = { 0x0300, 0x2066, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM RLI S L; 4 ('RTL') (line 445585)
        std::vector<uint32_t> const cps = { 0x0300, 0x2067, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM RLI S EN; 4 ('RTL') (line 445586)
        std::vector<uint32_t> const cps = { 0x0300, 0x2067, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM RLI S AN; 4 ('RTL') (line 445587)
        std::vector<uint32_t> const cps = { 0x0300, 0x2067, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM FSI S AN; 4 ('RTL') (line 445588)
        std::vector<uint32_t> const cps = { 0x0300, 0x2068, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM PDI LRI AN; 4 ('RTL') (line 445589)
        std::vector<uint32_t> const cps = { 0x0300, 0x2069, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM PDI RLI L; 4 ('RTL') (line 445590)
        std::vector<uint32_t> const cps = { 0x0300, 0x2069, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_009)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // NSM PDI RLI EN; 4 ('RTL') (line 445591)
        std::vector<uint32_t> const cps = { 0x0300, 0x2069, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM PDI RLI AN; 4 ('RTL') (line 445592)
        std::vector<uint32_t> const cps = { 0x0300, 0x2069, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // NSM PDI FSI AN; 4 ('RTL') (line 445593)
        std::vector<uint32_t> const cps = { 0x0300, 0x2069, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R LRI AN; 5 ('auto') (line 445594)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R LRI AN; 5 ('RTL') (line 445594)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R RLI L; 5 ('auto') (line 445595)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R RLI L; 5 ('RTL') (line 445595)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R RLI EN; 5 ('auto') (line 445596)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R RLI EN; 5 ('RTL') (line 445596)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R RLI AN; 5 ('auto') (line 445597)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R RLI AN; 5 ('RTL') (line 445597)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R FSI AN; 5 ('auto') (line 445598)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S R FSI AN; 5 ('RTL') (line 445598)
        std::vector<uint32_t> const cps = { 0x0009, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S AL LRI AN; 5 ('auto') (line 445599)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S AL LRI AN; 5 ('RTL') (line 445599)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S AL RLI L; 5 ('auto') (line 445600)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S AL RLI L; 5 ('RTL') (line 445600)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_010)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // S AL RLI EN; 5 ('auto') (line 445601)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S AL RLI EN; 5 ('RTL') (line 445601)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S AL RLI AN; 5 ('auto') (line 445602)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S AL RLI AN; 5 ('RTL') (line 445602)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S AL FSI AN; 5 ('auto') (line 445603)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S AL FSI AN; 5 ('RTL') (line 445603)
        std::vector<uint32_t> const cps = { 0x0009, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ES LRI AN; 4 ('RTL') (line 445604)
        std::vector<uint32_t> const cps = { 0x0009, 0x002B, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ES RLI L; 4 ('RTL') (line 445605)
        std::vector<uint32_t> const cps = { 0x0009, 0x002B, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ES RLI EN; 4 ('RTL') (line 445606)
        std::vector<uint32_t> const cps = { 0x0009, 0x002B, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ES RLI AN; 4 ('RTL') (line 445607)
        std::vector<uint32_t> const cps = { 0x0009, 0x002B, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ES FSI AN; 4 ('RTL') (line 445608)
        std::vector<uint32_t> const cps = { 0x0009, 0x002B, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ET LRI AN; 4 ('RTL') (line 445609)
        std::vector<uint32_t> const cps = { 0x0009, 0x0023, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ET RLI L; 4 ('RTL') (line 445610)
        std::vector<uint32_t> const cps = { 0x0009, 0x0023, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_011)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // S ET RLI EN; 4 ('RTL') (line 445611)
        std::vector<uint32_t> const cps = { 0x0009, 0x0023, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ET RLI AN; 4 ('RTL') (line 445612)
        std::vector<uint32_t> const cps = { 0x0009, 0x0023, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ET FSI AN; 4 ('RTL') (line 445613)
        std::vector<uint32_t> const cps = { 0x0009, 0x0023, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S CS LRI AN; 4 ('RTL') (line 445614)
        std::vector<uint32_t> const cps = { 0x0009, 0x002C, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S CS RLI L; 4 ('RTL') (line 445615)
        std::vector<uint32_t> const cps = { 0x0009, 0x002C, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S CS RLI EN; 4 ('RTL') (line 445616)
        std::vector<uint32_t> const cps = { 0x0009, 0x002C, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S CS RLI AN; 4 ('RTL') (line 445617)
        std::vector<uint32_t> const cps = { 0x0009, 0x002C, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S CS FSI AN; 4 ('RTL') (line 445618)
        std::vector<uint32_t> const cps = { 0x0009, 0x002C, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S NSM LRI AN; 4 ('RTL') (line 445619)
        std::vector<uint32_t> const cps = { 0x0009, 0x0300, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S NSM RLI L; 4 ('RTL') (line 445620)
        std::vector<uint32_t> const cps = { 0x0009, 0x0300, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_012)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // S NSM RLI EN; 4 ('RTL') (line 445621)
        std::vector<uint32_t> const cps = { 0x0009, 0x0300, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S NSM RLI AN; 4 ('RTL') (line 445622)
        std::vector<uint32_t> const cps = { 0x0009, 0x0300, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S NSM FSI AN; 4 ('RTL') (line 445623)
        std::vector<uint32_t> const cps = { 0x0009, 0x0300, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S S LRI AN; 4 ('RTL') (line 445624)
        std::vector<uint32_t> const cps = { 0x0009, 0x0009, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S S RLI L; 4 ('RTL') (line 445625)
        std::vector<uint32_t> const cps = { 0x0009, 0x0009, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S S RLI EN; 4 ('RTL') (line 445626)
        std::vector<uint32_t> const cps = { 0x0009, 0x0009, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S S RLI AN; 4 ('RTL') (line 445627)
        std::vector<uint32_t> const cps = { 0x0009, 0x0009, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S S FSI AN; 4 ('RTL') (line 445628)
        std::vector<uint32_t> const cps = { 0x0009, 0x0009, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S WS LRI AN; 4 ('RTL') (line 445629)
        std::vector<uint32_t> const cps = { 0x0009, 0x0020, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S WS RLI L; 4 ('RTL') (line 445630)
        std::vector<uint32_t> const cps = { 0x0009, 0x0020, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_013)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // S WS RLI EN; 4 ('RTL') (line 445631)
        std::vector<uint32_t> const cps = { 0x0009, 0x0020, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S WS RLI AN; 4 ('RTL') (line 445632)
        std::vector<uint32_t> const cps = { 0x0009, 0x0020, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S WS FSI AN; 4 ('RTL') (line 445633)
        std::vector<uint32_t> const cps = { 0x0009, 0x0020, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ON LRI AN; 4 ('RTL') (line 445634)
        std::vector<uint32_t> const cps = { 0x0009, 0x0021, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ON RLI L; 4 ('RTL') (line 445635)
        std::vector<uint32_t> const cps = { 0x0009, 0x0021, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ON RLI EN; 4 ('RTL') (line 445636)
        std::vector<uint32_t> const cps = { 0x0009, 0x0021, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ON RLI AN; 4 ('RTL') (line 445637)
        std::vector<uint32_t> const cps = { 0x0009, 0x0021, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S ON FSI AN; 4 ('RTL') (line 445638)
        std::vector<uint32_t> const cps = { 0x0009, 0x0021, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S LRI S AN; 4 ('RTL') (line 445639)
        std::vector<uint32_t> const cps = { 0x0009, 0x2066, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S RLI S L; 4 ('RTL') (line 445640)
        std::vector<uint32_t> const cps = { 0x0009, 0x2067, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_014)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // S RLI S EN; 4 ('RTL') (line 445641)
        std::vector<uint32_t> const cps = { 0x0009, 0x2067, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S RLI S AN; 4 ('RTL') (line 445642)
        std::vector<uint32_t> const cps = { 0x0009, 0x2067, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S FSI S AN; 4 ('RTL') (line 445643)
        std::vector<uint32_t> const cps = { 0x0009, 0x2068, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S PDI LRI AN; 4 ('RTL') (line 445644)
        std::vector<uint32_t> const cps = { 0x0009, 0x2069, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S PDI RLI L; 4 ('RTL') (line 445645)
        std::vector<uint32_t> const cps = { 0x0009, 0x2069, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S PDI RLI EN; 4 ('RTL') (line 445646)
        std::vector<uint32_t> const cps = { 0x0009, 0x2069, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S PDI RLI AN; 4 ('RTL') (line 445647)
        std::vector<uint32_t> const cps = { 0x0009, 0x2069, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // S PDI FSI AN; 4 ('RTL') (line 445648)
        std::vector<uint32_t> const cps = { 0x0009, 0x2069, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS R LRI AN; 5 ('auto') (line 445649)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS R LRI AN; 5 ('RTL') (line 445649)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS R RLI L; 5 ('auto') (line 445650)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS R RLI L; 5 ('RTL') (line 445650)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_015)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // WS R RLI EN; 5 ('auto') (line 445651)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS R RLI EN; 5 ('RTL') (line 445651)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS R RLI AN; 5 ('auto') (line 445652)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS R RLI AN; 5 ('RTL') (line 445652)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS R FSI AN; 5 ('auto') (line 445653)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS R FSI AN; 5 ('RTL') (line 445653)
        std::vector<uint32_t> const cps = { 0x0020, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL LRI AN; 5 ('auto') (line 445654)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL LRI AN; 5 ('RTL') (line 445654)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL RLI L; 5 ('auto') (line 445655)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL RLI L; 5 ('RTL') (line 445655)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL RLI EN; 5 ('auto') (line 445656)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL RLI EN; 5 ('RTL') (line 445656)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL RLI AN; 5 ('auto') (line 445657)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL RLI AN; 5 ('RTL') (line 445657)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL FSI AN; 5 ('auto') (line 445658)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS AL FSI AN; 5 ('RTL') (line 445658)
        std::vector<uint32_t> const cps = { 0x0020, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ES LRI AN; 4 ('RTL') (line 445659)
        std::vector<uint32_t> const cps = { 0x0020, 0x002B, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ES RLI L; 4 ('RTL') (line 445660)
        std::vector<uint32_t> const cps = { 0x0020, 0x002B, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_016)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // WS ES RLI EN; 4 ('RTL') (line 445661)
        std::vector<uint32_t> const cps = { 0x0020, 0x002B, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ES RLI AN; 4 ('RTL') (line 445662)
        std::vector<uint32_t> const cps = { 0x0020, 0x002B, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ES FSI AN; 4 ('RTL') (line 445663)
        std::vector<uint32_t> const cps = { 0x0020, 0x002B, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ET LRI AN; 4 ('RTL') (line 445664)
        std::vector<uint32_t> const cps = { 0x0020, 0x0023, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ET RLI L; 4 ('RTL') (line 445665)
        std::vector<uint32_t> const cps = { 0x0020, 0x0023, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ET RLI EN; 4 ('RTL') (line 445666)
        std::vector<uint32_t> const cps = { 0x0020, 0x0023, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ET RLI AN; 4 ('RTL') (line 445667)
        std::vector<uint32_t> const cps = { 0x0020, 0x0023, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ET FSI AN; 4 ('RTL') (line 445668)
        std::vector<uint32_t> const cps = { 0x0020, 0x0023, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS CS LRI AN; 4 ('RTL') (line 445669)
        std::vector<uint32_t> const cps = { 0x0020, 0x002C, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS CS RLI L; 4 ('RTL') (line 445670)
        std::vector<uint32_t> const cps = { 0x0020, 0x002C, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_017)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // WS CS RLI EN; 4 ('RTL') (line 445671)
        std::vector<uint32_t> const cps = { 0x0020, 0x002C, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS CS RLI AN; 4 ('RTL') (line 445672)
        std::vector<uint32_t> const cps = { 0x0020, 0x002C, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS CS FSI AN; 4 ('RTL') (line 445673)
        std::vector<uint32_t> const cps = { 0x0020, 0x002C, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS NSM LRI AN; 4 ('RTL') (line 445674)
        std::vector<uint32_t> const cps = { 0x0020, 0x0300, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS NSM RLI L; 4 ('RTL') (line 445675)
        std::vector<uint32_t> const cps = { 0x0020, 0x0300, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS NSM RLI EN; 4 ('RTL') (line 445676)
        std::vector<uint32_t> const cps = { 0x0020, 0x0300, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS NSM RLI AN; 4 ('RTL') (line 445677)
        std::vector<uint32_t> const cps = { 0x0020, 0x0300, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS NSM FSI AN; 4 ('RTL') (line 445678)
        std::vector<uint32_t> const cps = { 0x0020, 0x0300, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS S LRI AN; 4 ('RTL') (line 445679)
        std::vector<uint32_t> const cps = { 0x0020, 0x0009, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS S RLI L; 4 ('RTL') (line 445680)
        std::vector<uint32_t> const cps = { 0x0020, 0x0009, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_018)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // WS S RLI EN; 4 ('RTL') (line 445681)
        std::vector<uint32_t> const cps = { 0x0020, 0x0009, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS S RLI AN; 4 ('RTL') (line 445682)
        std::vector<uint32_t> const cps = { 0x0020, 0x0009, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS S FSI AN; 4 ('RTL') (line 445683)
        std::vector<uint32_t> const cps = { 0x0020, 0x0009, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS WS LRI AN; 4 ('RTL') (line 445684)
        std::vector<uint32_t> const cps = { 0x0020, 0x0020, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS WS RLI L; 4 ('RTL') (line 445685)
        std::vector<uint32_t> const cps = { 0x0020, 0x0020, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS WS RLI EN; 4 ('RTL') (line 445686)
        std::vector<uint32_t> const cps = { 0x0020, 0x0020, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS WS RLI AN; 4 ('RTL') (line 445687)
        std::vector<uint32_t> const cps = { 0x0020, 0x0020, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS WS FSI AN; 4 ('RTL') (line 445688)
        std::vector<uint32_t> const cps = { 0x0020, 0x0020, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ON LRI AN; 4 ('RTL') (line 445689)
        std::vector<uint32_t> const cps = { 0x0020, 0x0021, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ON RLI L; 4 ('RTL') (line 445690)
        std::vector<uint32_t> const cps = { 0x0020, 0x0021, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_019)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // WS ON RLI EN; 4 ('RTL') (line 445691)
        std::vector<uint32_t> const cps = { 0x0020, 0x0021, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ON RLI AN; 4 ('RTL') (line 445692)
        std::vector<uint32_t> const cps = { 0x0020, 0x0021, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS ON FSI AN; 4 ('RTL') (line 445693)
        std::vector<uint32_t> const cps = { 0x0020, 0x0021, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS LRI S AN; 4 ('RTL') (line 445694)
        std::vector<uint32_t> const cps = { 0x0020, 0x2066, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS RLI S L; 4 ('RTL') (line 445695)
        std::vector<uint32_t> const cps = { 0x0020, 0x2067, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS RLI S EN; 4 ('RTL') (line 445696)
        std::vector<uint32_t> const cps = { 0x0020, 0x2067, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS RLI S AN; 4 ('RTL') (line 445697)
        std::vector<uint32_t> const cps = { 0x0020, 0x2067, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS FSI S AN; 4 ('RTL') (line 445698)
        std::vector<uint32_t> const cps = { 0x0020, 0x2068, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS PDI LRI AN; 4 ('RTL') (line 445699)
        std::vector<uint32_t> const cps = { 0x0020, 0x2069, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS PDI RLI L; 4 ('RTL') (line 445700)
        std::vector<uint32_t> const cps = { 0x0020, 0x2069, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_020)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // WS PDI RLI EN; 4 ('RTL') (line 445701)
        std::vector<uint32_t> const cps = { 0x0020, 0x2069, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS PDI RLI AN; 4 ('RTL') (line 445702)
        std::vector<uint32_t> const cps = { 0x0020, 0x2069, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // WS PDI FSI AN; 4 ('RTL') (line 445703)
        std::vector<uint32_t> const cps = { 0x0020, 0x2069, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R LRI AN; 5 ('auto') (line 445704)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R LRI AN; 5 ('RTL') (line 445704)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R RLI L; 5 ('auto') (line 445705)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R RLI L; 5 ('RTL') (line 445705)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R RLI EN; 5 ('auto') (line 445706)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R RLI EN; 5 ('RTL') (line 445706)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R RLI AN; 5 ('auto') (line 445707)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R RLI AN; 5 ('RTL') (line 445707)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R FSI AN; 5 ('auto') (line 445708)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON R FSI AN; 5 ('RTL') (line 445708)
        std::vector<uint32_t> const cps = { 0x0021, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON AL LRI AN; 5 ('auto') (line 445709)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON AL LRI AN; 5 ('RTL') (line 445709)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON AL RLI L; 5 ('auto') (line 445710)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON AL RLI L; 5 ('RTL') (line 445710)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_021)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // ON AL RLI EN; 5 ('auto') (line 445711)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON AL RLI EN; 5 ('RTL') (line 445711)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON AL RLI AN; 5 ('auto') (line 445712)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON AL RLI AN; 5 ('RTL') (line 445712)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON AL FSI AN; 5 ('auto') (line 445713)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON AL FSI AN; 5 ('RTL') (line 445713)
        std::vector<uint32_t> const cps = { 0x0021, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ES LRI AN; 4 ('RTL') (line 445714)
        std::vector<uint32_t> const cps = { 0x0021, 0x002B, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ES RLI L; 4 ('RTL') (line 445715)
        std::vector<uint32_t> const cps = { 0x0021, 0x002B, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ES RLI EN; 4 ('RTL') (line 445716)
        std::vector<uint32_t> const cps = { 0x0021, 0x002B, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ES RLI AN; 4 ('RTL') (line 445717)
        std::vector<uint32_t> const cps = { 0x0021, 0x002B, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ES FSI AN; 4 ('RTL') (line 445718)
        std::vector<uint32_t> const cps = { 0x0021, 0x002B, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ET LRI AN; 4 ('RTL') (line 445719)
        std::vector<uint32_t> const cps = { 0x0021, 0x0023, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ET RLI L; 4 ('RTL') (line 445720)
        std::vector<uint32_t> const cps = { 0x0021, 0x0023, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_022)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // ON ET RLI EN; 4 ('RTL') (line 445721)
        std::vector<uint32_t> const cps = { 0x0021, 0x0023, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ET RLI AN; 4 ('RTL') (line 445722)
        std::vector<uint32_t> const cps = { 0x0021, 0x0023, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ET FSI AN; 4 ('RTL') (line 445723)
        std::vector<uint32_t> const cps = { 0x0021, 0x0023, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON CS LRI AN; 4 ('RTL') (line 445724)
        std::vector<uint32_t> const cps = { 0x0021, 0x002C, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON CS RLI L; 4 ('RTL') (line 445725)
        std::vector<uint32_t> const cps = { 0x0021, 0x002C, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON CS RLI EN; 4 ('RTL') (line 445726)
        std::vector<uint32_t> const cps = { 0x0021, 0x002C, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON CS RLI AN; 4 ('RTL') (line 445727)
        std::vector<uint32_t> const cps = { 0x0021, 0x002C, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON CS FSI AN; 4 ('RTL') (line 445728)
        std::vector<uint32_t> const cps = { 0x0021, 0x002C, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON NSM LRI AN; 4 ('RTL') (line 445729)
        std::vector<uint32_t> const cps = { 0x0021, 0x0300, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON NSM RLI L; 4 ('RTL') (line 445730)
        std::vector<uint32_t> const cps = { 0x0021, 0x0300, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_023)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // ON NSM RLI EN; 4 ('RTL') (line 445731)
        std::vector<uint32_t> const cps = { 0x0021, 0x0300, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON NSM RLI AN; 4 ('RTL') (line 445732)
        std::vector<uint32_t> const cps = { 0x0021, 0x0300, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON NSM FSI AN; 4 ('RTL') (line 445733)
        std::vector<uint32_t> const cps = { 0x0021, 0x0300, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON S LRI AN; 4 ('RTL') (line 445734)
        std::vector<uint32_t> const cps = { 0x0021, 0x0009, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON S RLI L; 4 ('RTL') (line 445735)
        std::vector<uint32_t> const cps = { 0x0021, 0x0009, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON S RLI EN; 4 ('RTL') (line 445736)
        std::vector<uint32_t> const cps = { 0x0021, 0x0009, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON S RLI AN; 4 ('RTL') (line 445737)
        std::vector<uint32_t> const cps = { 0x0021, 0x0009, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON S FSI AN; 4 ('RTL') (line 445738)
        std::vector<uint32_t> const cps = { 0x0021, 0x0009, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON WS LRI AN; 4 ('RTL') (line 445739)
        std::vector<uint32_t> const cps = { 0x0021, 0x0020, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON WS RLI L; 4 ('RTL') (line 445740)
        std::vector<uint32_t> const cps = { 0x0021, 0x0020, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_024)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // ON WS RLI EN; 4 ('RTL') (line 445741)
        std::vector<uint32_t> const cps = { 0x0021, 0x0020, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON WS RLI AN; 4 ('RTL') (line 445742)
        std::vector<uint32_t> const cps = { 0x0021, 0x0020, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON WS FSI AN; 4 ('RTL') (line 445743)
        std::vector<uint32_t> const cps = { 0x0021, 0x0020, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ON LRI AN; 4 ('RTL') (line 445744)
        std::vector<uint32_t> const cps = { 0x0021, 0x0021, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ON RLI L; 4 ('RTL') (line 445745)
        std::vector<uint32_t> const cps = { 0x0021, 0x0021, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ON RLI EN; 4 ('RTL') (line 445746)
        std::vector<uint32_t> const cps = { 0x0021, 0x0021, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ON RLI AN; 4 ('RTL') (line 445747)
        std::vector<uint32_t> const cps = { 0x0021, 0x0021, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON ON FSI AN; 4 ('RTL') (line 445748)
        std::vector<uint32_t> const cps = { 0x0021, 0x0021, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON LRI S AN; 4 ('RTL') (line 445749)
        std::vector<uint32_t> const cps = { 0x0021, 0x2066, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON RLI S L; 4 ('RTL') (line 445750)
        std::vector<uint32_t> const cps = { 0x0021, 0x2067, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_025)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // ON RLI S EN; 4 ('RTL') (line 445751)
        std::vector<uint32_t> const cps = { 0x0021, 0x2067, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON RLI S AN; 4 ('RTL') (line 445752)
        std::vector<uint32_t> const cps = { 0x0021, 0x2067, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON FSI S AN; 4 ('RTL') (line 445753)
        std::vector<uint32_t> const cps = { 0x0021, 0x2068, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON PDI LRI AN; 4 ('RTL') (line 445754)
        std::vector<uint32_t> const cps = { 0x0021, 0x2069, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON PDI RLI L; 4 ('RTL') (line 445755)
        std::vector<uint32_t> const cps = { 0x0021, 0x2069, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON PDI RLI EN; 4 ('RTL') (line 445756)
        std::vector<uint32_t> const cps = { 0x0021, 0x2069, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON PDI RLI AN; 4 ('RTL') (line 445757)
        std::vector<uint32_t> const cps = { 0x0021, 0x2069, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // ON PDI FSI AN; 4 ('RTL') (line 445758)
        std::vector<uint32_t> const cps = { 0x0021, 0x2069, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI S S AN; 4 ('RTL') (line 445759)
        std::vector<uint32_t> const cps = { 0x2066, 0x0009, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI WS S AN; 4 ('RTL') (line 445760)
        std::vector<uint32_t> const cps = { 0x2066, 0x0020, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_026)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // LRI LRI S L; 4 ('RTL') (line 445761)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI LRI S EN; 4 ('RTL') (line 445762)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI LRI S ES; 4 ('RTL') (line 445763)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI LRI S ET; 4 ('RTL') (line 445764)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI LRI S CS; 4 ('RTL') (line 445765)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI LRI S NSM; 4 ('RTL') (line 445766)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x0300 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI LRI S ON; 4 ('RTL') (line 445767)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI RLI S L; 4 ('RTL') (line 445768)
        std::vector<uint32_t> const cps = { 0x2066, 0x2067, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI RLI S EN; 4 ('RTL') (line 445769)
        std::vector<uint32_t> const cps = { 0x2066, 0x2067, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI RLI S AN; 4 ('RTL') (line 445770)
        std::vector<uint32_t> const cps = { 0x2066, 0x2067, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_027)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // LRI FSI S L; 4 ('RTL') (line 445771)
        std::vector<uint32_t> const cps = { 0x2066, 0x2068, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI FSI S EN; 4 ('RTL') (line 445772)
        std::vector<uint32_t> const cps = { 0x2066, 0x2068, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI FSI S ES; 4 ('RTL') (line 445773)
        std::vector<uint32_t> const cps = { 0x2066, 0x2068, 0x0009, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI FSI S ET; 4 ('RTL') (line 445774)
        std::vector<uint32_t> const cps = { 0x2066, 0x2068, 0x0009, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI FSI S CS; 4 ('RTL') (line 445775)
        std::vector<uint32_t> const cps = { 0x2066, 0x2068, 0x0009, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI FSI S NSM; 4 ('RTL') (line 445776)
        std::vector<uint32_t> const cps = { 0x2066, 0x2068, 0x0009, 0x0300 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI FSI S ON; 4 ('RTL') (line 445777)
        std::vector<uint32_t> const cps = { 0x2066, 0x2068, 0x0009, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI PDI LRI AN; 4 ('RTL') (line 445778)
        std::vector<uint32_t> const cps = { 0x2066, 0x2069, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI PDI RLI L; 4 ('RTL') (line 445779)
        std::vector<uint32_t> const cps = { 0x2066, 0x2069, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI PDI RLI EN; 4 ('RTL') (line 445780)
        std::vector<uint32_t> const cps = { 0x2066, 0x2069, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_028)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // LRI PDI RLI AN; 4 ('RTL') (line 445781)
        std::vector<uint32_t> const cps = { 0x2066, 0x2069, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI PDI FSI AN; 4 ('RTL') (line 445782)
        std::vector<uint32_t> const cps = { 0x2066, 0x2069, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI S S L; 4 ('RTL') (line 445783)
        std::vector<uint32_t> const cps = { 0x2067, 0x0009, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI S S EN; 4 ('RTL') (line 445784)
        std::vector<uint32_t> const cps = { 0x2067, 0x0009, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI S S AN; 4 ('RTL') (line 445785)
        std::vector<uint32_t> const cps = { 0x2067, 0x0009, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI WS S L; 4 ('RTL') (line 445786)
        std::vector<uint32_t> const cps = { 0x2067, 0x0020, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI WS S EN; 4 ('RTL') (line 445787)
        std::vector<uint32_t> const cps = { 0x2067, 0x0020, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI WS S AN; 4 ('RTL') (line 445788)
        std::vector<uint32_t> const cps = { 0x2067, 0x0020, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI LRI S L; 4 ('RTL') (line 445789)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI LRI S EN; 4 ('RTL') (line 445790)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_029)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // RLI LRI S ES; 4 ('RTL') (line 445791)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI LRI S ET; 4 ('RTL') (line 445792)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI LRI S CS; 4 ('RTL') (line 445793)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI LRI S NSM; 4 ('RTL') (line 445794)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x0300 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI LRI S ON; 4 ('RTL') (line 445795)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI FSI S L; 4 ('RTL') (line 445796)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI FSI S EN; 4 ('RTL') (line 445797)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI FSI S ES; 4 ('RTL') (line 445798)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI FSI S ET; 4 ('RTL') (line 445799)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI FSI S CS; 4 ('RTL') (line 445800)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_030)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // RLI FSI S NSM; 4 ('RTL') (line 445801)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x0300 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI FSI S ON; 4 ('RTL') (line 445802)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI PDI LRI AN; 4 ('RTL') (line 445803)
        std::vector<uint32_t> const cps = { 0x2067, 0x2069, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI PDI RLI L; 4 ('RTL') (line 445804)
        std::vector<uint32_t> const cps = { 0x2067, 0x2069, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI PDI RLI EN; 4 ('RTL') (line 445805)
        std::vector<uint32_t> const cps = { 0x2067, 0x2069, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI PDI RLI AN; 4 ('RTL') (line 445806)
        std::vector<uint32_t> const cps = { 0x2067, 0x2069, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI PDI FSI AN; 4 ('RTL') (line 445807)
        std::vector<uint32_t> const cps = { 0x2067, 0x2069, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI S S AN; 4 ('RTL') (line 445808)
        std::vector<uint32_t> const cps = { 0x2068, 0x0009, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI WS S AN; 4 ('RTL') (line 445809)
        std::vector<uint32_t> const cps = { 0x2068, 0x0020, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI LRI S L; 4 ('RTL') (line 445810)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_031)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // FSI LRI S EN; 4 ('RTL') (line 445811)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI LRI S ES; 4 ('RTL') (line 445812)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI LRI S ET; 4 ('RTL') (line 445813)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI LRI S CS; 4 ('RTL') (line 445814)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI LRI S NSM; 4 ('RTL') (line 445815)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x0300 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI LRI S ON; 4 ('RTL') (line 445816)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI RLI S L; 4 ('RTL') (line 445817)
        std::vector<uint32_t> const cps = { 0x2068, 0x2067, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI RLI S EN; 4 ('RTL') (line 445818)
        std::vector<uint32_t> const cps = { 0x2068, 0x2067, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI RLI S AN; 4 ('RTL') (line 445819)
        std::vector<uint32_t> const cps = { 0x2068, 0x2067, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI FSI S L; 4 ('RTL') (line 445820)
        std::vector<uint32_t> const cps = { 0x2068, 0x2068, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_032)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // FSI FSI S EN; 4 ('RTL') (line 445821)
        std::vector<uint32_t> const cps = { 0x2068, 0x2068, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI FSI S ES; 4 ('RTL') (line 445822)
        std::vector<uint32_t> const cps = { 0x2068, 0x2068, 0x0009, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI FSI S ET; 4 ('RTL') (line 445823)
        std::vector<uint32_t> const cps = { 0x2068, 0x2068, 0x0009, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI FSI S CS; 4 ('RTL') (line 445824)
        std::vector<uint32_t> const cps = { 0x2068, 0x2068, 0x0009, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI FSI S NSM; 4 ('RTL') (line 445825)
        std::vector<uint32_t> const cps = { 0x2068, 0x2068, 0x0009, 0x0300 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI FSI S ON; 4 ('RTL') (line 445826)
        std::vector<uint32_t> const cps = { 0x2068, 0x2068, 0x0009, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI PDI LRI AN; 4 ('RTL') (line 445827)
        std::vector<uint32_t> const cps = { 0x2068, 0x2069, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI PDI RLI L; 4 ('RTL') (line 445828)
        std::vector<uint32_t> const cps = { 0x2068, 0x2069, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI PDI RLI EN; 4 ('RTL') (line 445829)
        std::vector<uint32_t> const cps = { 0x2068, 0x2069, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI PDI RLI AN; 4 ('RTL') (line 445830)
        std::vector<uint32_t> const cps = { 0x2068, 0x2069, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_033)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // FSI PDI FSI AN; 4 ('RTL') (line 445831)
        std::vector<uint32_t> const cps = { 0x2068, 0x2069, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R LRI AN; 5 ('auto') (line 445832)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R LRI AN; 5 ('RTL') (line 445832)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R RLI L; 5 ('auto') (line 445833)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R RLI L; 5 ('RTL') (line 445833)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R RLI EN; 5 ('auto') (line 445834)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R RLI EN; 5 ('RTL') (line 445834)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R RLI AN; 5 ('auto') (line 445835)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R RLI AN; 5 ('RTL') (line 445835)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R FSI AN; 5 ('auto') (line 445836)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI R FSI AN; 5 ('RTL') (line 445836)
        std::vector<uint32_t> const cps = { 0x2069, 0x05BE, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI AL LRI AN; 5 ('auto') (line 445837)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI AL LRI AN; 5 ('RTL') (line 445837)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI AL RLI L; 5 ('auto') (line 445838)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI AL RLI L; 5 ('RTL') (line 445838)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI AL RLI EN; 5 ('auto') (line 445839)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI AL RLI EN; 5 ('RTL') (line 445839)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI AL RLI AN; 5 ('auto') (line 445840)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI AL RLI AN; 5 ('RTL') (line 445840)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_034)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // PDI AL FSI AN; 5 ('auto') (line 445841)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), -1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, -1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI AL FSI AN; 5 ('RTL') (line 445841)
        std::vector<uint32_t> const cps = { 0x2069, 0x0608, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ES LRI AN; 4 ('RTL') (line 445842)
        std::vector<uint32_t> const cps = { 0x2069, 0x002B, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ES RLI L; 4 ('RTL') (line 445843)
        std::vector<uint32_t> const cps = { 0x2069, 0x002B, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ES RLI EN; 4 ('RTL') (line 445844)
        std::vector<uint32_t> const cps = { 0x2069, 0x002B, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ES RLI AN; 4 ('RTL') (line 445845)
        std::vector<uint32_t> const cps = { 0x2069, 0x002B, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ES FSI AN; 4 ('RTL') (line 445846)
        std::vector<uint32_t> const cps = { 0x2069, 0x002B, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ET LRI AN; 4 ('RTL') (line 445847)
        std::vector<uint32_t> const cps = { 0x2069, 0x0023, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ET RLI L; 4 ('RTL') (line 445848)
        std::vector<uint32_t> const cps = { 0x2069, 0x0023, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ET RLI EN; 4 ('RTL') (line 445849)
        std::vector<uint32_t> const cps = { 0x2069, 0x0023, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ET RLI AN; 4 ('RTL') (line 445850)
        std::vector<uint32_t> const cps = { 0x2069, 0x0023, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_035)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // PDI ET FSI AN; 4 ('RTL') (line 445851)
        std::vector<uint32_t> const cps = { 0x2069, 0x0023, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI CS LRI AN; 4 ('RTL') (line 445852)
        std::vector<uint32_t> const cps = { 0x2069, 0x002C, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI CS RLI L; 4 ('RTL') (line 445853)
        std::vector<uint32_t> const cps = { 0x2069, 0x002C, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI CS RLI EN; 4 ('RTL') (line 445854)
        std::vector<uint32_t> const cps = { 0x2069, 0x002C, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI CS RLI AN; 4 ('RTL') (line 445855)
        std::vector<uint32_t> const cps = { 0x2069, 0x002C, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI CS FSI AN; 4 ('RTL') (line 445856)
        std::vector<uint32_t> const cps = { 0x2069, 0x002C, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI NSM LRI AN; 4 ('RTL') (line 445857)
        std::vector<uint32_t> const cps = { 0x2069, 0x0300, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI NSM RLI L; 4 ('RTL') (line 445858)
        std::vector<uint32_t> const cps = { 0x2069, 0x0300, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI NSM RLI EN; 4 ('RTL') (line 445859)
        std::vector<uint32_t> const cps = { 0x2069, 0x0300, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI NSM RLI AN; 4 ('RTL') (line 445860)
        std::vector<uint32_t> const cps = { 0x2069, 0x0300, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_036)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // PDI NSM FSI AN; 4 ('RTL') (line 445861)
        std::vector<uint32_t> const cps = { 0x2069, 0x0300, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI S LRI AN; 4 ('RTL') (line 445862)
        std::vector<uint32_t> const cps = { 0x2069, 0x0009, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI S RLI L; 4 ('RTL') (line 445863)
        std::vector<uint32_t> const cps = { 0x2069, 0x0009, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI S RLI EN; 4 ('RTL') (line 445864)
        std::vector<uint32_t> const cps = { 0x2069, 0x0009, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI S RLI AN; 4 ('RTL') (line 445865)
        std::vector<uint32_t> const cps = { 0x2069, 0x0009, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI S FSI AN; 4 ('RTL') (line 445866)
        std::vector<uint32_t> const cps = { 0x2069, 0x0009, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI WS LRI AN; 4 ('RTL') (line 445867)
        std::vector<uint32_t> const cps = { 0x2069, 0x0020, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI WS RLI L; 4 ('RTL') (line 445868)
        std::vector<uint32_t> const cps = { 0x2069, 0x0020, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI WS RLI EN; 4 ('RTL') (line 445869)
        std::vector<uint32_t> const cps = { 0x2069, 0x0020, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI WS RLI AN; 4 ('RTL') (line 445870)
        std::vector<uint32_t> const cps = { 0x2069, 0x0020, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_037)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // PDI WS FSI AN; 4 ('RTL') (line 445871)
        std::vector<uint32_t> const cps = { 0x2069, 0x0020, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ON LRI AN; 4 ('RTL') (line 445872)
        std::vector<uint32_t> const cps = { 0x2069, 0x0021, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ON RLI L; 4 ('RTL') (line 445873)
        std::vector<uint32_t> const cps = { 0x2069, 0x0021, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ON RLI EN; 4 ('RTL') (line 445874)
        std::vector<uint32_t> const cps = { 0x2069, 0x0021, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ON RLI AN; 4 ('RTL') (line 445875)
        std::vector<uint32_t> const cps = { 0x2069, 0x0021, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI ON FSI AN; 4 ('RTL') (line 445876)
        std::vector<uint32_t> const cps = { 0x2069, 0x0021, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI LRI S AN; 4 ('RTL') (line 445877)
        std::vector<uint32_t> const cps = { 0x2069, 0x2066, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI RLI S L; 4 ('RTL') (line 445878)
        std::vector<uint32_t> const cps = { 0x2069, 0x2067, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI RLI S EN; 4 ('RTL') (line 445879)
        std::vector<uint32_t> const cps = { 0x2069, 0x2067, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI RLI S AN; 4 ('RTL') (line 445880)
        std::vector<uint32_t> const cps = { 0x2069, 0x2067, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_038)
{

    expected_levels = { 1, 1, 1, 4 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // PDI FSI S AN; 4 ('RTL') (line 445881)
        std::vector<uint32_t> const cps = { 0x2069, 0x2068, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI PDI LRI AN; 4 ('RTL') (line 445882)
        std::vector<uint32_t> const cps = { 0x2069, 0x2069, 0x2066, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI PDI RLI L; 4 ('RTL') (line 445883)
        std::vector<uint32_t> const cps = { 0x2069, 0x2069, 0x2067, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI PDI RLI EN; 4 ('RTL') (line 445884)
        std::vector<uint32_t> const cps = { 0x2069, 0x2069, 0x2067, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI PDI RLI AN; 4 ('RTL') (line 445885)
        std::vector<uint32_t> const cps = { 0x2069, 0x2069, 0x2067, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // PDI PDI FSI AN; 4 ('RTL') (line 445886)
        std::vector<uint32_t> const cps = { 0x2069, 0x2069, 0x2068, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    expected_levels = { 1, 1, 1, 5 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // LRI LRI S R; 4 ('RTL') (line 445892)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x05BE };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI LRI S AL; 4 ('RTL') (line 445893)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x0608 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI LRI S R; 4 ('RTL') (line 445894)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x05BE };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI LRI S AL; 4 ('RTL') (line 445895)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x0608 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_039)
{

    expected_levels = { 1, 1, 1, 5 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // RLI RLI S R; 4 ('RTL') (line 445896)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x05BE };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI RLI S AL; 4 ('RTL') (line 445897)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x0608 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI RLI S ES; 4 ('RTL') (line 445898)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI RLI S ET; 4 ('RTL') (line 445899)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI RLI S CS; 4 ('RTL') (line 445900)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI RLI S NSM; 4 ('RTL') (line 445901)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x0300 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI RLI S ON; 4 ('RTL') (line 445902)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI FSI S R; 4 ('RTL') (line 445903)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x05BE };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI FSI S AL; 4 ('RTL') (line 445904)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x0608 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI LRI S R; 4 ('RTL') (line 445905)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x05BE };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_040)
{

    expected_levels = { 1, 1, 1, 5 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // FSI LRI S AL; 4 ('RTL') (line 445906)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x0608 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    expected_levels = { 1, 1, 1, 6 };
    expected_reordered_indices = { 3, 2, 1, 0 };

    {
        // LRI LRI S AN; 4 ('RTL') (line 445912)
        std::vector<uint32_t> const cps = { 0x2066, 0x2066, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // LRI FSI S AN; 4 ('RTL') (line 445913)
        std::vector<uint32_t> const cps = { 0x2066, 0x2068, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI LRI S AN; 4 ('RTL') (line 445914)
        std::vector<uint32_t> const cps = { 0x2067, 0x2066, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI RLI S L; 4 ('RTL') (line 445915)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI RLI S EN; 4 ('RTL') (line 445916)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x0030 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI RLI S AN; 4 ('RTL') (line 445917)
        std::vector<uint32_t> const cps = { 0x2067, 0x2067, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // RLI FSI S AN; 4 ('RTL') (line 445918)
        std::vector<uint32_t> const cps = { 0x2067, 0x2068, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI LRI S AN; 4 ('RTL') (line 445919)
        std::vector<uint32_t> const cps = { 0x2068, 0x2066, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // FSI FSI S AN; 4 ('RTL') (line 445920)
        std::vector<uint32_t> const cps = { 0x2068, 0x2068, 0x0009, 0x0660 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_041)
{

    expected_levels = { 1, 1, 2, 0 };
    expected_reordered_indices = { 2, 1, 0, 3 };

    {
        // R R EN L; 2 ('LTR') (line 445926)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R EN ES; 2 ('LTR') (line 445927)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R EN CS; 2 ('LTR') (line 445928)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R EN B; 2 ('LTR') (line 445929)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x2029 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R EN S; 2 ('LTR') (line 445930)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x0009 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R EN WS; 2 ('LTR') (line 445931)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x0020 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R EN ON; 2 ('LTR') (line 445932)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R EN LRI; 2 ('LTR') (line 445933)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x2066 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R EN RLI; 2 ('LTR') (line 445934)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x2067 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R EN FSI; 2 ('LTR') (line 445935)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x2068 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_042)
{

    expected_levels = { 1, 1, 2, 0 };
    expected_reordered_indices = { 2, 1, 0, 3 };

    {
        // R R EN PDI; 2 ('LTR') (line 445936)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0030, 0x2069 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN L; 2 ('LTR') (line 445937)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN ES; 2 ('LTR') (line 445938)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN ET; 2 ('LTR') (line 445939)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN CS; 2 ('LTR') (line 445940)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN B; 2 ('LTR') (line 445941)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x2029 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN S; 2 ('LTR') (line 445942)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x0009 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN WS; 2 ('LTR') (line 445943)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x0020 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN ON; 2 ('LTR') (line 445944)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN LRI; 2 ('LTR') (line 445945)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x2066 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_043)
{

    expected_levels = { 1, 1, 2, 0 };
    expected_reordered_indices = { 2, 1, 0, 3 };

    {
        // R R AN RLI; 2 ('LTR') (line 445946)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x2067 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN FSI; 2 ('LTR') (line 445947)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x2068 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R R AN PDI; 2 ('LTR') (line 445948)
        std::vector<uint32_t> const cps = { 0x05BE, 0x05BE, 0x0660, 0x2069 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN L; 2 ('LTR') (line 445949)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN ES; 2 ('LTR') (line 445950)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN ET; 2 ('LTR') (line 445951)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN CS; 2 ('LTR') (line 445952)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN B; 2 ('LTR') (line 445953)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x2029 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN S; 2 ('LTR') (line 445954)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x0009 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN WS; 2 ('LTR') (line 445955)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x0020 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_044)
{

    expected_levels = { 1, 1, 2, 0 };
    expected_reordered_indices = { 2, 1, 0, 3 };

    {
        // R AL EN ON; 2 ('LTR') (line 445956)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN LRI; 2 ('LTR') (line 445957)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x2066 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN RLI; 2 ('LTR') (line 445958)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x2067 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN FSI; 2 ('LTR') (line 445959)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x2068 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL EN PDI; 2 ('LTR') (line 445960)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0030, 0x2069 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN L; 2 ('LTR') (line 445961)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN ES; 2 ('LTR') (line 445962)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN ET; 2 ('LTR') (line 445963)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN CS; 2 ('LTR') (line 445964)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN B; 2 ('LTR') (line 445965)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x2029 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_045)
{

    expected_levels = { 1, 1, 2, 0 };
    expected_reordered_indices = { 2, 1, 0, 3 };

    {
        // R AL AN S; 2 ('LTR') (line 445966)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x0009 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN WS; 2 ('LTR') (line 445967)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x0020 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN ON; 2 ('LTR') (line 445968)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN LRI; 2 ('LTR') (line 445969)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x2066 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN RLI; 2 ('LTR') (line 445970)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x2067 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN FSI; 2 ('LTR') (line 445971)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x2068 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R AL AN PDI; 2 ('LTR') (line 445972)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0608, 0x0660, 0x2069 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN L; 2 ('LTR') (line 445973)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN ES; 2 ('LTR') (line 445974)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN CS; 2 ('LTR') (line 445975)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_046)
{

    expected_levels = { 1, 1, 2, 0 };
    expected_reordered_indices = { 2, 1, 0, 3 };

    {
        // R ES EN B; 2 ('LTR') (line 445976)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x2029 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN S; 2 ('LTR') (line 445977)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x0009 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN WS; 2 ('LTR') (line 445978)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x0020 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN ON; 2 ('LTR') (line 445979)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN LRI; 2 ('LTR') (line 445980)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x2066 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN RLI; 2 ('LTR') (line 445981)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x2067 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN FSI; 2 ('LTR') (line 445982)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x2068 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES EN PDI; 2 ('LTR') (line 445983)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0030, 0x2069 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN L; 2 ('LTR') (line 445984)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN ES; 2 ('LTR') (line 445985)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_047)
{

    expected_levels = { 1, 1, 2, 0 };
    expected_reordered_indices = { 2, 1, 0, 3 };

    {
        // R ES AN ET; 2 ('LTR') (line 445986)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN CS; 2 ('LTR') (line 445987)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN B; 2 ('LTR') (line 445988)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x2029 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN S; 2 ('LTR') (line 445989)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x0009 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN WS; 2 ('LTR') (line 445990)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x0020 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN ON; 2 ('LTR') (line 445991)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x0021 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN LRI; 2 ('LTR') (line 445992)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x2066 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN RLI; 2 ('LTR') (line 445993)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x2067 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN FSI; 2 ('LTR') (line 445994)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x2068 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ES AN PDI; 2 ('LTR') (line 445995)
        std::vector<uint32_t> const cps = { 0x05BE, 0x002B, 0x0660, 0x2069 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }
}

TEST(bidi, bidi_891_048)
{

    expected_levels = { 1, 1, 2, 0 };
    expected_reordered_indices = { 2, 1, 0, 3 };

    {
        // R ET AN L; 2 ('LTR') (line 445996)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0023, 0x0660, 0x0041 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ET AN ES; 2 ('LTR') (line 445997)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0023, 0x0660, 0x002B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ET AN ET; 2 ('LTR') (line 445998)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0023, 0x0660, 0x0023 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ET AN CS; 2 ('LTR') (line 445999)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0023, 0x0660, 0x002C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ET AN B; 2 ('LTR') (line 446000)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0023, 0x0660, 0x2029 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 0);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 0);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 0)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

}

max_stars_repo_name: eightysquirrels/text

max_issues_repo_name: eightysquirrels/text

max_forks_repo_name: eightysquirrels/text