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_197_000)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_001)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_002)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_003)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_004)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_005)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_006)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_007)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_008)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_009)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_010)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_011)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_012)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_013)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_014)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_015)
{

    expected_levels = { 2, 1, -1, -1 };
    expected_reordered_indices = { 1, 0 };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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 = { 2, 2, 0 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // AN AN L; 3 ('auto') (line 98663)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN L; 3 ('LTR') (line 98663)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

    {
        // AN AN EN; 3 ('auto') (line 98664)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN EN; 3 ('LTR') (line 98664)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 0x0030 };
        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());
    }

    {
        // AN AN ES; 3 ('auto') (line 98665)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN ES; 3 ('LTR') (line 98665)
        std::vector<uint32_t> const cps = { 0x0660, 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_197_016)
{

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

    {
        // AN AN ET; 3 ('auto') (line 98666)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN ET; 3 ('LTR') (line 98666)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

    {
        // AN AN CS; 3 ('auto') (line 98667)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN CS; 3 ('LTR') (line 98667)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

    {
        // AN AN B; 3 ('auto') (line 98668)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 0x2029 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

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

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

    {
        // AN AN B; 3 ('LTR') (line 98668)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

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

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

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

    {
        // AN AN S; 3 ('LTR') (line 98669)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

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

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

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

    {
        // AN AN WS; 3 ('LTR') (line 98670)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

    {
        // AN AN ON; 3 ('auto') (line 98671)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN ON; 3 ('LTR') (line 98671)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

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

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

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

    {
        // AN AN LRI; 3 ('LTR') (line 98672)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

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

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

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

    {
        // AN AN RLI; 3 ('LTR') (line 98673)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

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

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

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

    {
        // AN AN FSI; 3 ('LTR') (line 98674)
        std::vector<uint32_t> const cps = { 0x0660, 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());
    }

    {
        // AN AN PDI; 3 ('auto') (line 98675)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 0x2069 };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), -1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

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

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

    {
        // AN AN PDI; 3 ('LTR') (line 98675)
        std::vector<uint32_t> const cps = { 0x0660, 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_197_017)
{

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

    {
        // AN NSM L; 3 ('auto') (line 98676)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM L; 3 ('LTR') (line 98676)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM EN; 3 ('auto') (line 98677)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM EN; 3 ('LTR') (line 98677)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 0x0030 };
        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());
    }

    {
        // AN NSM ES; 3 ('auto') (line 98678)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM ES; 3 ('LTR') (line 98678)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM ET; 3 ('auto') (line 98679)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM ET; 3 ('LTR') (line 98679)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM CS; 3 ('auto') (line 98680)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM CS; 3 ('LTR') (line 98680)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

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

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

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

    {
        // AN NSM B; 3 ('LTR') (line 98681)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

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

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

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

    {
        // AN NSM S; 3 ('LTR') (line 98682)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

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

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

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

    {
        // AN NSM WS; 3 ('LTR') (line 98683)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM ON; 3 ('auto') (line 98684)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM ON; 3 ('LTR') (line 98684)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

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

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

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

    {
        // AN NSM LRI; 3 ('LTR') (line 98685)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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_197_018)
{

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

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

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

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

    {
        // AN NSM RLI; 3 ('LTR') (line 98686)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

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

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

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

    {
        // AN NSM FSI; 3 ('LTR') (line 98687)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

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

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

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

    {
        // AN NSM PDI; 3 ('LTR') (line 98688)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

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

    {
        // L L R; 4 ('RTL') (line 98694)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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());
    }

    {
        // L L AL; 4 ('RTL') (line 98695)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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());
    }

    {
        // L L ES; 4 ('RTL') (line 98696)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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());
    }

    {
        // L L ET; 4 ('RTL') (line 98697)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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());
    }

    {
        // L L CS; 4 ('RTL') (line 98698)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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());
    }

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_019)
{

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

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

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

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

    {
        // L L ON; 4 ('RTL') (line 98702)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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());
    }

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

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

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

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

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

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

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

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

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

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

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

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

    {
        // L EN R; 4 ('RTL') (line 98707)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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());
    }

    {
        // L EN AL; 4 ('RTL') (line 98708)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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());
    }

    {
        // L EN ES; 4 ('RTL') (line 98709)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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());
    }

    {
        // L EN CS; 4 ('RTL') (line 98710)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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_197_020)
{

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

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

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

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

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

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

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

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

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

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

    {
        // L EN ON; 4 ('RTL') (line 98714)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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());
    }

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

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

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

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

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

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

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

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

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

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

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

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

    {
        // L AN R; 4 ('RTL') (line 98719)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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());
    }

    {
        // L AN AL; 4 ('RTL') (line 98720)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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_197_021)
{

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

    {
        // L AN ES; 4 ('RTL') (line 98721)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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());
    }

    {
        // L AN ET; 4 ('RTL') (line 98722)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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());
    }

    {
        // L AN CS; 4 ('RTL') (line 98723)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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());
    }

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

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

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

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

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

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

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

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

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

    {
        // L AN ON; 4 ('RTL') (line 98727)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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());
    }

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_022)
{

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

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

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

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

    {
        // L NSM R; 4 ('RTL') (line 98732)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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());
    }

    {
        // L NSM AL; 4 ('RTL') (line 98733)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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());
    }

    {
        // L NSM ES; 4 ('RTL') (line 98734)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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());
    }

    {
        // L NSM ET; 4 ('RTL') (line 98735)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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());
    }

    {
        // L NSM CS; 4 ('RTL') (line 98736)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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());
    }

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

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

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

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

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

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

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

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

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

    {
        // L NSM ON; 4 ('RTL') (line 98740)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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());
    }
}

TEST(bidi, bidi_197_023)
{

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

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

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

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

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

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

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

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

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

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

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

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

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

    {
        // EN L R; 4 ('RTL') (line 98745)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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());
    }

    {
        // EN L AL; 4 ('RTL') (line 98746)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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());
    }

    {
        // EN L ES; 4 ('RTL') (line 98747)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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());
    }

    {
        // EN L ET; 4 ('RTL') (line 98748)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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());
    }

    {
        // EN L CS; 4 ('RTL') (line 98749)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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());
    }

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_024)
{

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

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

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

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

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

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

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

    {
        // EN L ON; 4 ('RTL') (line 98753)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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());
    }

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

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

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

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

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

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

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

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

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

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

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

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

    {
        // EN EN R; 5 ('auto') (line 98758)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

    {
        // EN EN R; 5 ('RTL') (line 98758)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

    {
        // EN EN AL; 5 ('auto') (line 98759)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

    {
        // EN EN AL; 5 ('RTL') (line 98759)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

    {
        // EN EN ES; 4 ('RTL') (line 98760)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }
}

TEST(bidi, bidi_197_025)
{

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

    {
        // EN EN CS; 4 ('RTL') (line 98761)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

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

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

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

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

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

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

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

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

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

    {
        // EN EN ON; 4 ('RTL') (line 98765)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

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

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

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

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

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

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

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

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

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

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

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

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

    {
        // EN ET R; 5 ('auto') (line 98770)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

    {
        // EN ET R; 5 ('RTL') (line 98770)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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_197_026)
{

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

    {
        // EN ET AL; 5 ('auto') (line 98771)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

    {
        // EN ET AL; 5 ('RTL') (line 98771)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

    {
        // EN ET ES; 4 ('RTL') (line 98772)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

    {
        // EN ET CS; 4 ('RTL') (line 98773)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

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

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

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

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

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

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

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

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

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

    {
        // EN ET ON; 4 ('RTL') (line 98777)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_027)
{

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

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

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

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

    {
        // EN AN R; 5 ('auto') (line 98782)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN AN R; 5 ('RTL') (line 98782)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN AN AL; 5 ('auto') (line 98783)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN AN AL; 5 ('RTL') (line 98783)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN AN ES; 4 ('RTL') (line 98784)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN AN ET; 4 ('RTL') (line 98785)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN AN CS; 4 ('RTL') (line 98786)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

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

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

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

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

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

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

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

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

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

    {
        // EN AN ON; 4 ('RTL') (line 98790)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }
}

TEST(bidi, bidi_197_028)
{

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

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

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

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

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

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

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

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

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

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

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

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

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

    {
        // EN NSM R; 5 ('auto') (line 98795)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

    {
        // EN NSM R; 5 ('RTL') (line 98795)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

    {
        // EN NSM AL; 5 ('auto') (line 98796)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

    {
        // EN NSM AL; 5 ('RTL') (line 98796)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

    {
        // EN NSM ES; 4 ('RTL') (line 98797)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

    {
        // EN NSM CS; 4 ('RTL') (line 98798)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_029)
{

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

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

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

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

    {
        // EN NSM ON; 4 ('RTL') (line 98802)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

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

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

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

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

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

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

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

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

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

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

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

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

    {
        // ET EN R; 5 ('auto') (line 98807)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET EN R; 5 ('RTL') (line 98807)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET EN AL; 5 ('auto') (line 98808)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET EN AL; 5 ('RTL') (line 98808)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET EN ES; 4 ('RTL') (line 98809)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET EN CS; 4 ('RTL') (line 98810)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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_197_030)
{

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

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

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

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

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

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

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

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

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

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

    {
        // ET EN ON; 4 ('RTL') (line 98814)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

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

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

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

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

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

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

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

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

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

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

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

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

    {
        // AN L R; 4 ('RTL') (line 98819)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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());
    }

    {
        // AN L AL; 4 ('RTL') (line 98820)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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_197_031)
{

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

    {
        // AN L ES; 4 ('RTL') (line 98821)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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());
    }

    {
        // AN L ET; 4 ('RTL') (line 98822)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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());
    }

    {
        // AN L CS; 4 ('RTL') (line 98823)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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());
    }

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

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

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

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

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

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

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

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

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

    {
        // AN L ON; 4 ('RTL') (line 98827)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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());
    }

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

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

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

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_032)
{

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

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

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

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

    {
        // AN EN R; 5 ('auto') (line 98832)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN EN R; 5 ('RTL') (line 98832)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN EN AL; 5 ('auto') (line 98833)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN EN AL; 5 ('RTL') (line 98833)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN EN ES; 4 ('RTL') (line 98834)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN EN CS; 4 ('RTL') (line 98835)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

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

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

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

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

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

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

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

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

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

    {
        // AN EN ON; 4 ('RTL') (line 98839)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_033)
{

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

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

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

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

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

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

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

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

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

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

    {
        // AN AN R; 7 ('auto') (line 98844)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN R; 7 ('LTR') (line 98844)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 0x05BE };
        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());
    }

    {
        // AN AN R; 7 ('RTL') (line 98844)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN AL; 7 ('auto') (line 98845)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN AL; 7 ('LTR') (line 98845)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 0x0608 };
        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());
    }

    {
        // AN AN AL; 7 ('RTL') (line 98845)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN ES; 4 ('RTL') (line 98846)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN ET; 4 ('RTL') (line 98847)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN CS; 4 ('RTL') (line 98848)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

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

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

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

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

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

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_034)
{

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

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

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

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

    {
        // AN AN ON; 4 ('RTL') (line 98852)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

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

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

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

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

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

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

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

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

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

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

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

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

    {
        // AN NSM R; 7 ('auto') (line 98857)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM R; 7 ('LTR') (line 98857)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 0x05BE };
        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());
    }

    {
        // AN NSM R; 7 ('RTL') (line 98857)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM AL; 7 ('auto') (line 98858)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM AL; 7 ('LTR') (line 98858)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 0x0608 };
        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());
    }

    {
        // AN NSM AL; 7 ('RTL') (line 98858)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM ES; 4 ('RTL') (line 98859)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM ET; 4 ('RTL') (line 98860)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }
}

TEST(bidi, bidi_197_035)
{

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

    {
        // AN NSM CS; 4 ('RTL') (line 98861)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

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

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

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

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

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

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

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

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

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

    {
        // AN NSM ON; 4 ('RTL') (line 98865)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

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

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

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

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

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

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

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

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

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

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

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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 = { 2, 2, 2 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // L L L; 4 ('RTL') (line 98875)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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_197_036)
{

    expected_levels = { 2, 2, 2 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // L L EN; 4 ('RTL') (line 98876)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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());
    }

    {
        // L L AN; 4 ('RTL') (line 98877)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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());
    }

    {
        // L L NSM; 4 ('RTL') (line 98878)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 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());
    }

    {
        // L EN L; 4 ('RTL') (line 98879)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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());
    }

    {
        // L EN EN; 4 ('RTL') (line 98880)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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());
    }

    {
        // L EN ET; 4 ('RTL') (line 98881)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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());
    }

    {
        // L EN AN; 4 ('RTL') (line 98882)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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());
    }

    {
        // L EN NSM; 4 ('RTL') (line 98883)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 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());
    }

    {
        // L ES L; 4 ('RTL') (line 98884)
        std::vector<uint32_t> const cps = { 0x0041, 0x002B, 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());
    }

    {
        // L ES EN; 4 ('RTL') (line 98885)
        std::vector<uint32_t> const cps = { 0x0041, 0x002B, 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_197_037)
{

    expected_levels = { 2, 2, 2 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // L ET L; 4 ('RTL') (line 98886)
        std::vector<uint32_t> const cps = { 0x0041, 0x0023, 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());
    }

    {
        // L ET EN; 4 ('RTL') (line 98887)
        std::vector<uint32_t> const cps = { 0x0041, 0x0023, 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());
    }

    {
        // L AN L; 4 ('RTL') (line 98888)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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());
    }

    {
        // L AN EN; 4 ('RTL') (line 98889)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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());
    }

    {
        // L AN AN; 4 ('RTL') (line 98890)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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());
    }

    {
        // L AN NSM; 4 ('RTL') (line 98891)
        std::vector<uint32_t> const cps = { 0x0041, 0x0660, 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());
    }

    {
        // L CS L; 4 ('RTL') (line 98892)
        std::vector<uint32_t> const cps = { 0x0041, 0x002C, 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());
    }

    {
        // L CS EN; 4 ('RTL') (line 98893)
        std::vector<uint32_t> const cps = { 0x0041, 0x002C, 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());
    }

    {
        // L NSM L; 4 ('RTL') (line 98894)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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());
    }

    {
        // L NSM EN; 4 ('RTL') (line 98895)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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_197_038)
{

    expected_levels = { 2, 2, 2 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // L NSM AN; 4 ('RTL') (line 98896)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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());
    }

    {
        // L NSM NSM; 4 ('RTL') (line 98897)
        std::vector<uint32_t> const cps = { 0x0041, 0x0300, 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());
    }

    {
        // L WS L; 4 ('RTL') (line 98898)
        std::vector<uint32_t> const cps = { 0x0041, 0x0020, 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());
    }

    {
        // L WS EN; 4 ('RTL') (line 98899)
        std::vector<uint32_t> const cps = { 0x0041, 0x0020, 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());
    }

    {
        // L ON L; 4 ('RTL') (line 98900)
        std::vector<uint32_t> const cps = { 0x0041, 0x0021, 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());
    }

    {
        // L ON EN; 4 ('RTL') (line 98901)
        std::vector<uint32_t> const cps = { 0x0041, 0x0021, 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());
    }

    {
        // L PDI L; 4 ('RTL') (line 98902)
        std::vector<uint32_t> const cps = { 0x0041, 0x2069, 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());
    }

    {
        // L PDI EN; 4 ('RTL') (line 98903)
        std::vector<uint32_t> const cps = { 0x0041, 0x2069, 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());
    }

    {
        // EN L L; 4 ('RTL') (line 98904)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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());
    }

    {
        // EN L EN; 4 ('RTL') (line 98905)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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_197_039)
{

    expected_levels = { 2, 2, 2 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // EN L AN; 4 ('RTL') (line 98906)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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());
    }

    {
        // EN L NSM; 4 ('RTL') (line 98907)
        std::vector<uint32_t> const cps = { 0x0030, 0x0041, 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());
    }

    {
        // EN EN L; 4 ('RTL') (line 98908)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

    {
        // EN EN EN; 4 ('RTL') (line 98909)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

    {
        // EN EN ET; 4 ('RTL') (line 98910)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

    {
        // EN EN AN; 4 ('RTL') (line 98911)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

    {
        // EN EN NSM; 4 ('RTL') (line 98912)
        std::vector<uint32_t> const cps = { 0x0030, 0x0030, 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());
    }

    {
        // EN ES EN; 4 ('RTL') (line 98913)
        std::vector<uint32_t> const cps = { 0x0030, 0x002B, 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());
    }

    {
        // EN ET L; 4 ('RTL') (line 98914)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

    {
        // EN ET EN; 4 ('RTL') (line 98915)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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_197_040)
{

    expected_levels = { 2, 2, 2 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // EN ET ET; 4 ('RTL') (line 98916)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

    {
        // EN ET AN; 4 ('RTL') (line 98917)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

    {
        // EN ET NSM; 4 ('RTL') (line 98918)
        std::vector<uint32_t> const cps = { 0x0030, 0x0023, 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());
    }

    {
        // EN AN L; 4 ('RTL') (line 98919)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN AN EN; 4 ('RTL') (line 98920)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN AN AN; 4 ('RTL') (line 98921)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN AN NSM; 4 ('RTL') (line 98922)
        std::vector<uint32_t> const cps = { 0x0030, 0x0660, 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());
    }

    {
        // EN CS EN; 4 ('RTL') (line 98923)
        std::vector<uint32_t> const cps = { 0x0030, 0x002C, 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());
    }

    {
        // EN NSM L; 4 ('RTL') (line 98924)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

    {
        // EN NSM EN; 4 ('RTL') (line 98925)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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_197_041)
{

    expected_levels = { 2, 2, 2 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // EN NSM ET; 4 ('RTL') (line 98926)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

    {
        // EN NSM AN; 4 ('RTL') (line 98927)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

    {
        // EN NSM NSM; 4 ('RTL') (line 98928)
        std::vector<uint32_t> const cps = { 0x0030, 0x0300, 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());
    }

    {
        // ET EN L; 4 ('RTL') (line 98929)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET EN EN; 4 ('RTL') (line 98930)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET EN ET; 4 ('RTL') (line 98931)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET EN AN; 4 ('RTL') (line 98932)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET EN NSM; 4 ('RTL') (line 98933)
        std::vector<uint32_t> const cps = { 0x0023, 0x0030, 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());
    }

    {
        // ET ET EN; 4 ('RTL') (line 98934)
        std::vector<uint32_t> const cps = { 0x0023, 0x0023, 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());
    }

    {
        // ET NSM EN; 4 ('RTL') (line 98935)
        std::vector<uint32_t> const cps = { 0x0023, 0x0300, 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_197_042)
{

    expected_levels = { 2, 2, 2 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // AN L L; 4 ('RTL') (line 98936)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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());
    }

    {
        // AN L EN; 4 ('RTL') (line 98937)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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());
    }

    {
        // AN L AN; 4 ('RTL') (line 98938)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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());
    }

    {
        // AN L NSM; 4 ('RTL') (line 98939)
        std::vector<uint32_t> const cps = { 0x0660, 0x0041, 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());
    }

    {
        // AN EN L; 4 ('RTL') (line 98940)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN EN EN; 4 ('RTL') (line 98941)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN EN ET; 4 ('RTL') (line 98942)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN EN AN; 4 ('RTL') (line 98943)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN EN NSM; 4 ('RTL') (line 98944)
        std::vector<uint32_t> const cps = { 0x0660, 0x0030, 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());
    }

    {
        // AN ET EN; 4 ('RTL') (line 98945)
        std::vector<uint32_t> const cps = { 0x0660, 0x0023, 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_197_043)
{

    expected_levels = { 2, 2, 2 };
    expected_reordered_indices = { 0, 1, 2 };

    {
        // AN AN L; 4 ('RTL') (line 98946)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN EN; 4 ('RTL') (line 98947)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN AN; 7 ('auto') (line 98948)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN AN; 7 ('LTR') (line 98948)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 0x0660 };
        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());
    }

    {
        // AN AN AN; 7 ('RTL') (line 98948)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN NSM; 7 ('auto') (line 98949)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN AN NSM; 7 ('LTR') (line 98949)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 0x0300 };
        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());
    }

    {
        // AN AN NSM; 7 ('RTL') (line 98949)
        std::vector<uint32_t> const cps = { 0x0660, 0x0660, 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());
    }

    {
        // AN CS AN; 7 ('auto') (line 98950)
        std::vector<uint32_t> const cps = { 0x0660, 0x002C, 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());
    }

    {
        // AN CS AN; 7 ('LTR') (line 98950)
        std::vector<uint32_t> const cps = { 0x0660, 0x002C, 0x0660 };
        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());
    }

    {
        // AN CS AN; 7 ('RTL') (line 98950)
        std::vector<uint32_t> const cps = { 0x0660, 0x002C, 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());
    }

    {
        // AN NSM L; 4 ('RTL') (line 98951)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM EN; 4 ('RTL') (line 98952)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM AN; 7 ('auto') (line 98953)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM AN; 7 ('LTR') (line 98953)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 0x0660 };
        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());
    }

    {
        // AN NSM AN; 7 ('RTL') (line 98953)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM NSM; 7 ('auto') (line 98954)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    {
        // AN NSM NSM; 7 ('LTR') (line 98954)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 0x0300 };
        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());
    }

    {
        // AN NSM NSM; 7 ('RTL') (line 98954)
        std::vector<uint32_t> const cps = { 0x0660, 0x0300, 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());
    }

    expected_levels = { 2, 2, -1, -1 };
    expected_reordered_indices = { 0, 1 };

    {
        // L L LRE LRE; 4 ('RTL') (line 98960)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202A, 0x202A };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_044)
{

    expected_levels = { 2, 2, -1, -1 };
    expected_reordered_indices = { 0, 1 };

    {
        // L L LRE LRO; 4 ('RTL') (line 98961)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202A, 0x202D };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L LRE RLE; 4 ('RTL') (line 98962)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202A, 0x202B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L LRE RLO; 4 ('RTL') (line 98963)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202A, 0x202E };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L LRE PDF; 4 ('RTL') (line 98964)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202A, 0x202C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L LRE BN; 4 ('RTL') (line 98965)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202A, 0x00AD };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L LRO LRE; 4 ('RTL') (line 98966)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202D, 0x202A };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L LRO LRO; 4 ('RTL') (line 98967)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202D, 0x202D };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L LRO RLE; 4 ('RTL') (line 98968)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202D, 0x202B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L LRO RLO; 4 ('RTL') (line 98969)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202D, 0x202E };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L LRO PDF; 4 ('RTL') (line 98970)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202D, 0x202C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_045)
{

    expected_levels = { 2, 2, -1, -1 };
    expected_reordered_indices = { 0, 1 };

    {
        // L L LRO BN; 4 ('RTL') (line 98971)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202D, 0x00AD };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLE LRE; 4 ('RTL') (line 98972)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202B, 0x202A };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLE LRO; 4 ('RTL') (line 98973)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202B, 0x202D };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLE RLE; 4 ('RTL') (line 98974)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202B, 0x202B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLE RLO; 4 ('RTL') (line 98975)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202B, 0x202E };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLE PDF; 4 ('RTL') (line 98976)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202B, 0x202C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLE BN; 4 ('RTL') (line 98977)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202B, 0x00AD };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLO LRE; 4 ('RTL') (line 98978)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202E, 0x202A };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLO LRO; 4 ('RTL') (line 98979)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202E, 0x202D };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLO RLE; 4 ('RTL') (line 98980)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202E, 0x202B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_046)
{

    expected_levels = { 2, 2, -1, -1 };
    expected_reordered_indices = { 0, 1 };

    {
        // L L RLO RLO; 4 ('RTL') (line 98981)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202E, 0x202E };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLO PDF; 4 ('RTL') (line 98982)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202E, 0x202C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L RLO BN; 4 ('RTL') (line 98983)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202E, 0x00AD };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L PDF LRE; 4 ('RTL') (line 98984)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202C, 0x202A };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L PDF LRO; 4 ('RTL') (line 98985)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202C, 0x202D };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L PDF RLE; 4 ('RTL') (line 98986)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202C, 0x202B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L PDF RLO; 4 ('RTL') (line 98987)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202C, 0x202E };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L PDF PDF; 4 ('RTL') (line 98988)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202C, 0x202C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L PDF BN; 4 ('RTL') (line 98989)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x202C, 0x00AD };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L BN LRE; 4 ('RTL') (line 98990)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x00AD, 0x202A };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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_197_047)
{

    expected_levels = { 2, 2, -1, -1 };
    expected_reordered_indices = { 0, 1 };

    {
        // L L BN LRO; 4 ('RTL') (line 98991)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x00AD, 0x202D };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L BN RLE; 4 ('RTL') (line 98992)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x00AD, 0x202B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L BN RLO; 4 ('RTL') (line 98993)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x00AD, 0x202E };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L BN PDF; 4 ('RTL') (line 98994)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x00AD, 0x202C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L L BN BN; 4 ('RTL') (line 98995)
        std::vector<uint32_t> const cps = { 0x0041, 0x0041, 0x00AD, 0x00AD };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L EN LRE LRE; 4 ('RTL') (line 98996)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 0x202A, 0x202A };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L EN LRE LRO; 4 ('RTL') (line 98997)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 0x202A, 0x202D };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L EN LRE RLE; 4 ('RTL') (line 98998)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 0x202A, 0x202B };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L EN LRE RLO; 4 ('RTL') (line 98999)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 0x202A, 0x202E };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // L EN LRE PDF; 4 ('RTL') (line 99000)
        std::vector<uint32_t> const cps = { 0x0041, 0x0030, 0x202A, 0x202C };
        std::vector<int> const levels =
            bidi_levels(cps.begin(), cps.end(), 1);
        int i = 0;
        for (int l : expected_levels) {
            if (0 <= l) {
                EXPECT_EQ(levels[i], l) << "i=" << i;
                ++i;
            }
        }
        EXPECT_EQ((int)levels.size(), i);

        std::vector<int> const reordered =
            bidi_reordered_indices(cps.begin(), cps.end(), 1);
        i = 0;
        for (int idx : expected_reordered_indices) {
            // Skip FSI, LRI, RLI, and PDI.
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered[i], cps[idx])
                    << std::hex
                    << " 0x" << reordered[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }

        std::vector<int> reordered_2;
        for (auto subrange :
            boost::text::bidirectional_subranges(cps, 1)) {
            for (auto cp : subrange) {
                reordered_2.push_back(cp);
            }
        }
        i = 0;
        for (int idx : expected_reordered_indices) {
            if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                EXPECT_EQ(reordered_2[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