text:
// Copyright (C) 2020 T. Zachary Laine
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// 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_439_000)
{

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

    {
        // R ON L LRE; 2 ('LTR') (line 219501)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0041, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON L LRO; 2 ('LTR') (line 219502)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0041, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON L RLE; 2 ('LTR') (line 219503)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0041, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON L RLO; 2 ('LTR') (line 219504)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0041, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON L PDF; 2 ('LTR') (line 219505)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0041, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON L BN; 2 ('LTR') (line 219506)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0041, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ES LRE; 2 ('LTR') (line 219507)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002B, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ES LRO; 2 ('LTR') (line 219508)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002B, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ES RLE; 2 ('LTR') (line 219509)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002B, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ES RLO; 2 ('LTR') (line 219510)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002B, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_001)
{

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

    {
        // R ON ES PDF; 2 ('LTR') (line 219511)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002B, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ES BN; 2 ('LTR') (line 219512)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002B, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ET LRE; 2 ('LTR') (line 219513)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0023, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ET LRO; 2 ('LTR') (line 219514)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0023, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ET RLE; 2 ('LTR') (line 219515)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0023, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ET RLO; 2 ('LTR') (line 219516)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0023, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ET PDF; 2 ('LTR') (line 219517)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0023, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ET BN; 2 ('LTR') (line 219518)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0023, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON CS LRE; 2 ('LTR') (line 219519)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002C, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON CS LRO; 2 ('LTR') (line 219520)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002C, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_002)
{

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

    {
        // R ON CS RLE; 2 ('LTR') (line 219521)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002C, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON CS RLO; 2 ('LTR') (line 219522)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002C, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON CS PDF; 2 ('LTR') (line 219523)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002C, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON CS BN; 2 ('LTR') (line 219524)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x002C, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON NSM LRE; 2 ('LTR') (line 219525)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0300, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON NSM LRO; 2 ('LTR') (line 219526)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0300, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON NSM RLE; 2 ('LTR') (line 219527)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0300, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON NSM RLO; 2 ('LTR') (line 219528)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0300, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON NSM PDF; 2 ('LTR') (line 219529)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0300, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON NSM BN; 2 ('LTR') (line 219530)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0300, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_003)
{

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

    {
        // R ON S LRE; 2 ('LTR') (line 219531)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0009, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON S LRO; 2 ('LTR') (line 219532)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0009, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON S RLE; 2 ('LTR') (line 219533)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0009, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON S RLO; 2 ('LTR') (line 219534)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0009, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON S PDF; 2 ('LTR') (line 219535)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0009, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON S BN; 2 ('LTR') (line 219536)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0009, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON WS LRE; 2 ('LTR') (line 219537)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0020, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON WS LRO; 2 ('LTR') (line 219538)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0020, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON WS RLE; 2 ('LTR') (line 219539)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0020, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON WS RLO; 2 ('LTR') (line 219540)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0020, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_004)
{

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

    {
        // R ON WS PDF; 2 ('LTR') (line 219541)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0020, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON WS BN; 2 ('LTR') (line 219542)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0020, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ON LRE; 2 ('LTR') (line 219543)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0021, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ON LRO; 2 ('LTR') (line 219544)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0021, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ON RLE; 2 ('LTR') (line 219545)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0021, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ON RLO; 2 ('LTR') (line 219546)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0021, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ON PDF; 2 ('LTR') (line 219547)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0021, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON ON BN; 2 ('LTR') (line 219548)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x0021, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON LRI LRE; 2 ('LTR') (line 219549)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2066, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON LRI LRO; 2 ('LTR') (line 219550)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2066, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_005)
{

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

    {
        // R ON LRI RLE; 2 ('LTR') (line 219551)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2066, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON LRI RLO; 2 ('LTR') (line 219552)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2066, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON LRI PDF; 2 ('LTR') (line 219553)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2066, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON LRI BN; 2 ('LTR') (line 219554)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2066, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON RLI LRE; 2 ('LTR') (line 219555)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2067, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON RLI LRO; 2 ('LTR') (line 219556)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2067, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON RLI RLE; 2 ('LTR') (line 219557)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2067, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON RLI RLO; 2 ('LTR') (line 219558)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2067, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON RLI PDF; 2 ('LTR') (line 219559)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2067, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON RLI BN; 2 ('LTR') (line 219560)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2067, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_006)
{

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

    {
        // R ON FSI LRE; 2 ('LTR') (line 219561)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2068, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON FSI LRO; 2 ('LTR') (line 219562)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2068, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON FSI RLE; 2 ('LTR') (line 219563)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2068, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON FSI RLO; 2 ('LTR') (line 219564)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2068, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON FSI PDF; 2 ('LTR') (line 219565)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2068, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON FSI BN; 2 ('LTR') (line 219566)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2068, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON PDI LRE; 2 ('LTR') (line 219567)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2069, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON PDI LRO; 2 ('LTR') (line 219568)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2069, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON PDI RLE; 2 ('LTR') (line 219569)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2069, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON PDI RLO; 2 ('LTR') (line 219570)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2069, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_007)
{

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

    {
        // R ON PDI PDF; 2 ('LTR') (line 219571)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2069, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R ON PDI BN; 2 ('LTR') (line 219572)
        std::vector<uint32_t> const cps = { 0x05BE, 0x0021, 0x2069, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI S LRE; 2 ('LTR') (line 219573)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0009, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI S LRO; 2 ('LTR') (line 219574)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0009, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI S RLE; 2 ('LTR') (line 219575)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0009, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI S RLO; 2 ('LTR') (line 219576)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0009, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI S PDF; 2 ('LTR') (line 219577)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0009, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI S BN; 2 ('LTR') (line 219578)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0009, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI WS LRE; 2 ('LTR') (line 219579)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0020, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI WS LRO; 2 ('LTR') (line 219580)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0020, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_008)
{

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

    {
        // R LRI WS RLE; 2 ('LTR') (line 219581)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0020, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI WS RLO; 2 ('LTR') (line 219582)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0020, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI WS PDF; 2 ('LTR') (line 219583)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0020, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI WS BN; 2 ('LTR') (line 219584)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x0020, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI LRI LRE; 2 ('LTR') (line 219585)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2066, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI LRI LRO; 2 ('LTR') (line 219586)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2066, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI LRI RLE; 2 ('LTR') (line 219587)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2066, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI LRI RLO; 2 ('LTR') (line 219588)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2066, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI LRI PDF; 2 ('LTR') (line 219589)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2066, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI LRI BN; 2 ('LTR') (line 219590)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2066, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_009)
{

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

    {
        // R LRI RLI LRE; 2 ('LTR') (line 219591)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2067, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI RLI LRO; 2 ('LTR') (line 219592)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2067, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI RLI RLE; 2 ('LTR') (line 219593)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2067, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI RLI RLO; 2 ('LTR') (line 219594)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2067, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI RLI PDF; 2 ('LTR') (line 219595)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2067, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI RLI BN; 2 ('LTR') (line 219596)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2067, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI FSI LRE; 2 ('LTR') (line 219597)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2068, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI FSI LRO; 2 ('LTR') (line 219598)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2068, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI FSI RLE; 2 ('LTR') (line 219599)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2068, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI FSI RLO; 2 ('LTR') (line 219600)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2068, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_010)
{

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

    {
        // R LRI FSI PDF; 2 ('LTR') (line 219601)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2068, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI FSI BN; 2 ('LTR') (line 219602)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2068, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI PDI LRE; 2 ('LTR') (line 219603)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2069, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI PDI LRO; 2 ('LTR') (line 219604)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2069, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI PDI RLE; 2 ('LTR') (line 219605)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2069, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI PDI RLO; 2 ('LTR') (line 219606)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2069, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI PDI PDF; 2 ('LTR') (line 219607)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2069, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R LRI PDI BN; 2 ('LTR') (line 219608)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2066, 0x2069, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI S LRE; 2 ('LTR') (line 219609)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0009, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI S LRO; 2 ('LTR') (line 219610)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0009, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_011)
{

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

    {
        // R RLI S RLE; 2 ('LTR') (line 219611)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0009, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI S RLO; 2 ('LTR') (line 219612)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0009, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI S PDF; 2 ('LTR') (line 219613)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0009, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI S BN; 2 ('LTR') (line 219614)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0009, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI WS LRE; 2 ('LTR') (line 219615)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0020, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI WS LRO; 2 ('LTR') (line 219616)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0020, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI WS RLE; 2 ('LTR') (line 219617)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0020, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI WS RLO; 2 ('LTR') (line 219618)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0020, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI WS PDF; 2 ('LTR') (line 219619)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0020, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI WS BN; 2 ('LTR') (line 219620)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x0020, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_012)
{

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

    {
        // R RLI LRI LRE; 2 ('LTR') (line 219621)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2066, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI LRI LRO; 2 ('LTR') (line 219622)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2066, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI LRI RLE; 2 ('LTR') (line 219623)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2066, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI LRI RLO; 2 ('LTR') (line 219624)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2066, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI LRI PDF; 2 ('LTR') (line 219625)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2066, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI LRI BN; 2 ('LTR') (line 219626)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2066, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI RLI LRE; 2 ('LTR') (line 219627)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2067, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI RLI LRO; 2 ('LTR') (line 219628)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2067, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI RLI RLE; 2 ('LTR') (line 219629)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2067, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI RLI RLO; 2 ('LTR') (line 219630)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2067, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_013)
{

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

    {
        // R RLI RLI PDF; 2 ('LTR') (line 219631)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2067, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI RLI BN; 2 ('LTR') (line 219632)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2067, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI FSI LRE; 2 ('LTR') (line 219633)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2068, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI FSI LRO; 2 ('LTR') (line 219634)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2068, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI FSI RLE; 2 ('LTR') (line 219635)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2068, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI FSI RLO; 2 ('LTR') (line 219636)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2068, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI FSI PDF; 2 ('LTR') (line 219637)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2068, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI FSI BN; 2 ('LTR') (line 219638)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2068, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI PDI LRE; 2 ('LTR') (line 219639)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2069, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI PDI LRO; 2 ('LTR') (line 219640)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2069, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_014)
{

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

    {
        // R RLI PDI RLE; 2 ('LTR') (line 219641)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2069, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI PDI RLO; 2 ('LTR') (line 219642)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2069, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI PDI PDF; 2 ('LTR') (line 219643)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2069, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R RLI PDI BN; 2 ('LTR') (line 219644)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2067, 0x2069, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI S LRE; 2 ('LTR') (line 219645)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0009, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI S LRO; 2 ('LTR') (line 219646)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0009, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI S RLE; 2 ('LTR') (line 219647)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0009, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI S RLO; 2 ('LTR') (line 219648)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0009, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI S PDF; 2 ('LTR') (line 219649)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0009, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI S BN; 2 ('LTR') (line 219650)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0009, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_015)
{

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

    {
        // R FSI WS LRE; 2 ('LTR') (line 219651)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0020, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI WS LRO; 2 ('LTR') (line 219652)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0020, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI WS RLE; 2 ('LTR') (line 219653)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0020, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI WS RLO; 2 ('LTR') (line 219654)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0020, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI WS PDF; 2 ('LTR') (line 219655)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0020, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI WS BN; 2 ('LTR') (line 219656)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x0020, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI LRI LRE; 2 ('LTR') (line 219657)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2066, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI LRI LRO; 2 ('LTR') (line 219658)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2066, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI LRI RLE; 2 ('LTR') (line 219659)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2066, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI LRI RLO; 2 ('LTR') (line 219660)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2066, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_016)
{

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

    {
        // R FSI LRI PDF; 2 ('LTR') (line 219661)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2066, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI LRI BN; 2 ('LTR') (line 219662)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2066, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI RLI LRE; 2 ('LTR') (line 219663)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2067, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI RLI LRO; 2 ('LTR') (line 219664)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2067, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI RLI RLE; 2 ('LTR') (line 219665)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2067, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI RLI RLO; 2 ('LTR') (line 219666)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2067, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI RLI PDF; 2 ('LTR') (line 219667)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2067, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI RLI BN; 2 ('LTR') (line 219668)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2067, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI FSI LRE; 2 ('LTR') (line 219669)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2068, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI FSI LRO; 2 ('LTR') (line 219670)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2068, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_017)
{

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

    {
        // R FSI FSI RLE; 2 ('LTR') (line 219671)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2068, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI FSI RLO; 2 ('LTR') (line 219672)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2068, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI FSI PDF; 2 ('LTR') (line 219673)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2068, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI FSI BN; 2 ('LTR') (line 219674)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2068, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI PDI LRE; 2 ('LTR') (line 219675)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2069, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI PDI LRO; 2 ('LTR') (line 219676)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2069, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI PDI RLE; 2 ('LTR') (line 219677)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2069, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI PDI RLO; 2 ('LTR') (line 219678)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2069, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI PDI PDF; 2 ('LTR') (line 219679)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2069, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R FSI PDI BN; 2 ('LTR') (line 219680)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2068, 0x2069, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_018)
{

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

    {
        // R PDI L LRE; 2 ('LTR') (line 219681)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0041, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI L LRO; 2 ('LTR') (line 219682)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0041, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI L RLE; 2 ('LTR') (line 219683)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0041, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI L RLO; 2 ('LTR') (line 219684)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0041, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI L PDF; 2 ('LTR') (line 219685)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0041, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI L BN; 2 ('LTR') (line 219686)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0041, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ES LRE; 2 ('LTR') (line 219687)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002B, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ES LRO; 2 ('LTR') (line 219688)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002B, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ES RLE; 2 ('LTR') (line 219689)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002B, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ES RLO; 2 ('LTR') (line 219690)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002B, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_019)
{

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

    {
        // R PDI ES PDF; 2 ('LTR') (line 219691)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002B, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ES BN; 2 ('LTR') (line 219692)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002B, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ET LRE; 2 ('LTR') (line 219693)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0023, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ET LRO; 2 ('LTR') (line 219694)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0023, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ET RLE; 2 ('LTR') (line 219695)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0023, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ET RLO; 2 ('LTR') (line 219696)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0023, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ET PDF; 2 ('LTR') (line 219697)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0023, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ET BN; 2 ('LTR') (line 219698)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0023, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI CS LRE; 2 ('LTR') (line 219699)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002C, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI CS LRO; 2 ('LTR') (line 219700)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002C, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_020)
{

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

    {
        // R PDI CS RLE; 2 ('LTR') (line 219701)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002C, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI CS RLO; 2 ('LTR') (line 219702)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002C, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI CS PDF; 2 ('LTR') (line 219703)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002C, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI CS BN; 2 ('LTR') (line 219704)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x002C, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI NSM LRE; 2 ('LTR') (line 219705)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0300, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI NSM LRO; 2 ('LTR') (line 219706)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0300, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI NSM RLE; 2 ('LTR') (line 219707)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0300, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI NSM RLO; 2 ('LTR') (line 219708)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0300, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI NSM PDF; 2 ('LTR') (line 219709)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0300, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI NSM BN; 2 ('LTR') (line 219710)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0300, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_021)
{

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

    {
        // R PDI S LRE; 2 ('LTR') (line 219711)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0009, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI S LRO; 2 ('LTR') (line 219712)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0009, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI S RLE; 2 ('LTR') (line 219713)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0009, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI S RLO; 2 ('LTR') (line 219714)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0009, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI S PDF; 2 ('LTR') (line 219715)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0009, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI S BN; 2 ('LTR') (line 219716)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0009, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI WS LRE; 2 ('LTR') (line 219717)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0020, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI WS LRO; 2 ('LTR') (line 219718)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0020, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI WS RLE; 2 ('LTR') (line 219719)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0020, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI WS RLO; 2 ('LTR') (line 219720)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0020, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_022)
{

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

    {
        // R PDI WS PDF; 2 ('LTR') (line 219721)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0020, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI WS BN; 2 ('LTR') (line 219722)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0020, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ON LRE; 2 ('LTR') (line 219723)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0021, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ON LRO; 2 ('LTR') (line 219724)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0021, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ON RLE; 2 ('LTR') (line 219725)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0021, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ON RLO; 2 ('LTR') (line 219726)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0021, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ON PDF; 2 ('LTR') (line 219727)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0021, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI ON BN; 2 ('LTR') (line 219728)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x0021, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI LRI LRE; 2 ('LTR') (line 219729)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2066, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI LRI LRO; 2 ('LTR') (line 219730)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2066, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_023)
{

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

    {
        // R PDI LRI RLE; 2 ('LTR') (line 219731)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2066, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI LRI RLO; 2 ('LTR') (line 219732)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2066, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI LRI PDF; 2 ('LTR') (line 219733)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2066, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI LRI BN; 2 ('LTR') (line 219734)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2066, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI RLI LRE; 2 ('LTR') (line 219735)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2067, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI RLI LRO; 2 ('LTR') (line 219736)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2067, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI RLI RLE; 2 ('LTR') (line 219737)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2067, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI RLI RLO; 2 ('LTR') (line 219738)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2067, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI RLI PDF; 2 ('LTR') (line 219739)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2067, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI RLI BN; 2 ('LTR') (line 219740)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2067, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_024)
{

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

    {
        // R PDI FSI LRE; 2 ('LTR') (line 219741)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2068, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI FSI LRO; 2 ('LTR') (line 219742)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2068, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI FSI RLE; 2 ('LTR') (line 219743)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2068, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI FSI RLO; 2 ('LTR') (line 219744)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2068, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI FSI PDF; 2 ('LTR') (line 219745)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2068, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI FSI BN; 2 ('LTR') (line 219746)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2068, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI PDI LRE; 2 ('LTR') (line 219747)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2069, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI PDI LRO; 2 ('LTR') (line 219748)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2069, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI PDI RLE; 2 ('LTR') (line 219749)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2069, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI PDI RLO; 2 ('LTR') (line 219750)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2069, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_025)
{

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

    {
        // R PDI PDI PDF; 2 ('LTR') (line 219751)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2069, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // R PDI PDI BN; 2 ('LTR') (line 219752)
        std::vector<uint32_t> const cps = { 0x05BE, 0x2069, 0x2069, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L L LRE; 2 ('LTR') (line 219753)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0041, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L L LRO; 2 ('LTR') (line 219754)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0041, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L L RLE; 2 ('LTR') (line 219755)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0041, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L L RLO; 2 ('LTR') (line 219756)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0041, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L L PDF; 2 ('LTR') (line 219757)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0041, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L L BN; 2 ('LTR') (line 219758)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0041, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L EN LRE; 2 ('LTR') (line 219759)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0030, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L EN LRO; 2 ('LTR') (line 219760)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0030, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_026)
{

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

    {
        // AL L EN RLE; 2 ('LTR') (line 219761)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0030, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L EN RLO; 2 ('LTR') (line 219762)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0030, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L EN PDF; 2 ('LTR') (line 219763)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0030, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L EN BN; 2 ('LTR') (line 219764)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0030, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ES LRE; 2 ('LTR') (line 219765)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002B, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ES LRO; 2 ('LTR') (line 219766)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002B, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ES RLE; 2 ('LTR') (line 219767)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002B, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ES RLO; 2 ('LTR') (line 219768)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002B, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ES PDF; 2 ('LTR') (line 219769)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002B, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ES BN; 2 ('LTR') (line 219770)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002B, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_027)
{

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

    {
        // AL L ET LRE; 2 ('LTR') (line 219771)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0023, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ET LRO; 2 ('LTR') (line 219772)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0023, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ET RLE; 2 ('LTR') (line 219773)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0023, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ET RLO; 2 ('LTR') (line 219774)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0023, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ET PDF; 2 ('LTR') (line 219775)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0023, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ET BN; 2 ('LTR') (line 219776)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0023, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L CS LRE; 2 ('LTR') (line 219777)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002C, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L CS LRO; 2 ('LTR') (line 219778)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002C, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L CS RLE; 2 ('LTR') (line 219779)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002C, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L CS RLO; 2 ('LTR') (line 219780)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002C, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_028)
{

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

    {
        // AL L CS PDF; 2 ('LTR') (line 219781)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002C, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L CS BN; 2 ('LTR') (line 219782)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x002C, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L NSM LRE; 2 ('LTR') (line 219783)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0300, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L NSM LRO; 2 ('LTR') (line 219784)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0300, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L NSM RLE; 2 ('LTR') (line 219785)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0300, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L NSM RLO; 2 ('LTR') (line 219786)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0300, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L NSM PDF; 2 ('LTR') (line 219787)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0300, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L NSM BN; 2 ('LTR') (line 219788)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0300, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L S LRE; 2 ('LTR') (line 219789)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0009, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L S LRO; 2 ('LTR') (line 219790)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0009, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_029)
{

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

    {
        // AL L S RLE; 2 ('LTR') (line 219791)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0009, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L S RLO; 2 ('LTR') (line 219792)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0009, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L S PDF; 2 ('LTR') (line 219793)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0009, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L S BN; 2 ('LTR') (line 219794)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0009, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L WS LRE; 2 ('LTR') (line 219795)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0020, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L WS LRO; 2 ('LTR') (line 219796)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0020, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L WS RLE; 2 ('LTR') (line 219797)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0020, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L WS RLO; 2 ('LTR') (line 219798)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0020, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L WS PDF; 2 ('LTR') (line 219799)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0020, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L WS BN; 2 ('LTR') (line 219800)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0020, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_030)
{

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

    {
        // AL L ON LRE; 2 ('LTR') (line 219801)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0021, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ON LRO; 2 ('LTR') (line 219802)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0021, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ON RLE; 2 ('LTR') (line 219803)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0021, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ON RLO; 2 ('LTR') (line 219804)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0021, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ON PDF; 2 ('LTR') (line 219805)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0021, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L ON BN; 2 ('LTR') (line 219806)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x0021, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L LRI LRE; 2 ('LTR') (line 219807)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2066, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L LRI LRO; 2 ('LTR') (line 219808)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2066, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L LRI RLE; 2 ('LTR') (line 219809)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2066, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L LRI RLO; 2 ('LTR') (line 219810)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2066, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_031)
{

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

    {
        // AL L LRI PDF; 2 ('LTR') (line 219811)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2066, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L LRI BN; 2 ('LTR') (line 219812)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2066, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L RLI LRE; 2 ('LTR') (line 219813)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2067, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L RLI LRO; 2 ('LTR') (line 219814)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2067, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L RLI RLE; 2 ('LTR') (line 219815)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2067, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L RLI RLO; 2 ('LTR') (line 219816)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2067, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L RLI PDF; 2 ('LTR') (line 219817)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2067, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L RLI BN; 2 ('LTR') (line 219818)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2067, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L FSI LRE; 2 ('LTR') (line 219819)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2068, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L FSI LRO; 2 ('LTR') (line 219820)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2068, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_032)
{

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

    {
        // AL L FSI RLE; 2 ('LTR') (line 219821)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2068, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L FSI RLO; 2 ('LTR') (line 219822)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2068, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L FSI PDF; 2 ('LTR') (line 219823)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2068, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L FSI BN; 2 ('LTR') (line 219824)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2068, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L PDI LRE; 2 ('LTR') (line 219825)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2069, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L PDI LRO; 2 ('LTR') (line 219826)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2069, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L PDI RLE; 2 ('LTR') (line 219827)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2069, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L PDI RLO; 2 ('LTR') (line 219828)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2069, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L PDI PDF; 2 ('LTR') (line 219829)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2069, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL L PDI BN; 2 ('LTR') (line 219830)
        std::vector<uint32_t> const cps = { 0x0608, 0x0041, 0x2069, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_033)
{

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

    {
        // AL ES L LRE; 2 ('LTR') (line 219831)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0041, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES L LRO; 2 ('LTR') (line 219832)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0041, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES L RLE; 2 ('LTR') (line 219833)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0041, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES L RLO; 2 ('LTR') (line 219834)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0041, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES L PDF; 2 ('LTR') (line 219835)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0041, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES L BN; 2 ('LTR') (line 219836)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0041, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ES LRE; 2 ('LTR') (line 219837)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002B, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ES LRO; 2 ('LTR') (line 219838)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002B, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ES RLE; 2 ('LTR') (line 219839)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002B, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ES RLO; 2 ('LTR') (line 219840)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002B, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_034)
{

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

    {
        // AL ES ES PDF; 2 ('LTR') (line 219841)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002B, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ES BN; 2 ('LTR') (line 219842)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002B, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ET LRE; 2 ('LTR') (line 219843)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0023, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ET LRO; 2 ('LTR') (line 219844)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0023, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ET RLE; 2 ('LTR') (line 219845)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0023, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ET RLO; 2 ('LTR') (line 219846)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0023, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ET PDF; 2 ('LTR') (line 219847)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0023, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ET BN; 2 ('LTR') (line 219848)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0023, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES CS LRE; 2 ('LTR') (line 219849)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002C, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES CS LRO; 2 ('LTR') (line 219850)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002C, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_035)
{

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

    {
        // AL ES CS RLE; 2 ('LTR') (line 219851)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002C, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES CS RLO; 2 ('LTR') (line 219852)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002C, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES CS PDF; 2 ('LTR') (line 219853)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002C, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES CS BN; 2 ('LTR') (line 219854)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x002C, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES NSM LRE; 2 ('LTR') (line 219855)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0300, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES NSM LRO; 2 ('LTR') (line 219856)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0300, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES NSM RLE; 2 ('LTR') (line 219857)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0300, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES NSM RLO; 2 ('LTR') (line 219858)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0300, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES NSM PDF; 2 ('LTR') (line 219859)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0300, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES NSM BN; 2 ('LTR') (line 219860)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0300, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_036)
{

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

    {
        // AL ES S LRE; 2 ('LTR') (line 219861)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0009, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES S LRO; 2 ('LTR') (line 219862)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0009, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES S RLE; 2 ('LTR') (line 219863)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0009, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES S RLO; 2 ('LTR') (line 219864)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0009, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES S PDF; 2 ('LTR') (line 219865)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0009, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES S BN; 2 ('LTR') (line 219866)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0009, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES WS LRE; 2 ('LTR') (line 219867)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0020, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES WS LRO; 2 ('LTR') (line 219868)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0020, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES WS RLE; 2 ('LTR') (line 219869)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0020, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES WS RLO; 2 ('LTR') (line 219870)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0020, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_037)
{

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

    {
        // AL ES WS PDF; 2 ('LTR') (line 219871)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0020, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES WS BN; 2 ('LTR') (line 219872)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0020, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ON LRE; 2 ('LTR') (line 219873)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0021, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ON LRO; 2 ('LTR') (line 219874)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0021, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ON RLE; 2 ('LTR') (line 219875)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0021, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ON RLO; 2 ('LTR') (line 219876)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0021, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ON PDF; 2 ('LTR') (line 219877)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0021, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES ON BN; 2 ('LTR') (line 219878)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x0021, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES LRI LRE; 2 ('LTR') (line 219879)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2066, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES LRI LRO; 2 ('LTR') (line 219880)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2066, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_038)
{

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

    {
        // AL ES LRI RLE; 2 ('LTR') (line 219881)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2066, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES LRI RLO; 2 ('LTR') (line 219882)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2066, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES LRI PDF; 2 ('LTR') (line 219883)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2066, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES LRI BN; 2 ('LTR') (line 219884)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2066, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES RLI LRE; 2 ('LTR') (line 219885)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2067, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES RLI LRO; 2 ('LTR') (line 219886)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2067, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES RLI RLE; 2 ('LTR') (line 219887)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2067, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES RLI RLO; 2 ('LTR') (line 219888)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2067, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES RLI PDF; 2 ('LTR') (line 219889)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2067, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES RLI BN; 2 ('LTR') (line 219890)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2067, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_039)
{

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

    {
        // AL ES FSI LRE; 2 ('LTR') (line 219891)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2068, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES FSI LRO; 2 ('LTR') (line 219892)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2068, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES FSI RLE; 2 ('LTR') (line 219893)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2068, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES FSI RLO; 2 ('LTR') (line 219894)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2068, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES FSI PDF; 2 ('LTR') (line 219895)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2068, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES FSI BN; 2 ('LTR') (line 219896)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2068, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES PDI LRE; 2 ('LTR') (line 219897)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2069, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES PDI LRO; 2 ('LTR') (line 219898)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2069, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES PDI RLE; 2 ('LTR') (line 219899)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2069, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES PDI RLO; 2 ('LTR') (line 219900)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2069, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_040)
{

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

    {
        // AL ES PDI PDF; 2 ('LTR') (line 219901)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2069, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ES PDI BN; 2 ('LTR') (line 219902)
        std::vector<uint32_t> const cps = { 0x0608, 0x002B, 0x2069, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET L LRE; 2 ('LTR') (line 219903)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0041, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET L LRO; 2 ('LTR') (line 219904)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0041, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET L RLE; 2 ('LTR') (line 219905)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0041, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET L RLO; 2 ('LTR') (line 219906)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0041, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET L PDF; 2 ('LTR') (line 219907)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0041, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET L BN; 2 ('LTR') (line 219908)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0041, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ES LRE; 2 ('LTR') (line 219909)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002B, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ES LRO; 2 ('LTR') (line 219910)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002B, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_041)
{

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

    {
        // AL ET ES RLE; 2 ('LTR') (line 219911)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002B, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ES RLO; 2 ('LTR') (line 219912)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002B, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ES PDF; 2 ('LTR') (line 219913)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002B, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ES BN; 2 ('LTR') (line 219914)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002B, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ET LRE; 2 ('LTR') (line 219915)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0023, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ET LRO; 2 ('LTR') (line 219916)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0023, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ET RLE; 2 ('LTR') (line 219917)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0023, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ET RLO; 2 ('LTR') (line 219918)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0023, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ET PDF; 2 ('LTR') (line 219919)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0023, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ET BN; 2 ('LTR') (line 219920)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0023, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_042)
{

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

    {
        // AL ET CS LRE; 2 ('LTR') (line 219921)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002C, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET CS LRO; 2 ('LTR') (line 219922)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002C, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET CS RLE; 2 ('LTR') (line 219923)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002C, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET CS RLO; 2 ('LTR') (line 219924)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002C, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET CS PDF; 2 ('LTR') (line 219925)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002C, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET CS BN; 2 ('LTR') (line 219926)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x002C, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET NSM LRE; 2 ('LTR') (line 219927)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0300, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET NSM LRO; 2 ('LTR') (line 219928)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0300, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET NSM RLE; 2 ('LTR') (line 219929)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0300, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET NSM RLO; 2 ('LTR') (line 219930)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0300, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_043)
{

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

    {
        // AL ET NSM PDF; 2 ('LTR') (line 219931)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0300, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET NSM BN; 2 ('LTR') (line 219932)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0300, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET S LRE; 2 ('LTR') (line 219933)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0009, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET S LRO; 2 ('LTR') (line 219934)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0009, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET S RLE; 2 ('LTR') (line 219935)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0009, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET S RLO; 2 ('LTR') (line 219936)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0009, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET S PDF; 2 ('LTR') (line 219937)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0009, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET S BN; 2 ('LTR') (line 219938)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0009, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET WS LRE; 2 ('LTR') (line 219939)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0020, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET WS LRO; 2 ('LTR') (line 219940)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0020, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_044)
{

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

    {
        // AL ET WS RLE; 2 ('LTR') (line 219941)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0020, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET WS RLO; 2 ('LTR') (line 219942)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0020, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET WS PDF; 2 ('LTR') (line 219943)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0020, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET WS BN; 2 ('LTR') (line 219944)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0020, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ON LRE; 2 ('LTR') (line 219945)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0021, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ON LRO; 2 ('LTR') (line 219946)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0021, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ON RLE; 2 ('LTR') (line 219947)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0021, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ON RLO; 2 ('LTR') (line 219948)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0021, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ON PDF; 2 ('LTR') (line 219949)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0021, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET ON BN; 2 ('LTR') (line 219950)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x0021, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_045)
{

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

    {
        // AL ET LRI LRE; 2 ('LTR') (line 219951)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2066, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET LRI LRO; 2 ('LTR') (line 219952)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2066, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET LRI RLE; 2 ('LTR') (line 219953)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2066, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET LRI RLO; 2 ('LTR') (line 219954)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2066, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET LRI PDF; 2 ('LTR') (line 219955)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2066, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET LRI BN; 2 ('LTR') (line 219956)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2066, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET RLI LRE; 2 ('LTR') (line 219957)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2067, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET RLI LRO; 2 ('LTR') (line 219958)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2067, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET RLI RLE; 2 ('LTR') (line 219959)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2067, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET RLI RLO; 2 ('LTR') (line 219960)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2067, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_046)
{

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

    {
        // AL ET RLI PDF; 2 ('LTR') (line 219961)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2067, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET RLI BN; 2 ('LTR') (line 219962)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2067, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET FSI LRE; 2 ('LTR') (line 219963)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2068, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET FSI LRO; 2 ('LTR') (line 219964)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2068, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET FSI RLE; 2 ('LTR') (line 219965)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2068, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET FSI RLO; 2 ('LTR') (line 219966)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2068, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET FSI PDF; 2 ('LTR') (line 219967)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2068, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET FSI BN; 2 ('LTR') (line 219968)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2068, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET PDI LRE; 2 ('LTR') (line 219969)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2069, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET PDI LRO; 2 ('LTR') (line 219970)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2069, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_047)
{

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

    {
        // AL ET PDI RLE; 2 ('LTR') (line 219971)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2069, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET PDI RLO; 2 ('LTR') (line 219972)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2069, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET PDI PDF; 2 ('LTR') (line 219973)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2069, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL ET PDI BN; 2 ('LTR') (line 219974)
        std::vector<uint32_t> const cps = { 0x0608, 0x0023, 0x2069, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS L LRE; 2 ('LTR') (line 219975)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0041, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS L LRO; 2 ('LTR') (line 219976)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0041, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS L RLE; 2 ('LTR') (line 219977)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0041, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS L RLO; 2 ('LTR') (line 219978)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0041, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS L PDF; 2 ('LTR') (line 219979)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0041, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS L BN; 2 ('LTR') (line 219980)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0041, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_048)
{

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

    {
        // AL CS ES LRE; 2 ('LTR') (line 219981)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002B, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ES LRO; 2 ('LTR') (line 219982)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002B, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ES RLE; 2 ('LTR') (line 219983)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002B, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ES RLO; 2 ('LTR') (line 219984)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002B, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ES PDF; 2 ('LTR') (line 219985)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002B, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ES BN; 2 ('LTR') (line 219986)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002B, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ET LRE; 2 ('LTR') (line 219987)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0023, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ET LRO; 2 ('LTR') (line 219988)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0023, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ET RLE; 2 ('LTR') (line 219989)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0023, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ET RLO; 2 ('LTR') (line 219990)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0023, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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_439_049)
{

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

    {
        // AL CS ET PDF; 2 ('LTR') (line 219991)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0023, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS ET BN; 2 ('LTR') (line 219992)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0023, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS CS LRE; 2 ('LTR') (line 219993)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002C, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS CS LRO; 2 ('LTR') (line 219994)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002C, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS CS RLE; 2 ('LTR') (line 219995)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002C, 0x202B };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS CS RLO; 2 ('LTR') (line 219996)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002C, 0x202E };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS CS PDF; 2 ('LTR') (line 219997)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002C, 0x202C };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS CS BN; 2 ('LTR') (line 219998)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x002C, 0x00AD };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS NSM LRE; 2 ('LTR') (line 219999)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0300, 0x202A };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)cps[idx])
                    << std::hex
                    << " 0x" << reordered_2[i]
                    << " 0x" << cps[idx]
                    << std::dec << " i=" << i;
            }
            ++i;
        }
        EXPECT_EQ(i, (int)reordered_2.size());
    }

    {
        // AL CS NSM LRO; 2 ('LTR') (line 220000)
        std::vector<uint32_t> const cps = { 0x0608, 0x002C, 0x0300, 0x202D };
        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], (int)cps[idx])
                    << std::hex
                    << " 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], (int)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: Ryan-rsm-McKenzie/text

max_issues_repo_name: Ryan-rsm-McKenzie/text

max_forks_repo_name: Ryan-rsm-McKenzie/text