text: // Warning! This file is autogenerated.
  #include <boost/text/bidirectional.hpp>
  
  #include "bidi_tests.hpp"
  
  #include <gtest/gtest.h>
  
  #include <algorithm>
  
  
  std::vector<int> expected_levels;
  std::vector<int> expected_reordered_indices;
  
  TEST(bidi, bidi_508_000)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI ET PDI RLO; 4 ('RTL') (line 254001)
          std::vector<uint32_t> const cps = { 0x2066, 0x0023, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ET PDI PDF; 4 ('RTL') (line 254002)
          std::vector<uint32_t> const cps = { 0x2066, 0x0023, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ET PDI BN; 4 ('RTL') (line 254003)
          std::vector<uint32_t> const cps = { 0x2066, 0x0023, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS S LRE; 4 ('RTL') (line 254004)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS S LRO; 4 ('RTL') (line 254005)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS S RLE; 4 ('RTL') (line 254006)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS S RLO; 4 ('RTL') (line 254007)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS S PDF; 4 ('RTL') (line 254008)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS S BN; 4 ('RTL') (line 254009)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS WS LRE; 4 ('RTL') (line 254010)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_001)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI CS WS LRO; 4 ('RTL') (line 254011)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS WS RLE; 4 ('RTL') (line 254012)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS WS RLO; 4 ('RTL') (line 254013)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS WS PDF; 4 ('RTL') (line 254014)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS WS BN; 4 ('RTL') (line 254015)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS LRI LRE; 4 ('RTL') (line 254016)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS LRI LRO; 4 ('RTL') (line 254017)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS LRI RLE; 4 ('RTL') (line 254018)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS LRI RLO; 4 ('RTL') (line 254019)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS LRI PDF; 4 ('RTL') (line 254020)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_002)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI CS LRI BN; 4 ('RTL') (line 254021)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS RLI LRE; 4 ('RTL') (line 254022)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS RLI LRO; 4 ('RTL') (line 254023)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS RLI RLE; 4 ('RTL') (line 254024)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS RLI RLO; 4 ('RTL') (line 254025)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS RLI PDF; 4 ('RTL') (line 254026)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS RLI BN; 4 ('RTL') (line 254027)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS FSI LRE; 4 ('RTL') (line 254028)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS FSI LRO; 4 ('RTL') (line 254029)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS FSI RLE; 4 ('RTL') (line 254030)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_003)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI CS FSI RLO; 4 ('RTL') (line 254031)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS FSI PDF; 4 ('RTL') (line 254032)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS FSI BN; 4 ('RTL') (line 254033)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS PDI LRE; 4 ('RTL') (line 254034)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS PDI LRO; 4 ('RTL') (line 254035)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS PDI RLE; 4 ('RTL') (line 254036)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS PDI RLO; 4 ('RTL') (line 254037)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS PDI PDF; 4 ('RTL') (line 254038)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI CS PDI BN; 4 ('RTL') (line 254039)
          std::vector<uint32_t> const cps = { 0x2066, 0x002C, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM S LRE; 4 ('RTL') (line 254040)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_004)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI NSM S LRO; 4 ('RTL') (line 254041)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM S RLE; 4 ('RTL') (line 254042)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM S RLO; 4 ('RTL') (line 254043)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM S PDF; 4 ('RTL') (line 254044)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM S BN; 4 ('RTL') (line 254045)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM WS LRE; 4 ('RTL') (line 254046)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM WS LRO; 4 ('RTL') (line 254047)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM WS RLE; 4 ('RTL') (line 254048)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM WS RLO; 4 ('RTL') (line 254049)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM WS PDF; 4 ('RTL') (line 254050)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_005)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI NSM WS BN; 4 ('RTL') (line 254051)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM LRI LRE; 4 ('RTL') (line 254052)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM LRI LRO; 4 ('RTL') (line 254053)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM LRI RLE; 4 ('RTL') (line 254054)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM LRI RLO; 4 ('RTL') (line 254055)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM LRI PDF; 4 ('RTL') (line 254056)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM LRI BN; 4 ('RTL') (line 254057)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM RLI LRE; 4 ('RTL') (line 254058)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM RLI LRO; 4 ('RTL') (line 254059)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM RLI RLE; 4 ('RTL') (line 254060)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_006)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI NSM RLI RLO; 4 ('RTL') (line 254061)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM RLI PDF; 4 ('RTL') (line 254062)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM RLI BN; 4 ('RTL') (line 254063)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM FSI LRE; 4 ('RTL') (line 254064)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM FSI LRO; 4 ('RTL') (line 254065)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM FSI RLE; 4 ('RTL') (line 254066)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM FSI RLO; 4 ('RTL') (line 254067)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM FSI PDF; 4 ('RTL') (line 254068)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM FSI BN; 4 ('RTL') (line 254069)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM PDI LRE; 4 ('RTL') (line 254070)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_007)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI NSM PDI LRO; 4 ('RTL') (line 254071)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM PDI RLE; 4 ('RTL') (line 254072)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM PDI RLO; 4 ('RTL') (line 254073)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM PDI PDF; 4 ('RTL') (line 254074)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI NSM PDI BN; 4 ('RTL') (line 254075)
          std::vector<uint32_t> const cps = { 0x2066, 0x0300, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON S LRE; 4 ('RTL') (line 254076)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON S LRO; 4 ('RTL') (line 254077)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON S RLE; 4 ('RTL') (line 254078)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON S RLO; 4 ('RTL') (line 254079)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON S PDF; 4 ('RTL') (line 254080)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_008)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI ON S BN; 4 ('RTL') (line 254081)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON WS LRE; 4 ('RTL') (line 254082)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON WS LRO; 4 ('RTL') (line 254083)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON WS RLE; 4 ('RTL') (line 254084)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON WS RLO; 4 ('RTL') (line 254085)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON WS PDF; 4 ('RTL') (line 254086)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON WS BN; 4 ('RTL') (line 254087)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON LRI LRE; 4 ('RTL') (line 254088)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON LRI LRO; 4 ('RTL') (line 254089)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON LRI RLE; 4 ('RTL') (line 254090)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_009)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI ON LRI RLO; 4 ('RTL') (line 254091)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON LRI PDF; 4 ('RTL') (line 254092)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON LRI BN; 4 ('RTL') (line 254093)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON RLI LRE; 4 ('RTL') (line 254094)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON RLI LRO; 4 ('RTL') (line 254095)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON RLI RLE; 4 ('RTL') (line 254096)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON RLI RLO; 4 ('RTL') (line 254097)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON RLI PDF; 4 ('RTL') (line 254098)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON RLI BN; 4 ('RTL') (line 254099)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON FSI LRE; 4 ('RTL') (line 254100)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_010)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI ON FSI LRO; 4 ('RTL') (line 254101)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON FSI RLE; 4 ('RTL') (line 254102)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON FSI RLO; 4 ('RTL') (line 254103)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON FSI PDF; 4 ('RTL') (line 254104)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON FSI BN; 4 ('RTL') (line 254105)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON PDI LRE; 4 ('RTL') (line 254106)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON PDI LRO; 4 ('RTL') (line 254107)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON PDI RLE; 4 ('RTL') (line 254108)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON PDI RLO; 4 ('RTL') (line 254109)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // LRI ON PDI PDF; 4 ('RTL') (line 254110)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_011)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // LRI ON PDI BN; 4 ('RTL') (line 254111)
          std::vector<uint32_t> const cps = { 0x2066, 0x0021, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L S LRE; 4 ('RTL') (line 254112)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L S LRO; 4 ('RTL') (line 254113)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L S RLE; 4 ('RTL') (line 254114)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L S RLO; 4 ('RTL') (line 254115)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L S PDF; 4 ('RTL') (line 254116)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L S BN; 4 ('RTL') (line 254117)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L WS LRE; 4 ('RTL') (line 254118)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L WS LRO; 4 ('RTL') (line 254119)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L WS RLE; 4 ('RTL') (line 254120)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_012)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI L WS RLO; 4 ('RTL') (line 254121)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L WS PDF; 4 ('RTL') (line 254122)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L WS BN; 4 ('RTL') (line 254123)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L LRI LRE; 4 ('RTL') (line 254124)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L LRI LRO; 4 ('RTL') (line 254125)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L LRI RLE; 4 ('RTL') (line 254126)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L LRI RLO; 4 ('RTL') (line 254127)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L LRI PDF; 4 ('RTL') (line 254128)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L LRI BN; 4 ('RTL') (line 254129)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L RLI LRE; 4 ('RTL') (line 254130)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_013)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI L RLI LRO; 4 ('RTL') (line 254131)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L RLI RLE; 4 ('RTL') (line 254132)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L RLI RLO; 4 ('RTL') (line 254133)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L RLI PDF; 4 ('RTL') (line 254134)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L RLI BN; 4 ('RTL') (line 254135)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L FSI LRE; 4 ('RTL') (line 254136)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L FSI LRO; 4 ('RTL') (line 254137)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L FSI RLE; 4 ('RTL') (line 254138)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L FSI RLO; 4 ('RTL') (line 254139)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L FSI PDF; 4 ('RTL') (line 254140)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_014)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI L FSI BN; 4 ('RTL') (line 254141)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L PDI LRE; 4 ('RTL') (line 254142)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L PDI LRO; 4 ('RTL') (line 254143)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L PDI RLE; 4 ('RTL') (line 254144)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L PDI RLO; 4 ('RTL') (line 254145)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L PDI PDF; 4 ('RTL') (line 254146)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI L PDI BN; 4 ('RTL') (line 254147)
          std::vector<uint32_t> const cps = { 0x2068, 0x0041, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN S LRE; 4 ('RTL') (line 254148)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN S LRO; 4 ('RTL') (line 254149)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN S RLE; 4 ('RTL') (line 254150)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_015)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI EN S RLO; 4 ('RTL') (line 254151)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN S PDF; 4 ('RTL') (line 254152)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN S BN; 4 ('RTL') (line 254153)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN WS LRE; 4 ('RTL') (line 254154)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN WS LRO; 4 ('RTL') (line 254155)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN WS RLE; 4 ('RTL') (line 254156)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN WS RLO; 4 ('RTL') (line 254157)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN WS PDF; 4 ('RTL') (line 254158)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN WS BN; 4 ('RTL') (line 254159)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN LRI LRE; 4 ('RTL') (line 254160)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_016)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI EN LRI LRO; 4 ('RTL') (line 254161)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN LRI RLE; 4 ('RTL') (line 254162)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN LRI RLO; 4 ('RTL') (line 254163)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN LRI PDF; 4 ('RTL') (line 254164)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN LRI BN; 4 ('RTL') (line 254165)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN RLI LRE; 4 ('RTL') (line 254166)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN RLI LRO; 4 ('RTL') (line 254167)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN RLI RLE; 4 ('RTL') (line 254168)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN RLI RLO; 4 ('RTL') (line 254169)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN RLI PDF; 4 ('RTL') (line 254170)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_017)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI EN RLI BN; 4 ('RTL') (line 254171)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN FSI LRE; 4 ('RTL') (line 254172)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN FSI LRO; 4 ('RTL') (line 254173)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN FSI RLE; 4 ('RTL') (line 254174)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN FSI RLO; 4 ('RTL') (line 254175)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN FSI PDF; 4 ('RTL') (line 254176)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN FSI BN; 4 ('RTL') (line 254177)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN PDI LRE; 4 ('RTL') (line 254178)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN PDI LRO; 4 ('RTL') (line 254179)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN PDI RLE; 4 ('RTL') (line 254180)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_018)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI EN PDI RLO; 4 ('RTL') (line 254181)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN PDI PDF; 4 ('RTL') (line 254182)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI EN PDI BN; 4 ('RTL') (line 254183)
          std::vector<uint32_t> const cps = { 0x2068, 0x0030, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES S LRE; 4 ('RTL') (line 254184)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES S LRO; 4 ('RTL') (line 254185)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES S RLE; 4 ('RTL') (line 254186)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES S RLO; 4 ('RTL') (line 254187)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES S PDF; 4 ('RTL') (line 254188)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES S BN; 4 ('RTL') (line 254189)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES WS LRE; 4 ('RTL') (line 254190)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_019)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ES WS LRO; 4 ('RTL') (line 254191)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES WS RLE; 4 ('RTL') (line 254192)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES WS RLO; 4 ('RTL') (line 254193)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES WS PDF; 4 ('RTL') (line 254194)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES WS BN; 4 ('RTL') (line 254195)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES LRI LRE; 4 ('RTL') (line 254196)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES LRI LRO; 4 ('RTL') (line 254197)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES LRI RLE; 4 ('RTL') (line 254198)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES LRI RLO; 4 ('RTL') (line 254199)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES LRI PDF; 4 ('RTL') (line 254200)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_020)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ES LRI BN; 4 ('RTL') (line 254201)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES RLI LRE; 4 ('RTL') (line 254202)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES RLI LRO; 4 ('RTL') (line 254203)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES RLI RLE; 4 ('RTL') (line 254204)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES RLI RLO; 4 ('RTL') (line 254205)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES RLI PDF; 4 ('RTL') (line 254206)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES RLI BN; 4 ('RTL') (line 254207)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES FSI LRE; 4 ('RTL') (line 254208)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES FSI LRO; 4 ('RTL') (line 254209)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES FSI RLE; 4 ('RTL') (line 254210)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_021)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ES FSI RLO; 4 ('RTL') (line 254211)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES FSI PDF; 4 ('RTL') (line 254212)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES FSI BN; 4 ('RTL') (line 254213)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES PDI LRE; 4 ('RTL') (line 254214)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES PDI LRO; 4 ('RTL') (line 254215)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES PDI RLE; 4 ('RTL') (line 254216)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES PDI RLO; 4 ('RTL') (line 254217)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES PDI PDF; 4 ('RTL') (line 254218)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ES PDI BN; 4 ('RTL') (line 254219)
          std::vector<uint32_t> const cps = { 0x2068, 0x002B, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET S LRE; 4 ('RTL') (line 254220)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_022)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ET S LRO; 4 ('RTL') (line 254221)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET S RLE; 4 ('RTL') (line 254222)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET S RLO; 4 ('RTL') (line 254223)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET S PDF; 4 ('RTL') (line 254224)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET S BN; 4 ('RTL') (line 254225)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET WS LRE; 4 ('RTL') (line 254226)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET WS LRO; 4 ('RTL') (line 254227)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET WS RLE; 4 ('RTL') (line 254228)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET WS RLO; 4 ('RTL') (line 254229)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET WS PDF; 4 ('RTL') (line 254230)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_023)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ET WS BN; 4 ('RTL') (line 254231)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET LRI LRE; 4 ('RTL') (line 254232)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET LRI LRO; 4 ('RTL') (line 254233)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET LRI RLE; 4 ('RTL') (line 254234)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET LRI RLO; 4 ('RTL') (line 254235)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET LRI PDF; 4 ('RTL') (line 254236)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET LRI BN; 4 ('RTL') (line 254237)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET RLI LRE; 4 ('RTL') (line 254238)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET RLI LRO; 4 ('RTL') (line 254239)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET RLI RLE; 4 ('RTL') (line 254240)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_024)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ET RLI RLO; 4 ('RTL') (line 254241)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET RLI PDF; 4 ('RTL') (line 254242)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET RLI BN; 4 ('RTL') (line 254243)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET FSI LRE; 4 ('RTL') (line 254244)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET FSI LRO; 4 ('RTL') (line 254245)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET FSI RLE; 4 ('RTL') (line 254246)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET FSI RLO; 4 ('RTL') (line 254247)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET FSI PDF; 4 ('RTL') (line 254248)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET FSI BN; 4 ('RTL') (line 254249)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET PDI LRE; 4 ('RTL') (line 254250)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_025)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ET PDI LRO; 4 ('RTL') (line 254251)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET PDI RLE; 4 ('RTL') (line 254252)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET PDI RLO; 4 ('RTL') (line 254253)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET PDI PDF; 4 ('RTL') (line 254254)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ET PDI BN; 4 ('RTL') (line 254255)
          std::vector<uint32_t> const cps = { 0x2068, 0x0023, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS S LRE; 4 ('RTL') (line 254256)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS S LRO; 4 ('RTL') (line 254257)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS S RLE; 4 ('RTL') (line 254258)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS S RLO; 4 ('RTL') (line 254259)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS S PDF; 4 ('RTL') (line 254260)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_026)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI CS S BN; 4 ('RTL') (line 254261)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS WS LRE; 4 ('RTL') (line 254262)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS WS LRO; 4 ('RTL') (line 254263)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS WS RLE; 4 ('RTL') (line 254264)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS WS RLO; 4 ('RTL') (line 254265)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS WS PDF; 4 ('RTL') (line 254266)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS WS BN; 4 ('RTL') (line 254267)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS LRI LRE; 4 ('RTL') (line 254268)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS LRI LRO; 4 ('RTL') (line 254269)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS LRI RLE; 4 ('RTL') (line 254270)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_027)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI CS LRI RLO; 4 ('RTL') (line 254271)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS LRI PDF; 4 ('RTL') (line 254272)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS LRI BN; 4 ('RTL') (line 254273)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS RLI LRE; 4 ('RTL') (line 254274)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS RLI LRO; 4 ('RTL') (line 254275)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS RLI RLE; 4 ('RTL') (line 254276)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS RLI RLO; 4 ('RTL') (line 254277)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS RLI PDF; 4 ('RTL') (line 254278)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS RLI BN; 4 ('RTL') (line 254279)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS FSI LRE; 4 ('RTL') (line 254280)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_028)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI CS FSI LRO; 4 ('RTL') (line 254281)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS FSI RLE; 4 ('RTL') (line 254282)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS FSI RLO; 4 ('RTL') (line 254283)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS FSI PDF; 4 ('RTL') (line 254284)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS FSI BN; 4 ('RTL') (line 254285)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS PDI LRE; 4 ('RTL') (line 254286)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS PDI LRO; 4 ('RTL') (line 254287)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS PDI RLE; 4 ('RTL') (line 254288)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS PDI RLO; 4 ('RTL') (line 254289)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI CS PDI PDF; 4 ('RTL') (line 254290)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_029)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI CS PDI BN; 4 ('RTL') (line 254291)
          std::vector<uint32_t> const cps = { 0x2068, 0x002C, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM S LRE; 4 ('RTL') (line 254292)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM S LRO; 4 ('RTL') (line 254293)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM S RLE; 4 ('RTL') (line 254294)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM S RLO; 4 ('RTL') (line 254295)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM S PDF; 4 ('RTL') (line 254296)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM S BN; 4 ('RTL') (line 254297)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM WS LRE; 4 ('RTL') (line 254298)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM WS LRO; 4 ('RTL') (line 254299)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM WS RLE; 4 ('RTL') (line 254300)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_030)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI NSM WS RLO; 4 ('RTL') (line 254301)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM WS PDF; 4 ('RTL') (line 254302)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM WS BN; 4 ('RTL') (line 254303)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM LRI LRE; 4 ('RTL') (line 254304)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM LRI LRO; 4 ('RTL') (line 254305)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM LRI RLE; 4 ('RTL') (line 254306)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM LRI RLO; 4 ('RTL') (line 254307)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM LRI PDF; 4 ('RTL') (line 254308)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM LRI BN; 4 ('RTL') (line 254309)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM RLI LRE; 4 ('RTL') (line 254310)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_031)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI NSM RLI LRO; 4 ('RTL') (line 254311)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM RLI RLE; 4 ('RTL') (line 254312)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM RLI RLO; 4 ('RTL') (line 254313)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM RLI PDF; 4 ('RTL') (line 254314)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM RLI BN; 4 ('RTL') (line 254315)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM FSI LRE; 4 ('RTL') (line 254316)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM FSI LRO; 4 ('RTL') (line 254317)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM FSI RLE; 4 ('RTL') (line 254318)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM FSI RLO; 4 ('RTL') (line 254319)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM FSI PDF; 4 ('RTL') (line 254320)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_032)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI NSM FSI BN; 4 ('RTL') (line 254321)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM PDI LRE; 4 ('RTL') (line 254322)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM PDI LRO; 4 ('RTL') (line 254323)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM PDI RLE; 4 ('RTL') (line 254324)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM PDI RLO; 4 ('RTL') (line 254325)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM PDI PDF; 4 ('RTL') (line 254326)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI NSM PDI BN; 4 ('RTL') (line 254327)
          std::vector<uint32_t> const cps = { 0x2068, 0x0300, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON S LRE; 4 ('RTL') (line 254328)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON S LRO; 4 ('RTL') (line 254329)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON S RLE; 4 ('RTL') (line 254330)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_033)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ON S RLO; 4 ('RTL') (line 254331)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON S PDF; 4 ('RTL') (line 254332)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON S BN; 4 ('RTL') (line 254333)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON WS LRE; 4 ('RTL') (line 254334)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON WS LRO; 4 ('RTL') (line 254335)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON WS RLE; 4 ('RTL') (line 254336)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON WS RLO; 4 ('RTL') (line 254337)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON WS PDF; 4 ('RTL') (line 254338)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON WS BN; 4 ('RTL') (line 254339)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON LRI LRE; 4 ('RTL') (line 254340)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_034)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ON LRI LRO; 4 ('RTL') (line 254341)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON LRI RLE; 4 ('RTL') (line 254342)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON LRI RLO; 4 ('RTL') (line 254343)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON LRI PDF; 4 ('RTL') (line 254344)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON LRI BN; 4 ('RTL') (line 254345)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON RLI LRE; 4 ('RTL') (line 254346)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON RLI LRO; 4 ('RTL') (line 254347)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON RLI RLE; 4 ('RTL') (line 254348)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON RLI RLO; 4 ('RTL') (line 254349)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON RLI PDF; 4 ('RTL') (line 254350)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_035)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ON RLI BN; 4 ('RTL') (line 254351)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON FSI LRE; 4 ('RTL') (line 254352)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON FSI LRO; 4 ('RTL') (line 254353)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON FSI RLE; 4 ('RTL') (line 254354)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON FSI RLO; 4 ('RTL') (line 254355)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON FSI PDF; 4 ('RTL') (line 254356)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON FSI BN; 4 ('RTL') (line 254357)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON PDI LRE; 4 ('RTL') (line 254358)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON PDI LRO; 4 ('RTL') (line 254359)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON PDI RLE; 4 ('RTL') (line 254360)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_036)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // FSI ON PDI RLO; 4 ('RTL') (line 254361)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON PDI PDF; 4 ('RTL') (line 254362)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // FSI ON PDI BN; 4 ('RTL') (line 254363)
          std::vector<uint32_t> const cps = { 0x2068, 0x0021, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L R LRE; 4 ('RTL') (line 254364)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x05BE, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L R LRO; 4 ('RTL') (line 254365)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x05BE, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L R RLE; 4 ('RTL') (line 254366)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x05BE, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L R RLO; 4 ('RTL') (line 254367)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x05BE, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L R PDF; 4 ('RTL') (line 254368)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x05BE, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L R BN; 4 ('RTL') (line 254369)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x05BE, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L AL LRE; 4 ('RTL') (line 254370)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0608, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_037)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI L AL LRO; 4 ('RTL') (line 254371)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0608, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L AL RLE; 4 ('RTL') (line 254372)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0608, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L AL RLO; 4 ('RTL') (line 254373)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0608, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L AL PDF; 4 ('RTL') (line 254374)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0608, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L AL BN; 4 ('RTL') (line 254375)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0608, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ES LRE; 4 ('RTL') (line 254376)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002B, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ES LRO; 4 ('RTL') (line 254377)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002B, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ES RLE; 4 ('RTL') (line 254378)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002B, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ES RLO; 4 ('RTL') (line 254379)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002B, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ES PDF; 4 ('RTL') (line 254380)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002B, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_038)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI L ES BN; 4 ('RTL') (line 254381)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002B, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ET LRE; 4 ('RTL') (line 254382)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0023, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ET LRO; 4 ('RTL') (line 254383)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0023, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ET RLE; 4 ('RTL') (line 254384)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0023, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ET RLO; 4 ('RTL') (line 254385)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0023, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ET PDF; 4 ('RTL') (line 254386)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0023, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ET BN; 4 ('RTL') (line 254387)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0023, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L CS LRE; 4 ('RTL') (line 254388)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002C, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L CS LRO; 4 ('RTL') (line 254389)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002C, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L CS RLE; 4 ('RTL') (line 254390)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002C, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_039)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI L CS RLO; 4 ('RTL') (line 254391)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002C, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L CS PDF; 4 ('RTL') (line 254392)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002C, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L CS BN; 4 ('RTL') (line 254393)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x002C, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L S LRE; 4 ('RTL') (line 254394)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L S LRO; 4 ('RTL') (line 254395)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L S RLE; 4 ('RTL') (line 254396)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L S RLO; 4 ('RTL') (line 254397)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L S PDF; 4 ('RTL') (line 254398)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L S BN; 4 ('RTL') (line 254399)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L WS LRE; 4 ('RTL') (line 254400)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_040)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI L WS LRO; 4 ('RTL') (line 254401)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L WS RLE; 4 ('RTL') (line 254402)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L WS RLO; 4 ('RTL') (line 254403)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L WS PDF; 4 ('RTL') (line 254404)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L WS BN; 4 ('RTL') (line 254405)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ON LRE; 4 ('RTL') (line 254406)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0021, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ON LRO; 4 ('RTL') (line 254407)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0021, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ON RLE; 4 ('RTL') (line 254408)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0021, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ON RLO; 4 ('RTL') (line 254409)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0021, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L ON PDF; 4 ('RTL') (line 254410)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0021, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_041)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI L ON BN; 4 ('RTL') (line 254411)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x0021, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L LRI LRE; 4 ('RTL') (line 254412)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L LRI LRO; 4 ('RTL') (line 254413)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L LRI RLE; 4 ('RTL') (line 254414)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L LRI RLO; 4 ('RTL') (line 254415)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L LRI PDF; 4 ('RTL') (line 254416)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L LRI BN; 4 ('RTL') (line 254417)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L RLI LRE; 4 ('RTL') (line 254418)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L RLI LRO; 4 ('RTL') (line 254419)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L RLI RLE; 4 ('RTL') (line 254420)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_042)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI L RLI RLO; 4 ('RTL') (line 254421)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L RLI PDF; 4 ('RTL') (line 254422)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L RLI BN; 4 ('RTL') (line 254423)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L FSI LRE; 4 ('RTL') (line 254424)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L FSI LRO; 4 ('RTL') (line 254425)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L FSI RLE; 4 ('RTL') (line 254426)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L FSI RLO; 4 ('RTL') (line 254427)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L FSI PDF; 4 ('RTL') (line 254428)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L FSI BN; 4 ('RTL') (line 254429)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L PDI LRE; 4 ('RTL') (line 254430)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_043)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI L PDI LRO; 4 ('RTL') (line 254431)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L PDI RLE; 4 ('RTL') (line 254432)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L PDI RLO; 4 ('RTL') (line 254433)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L PDI PDF; 4 ('RTL') (line 254434)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI L PDI BN; 4 ('RTL') (line 254435)
          std::vector<uint32_t> const cps = { 0x2069, 0x0041, 0x2069, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R LRE; 5 ('auto') (line 254436)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R LRE; 5 ('RTL') (line 254436)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R LRO; 5 ('auto') (line 254437)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R LRO; 5 ('RTL') (line 254437)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R RLE; 5 ('auto') (line 254438)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R RLE; 5 ('RTL') (line 254438)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R RLO; 5 ('auto') (line 254439)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R RLO; 5 ('RTL') (line 254439)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R PDF; 5 ('auto') (line 254440)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R PDF; 5 ('RTL') (line 254440)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_044)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI EN R BN; 5 ('auto') (line 254441)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN R BN; 5 ('RTL') (line 254441)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x05BE, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL LRE; 5 ('auto') (line 254442)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL LRE; 5 ('RTL') (line 254442)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL LRO; 5 ('auto') (line 254443)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL LRO; 5 ('RTL') (line 254443)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL RLE; 5 ('auto') (line 254444)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL RLE; 5 ('RTL') (line 254444)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL RLO; 5 ('auto') (line 254445)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL RLO; 5 ('RTL') (line 254445)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL PDF; 5 ('auto') (line 254446)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL PDF; 5 ('RTL') (line 254446)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL BN; 5 ('auto') (line 254447)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), -1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), -1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, -1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN AL BN; 5 ('RTL') (line 254447)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0608, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ES LRE; 4 ('RTL') (line 254448)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002B, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ES LRO; 4 ('RTL') (line 254449)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002B, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ES RLE; 4 ('RTL') (line 254450)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002B, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_045)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI EN ES RLO; 4 ('RTL') (line 254451)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002B, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ES PDF; 4 ('RTL') (line 254452)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002B, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ES BN; 4 ('RTL') (line 254453)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002B, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN CS LRE; 4 ('RTL') (line 254454)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002C, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN CS LRO; 4 ('RTL') (line 254455)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002C, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN CS RLE; 4 ('RTL') (line 254456)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002C, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN CS RLO; 4 ('RTL') (line 254457)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002C, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN CS PDF; 4 ('RTL') (line 254458)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002C, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN CS BN; 4 ('RTL') (line 254459)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x002C, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN S LRE; 4 ('RTL') (line 254460)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0009, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_046)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI EN S LRO; 4 ('RTL') (line 254461)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0009, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN S RLE; 4 ('RTL') (line 254462)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0009, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN S RLO; 4 ('RTL') (line 254463)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0009, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN S PDF; 4 ('RTL') (line 254464)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0009, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN S BN; 4 ('RTL') (line 254465)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0009, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN WS LRE; 4 ('RTL') (line 254466)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0020, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN WS LRO; 4 ('RTL') (line 254467)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0020, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN WS RLE; 4 ('RTL') (line 254468)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0020, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN WS RLO; 4 ('RTL') (line 254469)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0020, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN WS PDF; 4 ('RTL') (line 254470)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0020, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_047)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI EN WS BN; 4 ('RTL') (line 254471)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0020, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ON LRE; 4 ('RTL') (line 254472)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0021, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ON LRO; 4 ('RTL') (line 254473)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0021, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ON RLE; 4 ('RTL') (line 254474)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0021, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ON RLO; 4 ('RTL') (line 254475)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0021, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ON PDF; 4 ('RTL') (line 254476)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0021, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN ON BN; 4 ('RTL') (line 254477)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x0021, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN LRI LRE; 4 ('RTL') (line 254478)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2066, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN LRI LRO; 4 ('RTL') (line 254479)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2066, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN LRI RLE; 4 ('RTL') (line 254480)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2066, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_048)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI EN LRI RLO; 4 ('RTL') (line 254481)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2066, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN LRI PDF; 4 ('RTL') (line 254482)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2066, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN LRI BN; 4 ('RTL') (line 254483)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2066, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN RLI LRE; 4 ('RTL') (line 254484)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2067, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN RLI LRO; 4 ('RTL') (line 254485)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2067, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN RLI RLE; 4 ('RTL') (line 254486)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2067, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN RLI RLO; 4 ('RTL') (line 254487)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2067, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN RLI PDF; 4 ('RTL') (line 254488)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2067, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN RLI BN; 4 ('RTL') (line 254489)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2067, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN FSI LRE; 4 ('RTL') (line 254490)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2068, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  }
  
  TEST(bidi, bidi_508_049)
  {
  
      expected_levels = { 1, 2, 1, -1 };
      expected_reordered_indices = { 2, 1, 0 };
  
      {
          // PDI EN FSI LRO; 4 ('RTL') (line 254491)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2068, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN FSI RLE; 4 ('RTL') (line 254492)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2068, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN FSI RLO; 4 ('RTL') (line 254493)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2068, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN FSI PDF; 4 ('RTL') (line 254494)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2068, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN FSI BN; 4 ('RTL') (line 254495)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2068, 0x00AD };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN PDI LRE; 4 ('RTL') (line 254496)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2069, 0x202A };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN PDI LRO; 4 ('RTL') (line 254497)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2069, 0x202D };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN PDI RLE; 4 ('RTL') (line 254498)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2069, 0x202B };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN PDI RLO; 4 ('RTL') (line 254499)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2069, 0x202E };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
      {
          // PDI EN PDI PDF; 4 ('RTL') (line 254500)
          std::vector<uint32_t> const cps = { 0x2069, 0x0030, 0x2069, 0x202C };
          std::vector<int> const levels =
              bidi_levels(cps.begin(), cps.end(), 1);
          int i = 0;
          for (int l : expected_levels) {
              if (0 <= l) {
                  EXPECT_EQ(levels[i], l) << "i=" << i;
                  ++i;
              }
          }
          EXPECT_EQ((int)levels.size(), i);
  
          std::vector<int> const reordered =
              bidi_reordered_indices(cps.begin(), cps.end(), 1);
          i = 0;
          for (int idx : expected_reordered_indices) {
              // Skip FSI, LRI, RLI, and PDI.
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
  
          std::vector<int> reordered_2;
          for (auto subrange :
              boost::text::bidirectional_subranges(cps, 1)) {
              for (auto cp : subrange) {
                  reordered_2.push_back(cp);
              }
          }
          i = 0;
          for (int idx : expected_reordered_indices) {
              if (cps[idx] < 0x2066 || 0x2069 < cps[idx]) {
                  EXPECT_EQ(reordered_2[i], cps[idx])
                      << std::hex
                      << " 0x" << reordered_2[i]
                      << " 0x" << cps[idx]
                      << std::dec << " i=" << i;
              }
              ++i;
          }
          EXPECT_EQ(i, (int)reordered_2.size());
      }
  
  }
  