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

#include <gtest/gtest.h>

#include <algorithm>

TEST(normalization, nfkd_024_000)
{
    // B550;B550;1104 1162 11AB;B550;1104 1162 11AB;
    // (땐; 땐; 땐; 땐; 땐; ) HANGUL SYLLABLE DDAEN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB550 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB550 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB550 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11AB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_001)
{
    // B551;B551;1104 1162 11AC;B551;1104 1162 11AC;
    // (땑; 땑; 땑; 땑; 땑; ) HANGUL SYLLABLE DDAENJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB551 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB551 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB551 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11AC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_002)
{
    // B552;B552;1104 1162 11AD;B552;1104 1162 11AD;
    // (땒; 땒; 땒; 땒; 땒; ) HANGUL SYLLABLE DDAENH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB552 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB552 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB552 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11AD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_003)
{
    // B553;B553;1104 1162 11AE;B553;1104 1162 11AE;
    // (땓; 땓; 땓; 땓; 땓; ) HANGUL SYLLABLE DDAED
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB553 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB553 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB553 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11AE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_004)
{
    // B554;B554;1104 1162 11AF;B554;1104 1162 11AF;
    // (땔; 땔; 땔; 땔; 땔; ) HANGUL SYLLABLE DDAEL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB554 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB554 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB554 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11AF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_005)
{
    // B555;B555;1104 1162 11B0;B555;1104 1162 11B0;
    // (땕; 땕; 땕; 땕; 땕; ) HANGUL SYLLABLE DDAELG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB555 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB555 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB555 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_006)
{
    // B556;B556;1104 1162 11B1;B556;1104 1162 11B1;
    // (땖; 땖; 땖; 땖; 땖; ) HANGUL SYLLABLE DDAELM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB556 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB556 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB556 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_007)
{
    // B557;B557;1104 1162 11B2;B557;1104 1162 11B2;
    // (땗; 땗; 땗; 땗; 땗; ) HANGUL SYLLABLE DDAELB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB557 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB557 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB557 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_008)
{
    // B558;B558;1104 1162 11B3;B558;1104 1162 11B3;
    // (땘; 땘; 땘; 땘; 땘; ) HANGUL SYLLABLE DDAELS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB558 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB558 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB558 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B3 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_009)
{
    // B559;B559;1104 1162 11B4;B559;1104 1162 11B4;
    // (땙; 땙; 땙; 땙; 땙; ) HANGUL SYLLABLE DDAELT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB559 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB559 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB559 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B4 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_010)
{
    // B55A;B55A;1104 1162 11B5;B55A;1104 1162 11B5;
    // (땚; 땚; 땚; 땚; 땚; ) HANGUL SYLLABLE DDAELP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB55A }};
        std::array<uint32_t, 1> const c2 = {{ 0xB55A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB55A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B5 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_011)
{
    // B55B;B55B;1104 1162 11B6;B55B;1104 1162 11B6;
    // (땛; 땛; 땛; 땛; 땛; ) HANGUL SYLLABLE DDAELH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB55B }};
        std::array<uint32_t, 1> const c2 = {{ 0xB55B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB55B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B6 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_012)
{
    // B55C;B55C;1104 1162 11B7;B55C;1104 1162 11B7;
    // (땜; 땜; 땜; 땜; 땜; ) HANGUL SYLLABLE DDAEM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB55C }};
        std::array<uint32_t, 1> const c2 = {{ 0xB55C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB55C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B7 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_013)
{
    // B55D;B55D;1104 1162 11B8;B55D;1104 1162 11B8;
    // (땝; 땝; 땝; 땝; 땝; ) HANGUL SYLLABLE DDAEB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB55D }};
        std::array<uint32_t, 1> const c2 = {{ 0xB55D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB55D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_014)
{
    // B55E;B55E;1104 1162 11B9;B55E;1104 1162 11B9;
    // (땞; 땞; 땞; 땞; 땞; ) HANGUL SYLLABLE DDAEBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB55E }};
        std::array<uint32_t, 1> const c2 = {{ 0xB55E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB55E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11B9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_015)
{
    // B55F;B55F;1104 1162 11BA;B55F;1104 1162 11BA;
    // (땟; 땟; 땟; 땟; 땟; ) HANGUL SYLLABLE DDAES
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB55F }};
        std::array<uint32_t, 1> const c2 = {{ 0xB55F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB55F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11BA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_016)
{
    // B560;B560;1104 1162 11BB;B560;1104 1162 11BB;
    // (땠; 땠; 땠; 땠; 땠; ) HANGUL SYLLABLE DDAESS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB560 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB560 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB560 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11BB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_017)
{
    // B561;B561;1104 1162 11BC;B561;1104 1162 11BC;
    // (땡; 땡; 땡; 땡; 땡; ) HANGUL SYLLABLE DDAENG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB561 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB561 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB561 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11BC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_018)
{
    // B562;B562;1104 1162 11BD;B562;1104 1162 11BD;
    // (땢; 땢; 땢; 땢; 땢; ) HANGUL SYLLABLE DDAEJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB562 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB562 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB562 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11BD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_019)
{
    // B563;B563;1104 1162 11BE;B563;1104 1162 11BE;
    // (땣; 땣; 땣; 땣; 땣; ) HANGUL SYLLABLE DDAEC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB563 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB563 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB563 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11BE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_020)
{
    // B564;B564;1104 1162 11BF;B564;1104 1162 11BF;
    // (땤; 땤; 땤; 땤; 땤; ) HANGUL SYLLABLE DDAEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB564 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB564 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB564 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11BF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_021)
{
    // B565;B565;1104 1162 11C0;B565;1104 1162 11C0;
    // (땥; 땥; 땥; 땥; 땥; ) HANGUL SYLLABLE DDAET
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB565 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB565 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB565 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11C0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_022)
{
    // B566;B566;1104 1162 11C1;B566;1104 1162 11C1;
    // (땦; 땦; 땦; 땦; 땦; ) HANGUL SYLLABLE DDAEP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB566 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB566 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB566 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11C1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_023)
{
    // B567;B567;1104 1162 11C2;B567;1104 1162 11C2;
    // (땧; 땧; 땧; 땧; 땧; ) HANGUL SYLLABLE DDAEH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB567 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB567 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1162, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB567 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1162, 0x11C2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_024)
{
    // B568;B568;1104 1163;B568;1104 1163;
    // (땨; 땨; 땨; 땨; 땨; ) HANGUL SYLLABLE DDYA
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB568 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB568 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1104, 0x1163 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB568 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1104, 0x1163 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_025)
{
    // B569;B569;1104 1163 11A8;B569;1104 1163 11A8;
    // (땩; 땩; 땩; 땩; 땩; ) HANGUL SYLLABLE DDYAG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB569 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB569 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB569 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11A8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_026)
{
    // B56A;B56A;1104 1163 11A9;B56A;1104 1163 11A9;
    // (땪; 땪; 땪; 땪; 땪; ) HANGUL SYLLABLE DDYAGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB56A }};
        std::array<uint32_t, 1> const c2 = {{ 0xB56A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB56A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11A9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_027)
{
    // B56B;B56B;1104 1163 11AA;B56B;1104 1163 11AA;
    // (땫; 땫; 땫; 땫; 땫; ) HANGUL SYLLABLE DDYAGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB56B }};
        std::array<uint32_t, 1> const c2 = {{ 0xB56B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB56B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11AA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_028)
{
    // B56C;B56C;1104 1163 11AB;B56C;1104 1163 11AB;
    // (땬; 땬; 땬; 땬; 땬; ) HANGUL SYLLABLE DDYAN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB56C }};
        std::array<uint32_t, 1> const c2 = {{ 0xB56C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB56C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11AB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_029)
{
    // B56D;B56D;1104 1163 11AC;B56D;1104 1163 11AC;
    // (땭; 땭; 땭; 땭; 땭; ) HANGUL SYLLABLE DDYANJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB56D }};
        std::array<uint32_t, 1> const c2 = {{ 0xB56D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB56D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11AC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_030)
{
    // B56E;B56E;1104 1163 11AD;B56E;1104 1163 11AD;
    // (땮; 땮; 땮; 땮; 땮; ) HANGUL SYLLABLE DDYANH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB56E }};
        std::array<uint32_t, 1> const c2 = {{ 0xB56E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB56E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11AD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_031)
{
    // B56F;B56F;1104 1163 11AE;B56F;1104 1163 11AE;
    // (땯; 땯; 땯; 땯; 땯; ) HANGUL SYLLABLE DDYAD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB56F }};
        std::array<uint32_t, 1> const c2 = {{ 0xB56F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB56F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11AE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_032)
{
    // B570;B570;1104 1163 11AF;B570;1104 1163 11AF;
    // (땰; 땰; 땰; 땰; 땰; ) HANGUL SYLLABLE DDYAL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB570 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB570 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB570 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11AF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_033)
{
    // B571;B571;1104 1163 11B0;B571;1104 1163 11B0;
    // (땱; 땱; 땱; 땱; 땱; ) HANGUL SYLLABLE DDYALG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB571 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB571 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB571 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_034)
{
    // B572;B572;1104 1163 11B1;B572;1104 1163 11B1;
    // (땲; 땲; 땲; 땲; 땲; ) HANGUL SYLLABLE DDYALM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB572 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB572 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB572 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_035)
{
    // B573;B573;1104 1163 11B2;B573;1104 1163 11B2;
    // (땳; 땳; 땳; 땳; 땳; ) HANGUL SYLLABLE DDYALB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB573 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB573 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB573 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_036)
{
    // B574;B574;1104 1163 11B3;B574;1104 1163 11B3;
    // (땴; 땴; 땴; 땴; 땴; ) HANGUL SYLLABLE DDYALS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB574 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB574 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB574 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B3 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_037)
{
    // B575;B575;1104 1163 11B4;B575;1104 1163 11B4;
    // (땵; 땵; 땵; 땵; 땵; ) HANGUL SYLLABLE DDYALT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB575 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB575 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB575 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B4 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_038)
{
    // B576;B576;1104 1163 11B5;B576;1104 1163 11B5;
    // (땶; 땶; 땶; 땶; 땶; ) HANGUL SYLLABLE DDYALP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB576 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB576 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB576 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B5 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_039)
{
    // B577;B577;1104 1163 11B6;B577;1104 1163 11B6;
    // (땷; 땷; 땷; 땷; 땷; ) HANGUL SYLLABLE DDYALH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB577 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB577 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB577 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B6 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_040)
{
    // B578;B578;1104 1163 11B7;B578;1104 1163 11B7;
    // (땸; 땸; 땸; 땸; 땸; ) HANGUL SYLLABLE DDYAM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB578 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB578 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB578 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B7 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_041)
{
    // B579;B579;1104 1163 11B8;B579;1104 1163 11B8;
    // (땹; 땹; 땹; 땹; 땹; ) HANGUL SYLLABLE DDYAB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB579 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB579 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB579 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_042)
{
    // B57A;B57A;1104 1163 11B9;B57A;1104 1163 11B9;
    // (땺; 땺; 땺; 땺; 땺; ) HANGUL SYLLABLE DDYABS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB57A }};
        std::array<uint32_t, 1> const c2 = {{ 0xB57A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB57A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11B9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_043)
{
    // B57B;B57B;1104 1163 11BA;B57B;1104 1163 11BA;
    // (땻; 땻; 땻; 땻; 땻; ) HANGUL SYLLABLE DDYAS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB57B }};
        std::array<uint32_t, 1> const c2 = {{ 0xB57B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB57B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11BA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_044)
{
    // B57C;B57C;1104 1163 11BB;B57C;1104 1163 11BB;
    // (땼; 땼; 땼; 땼; 땼; ) HANGUL SYLLABLE DDYASS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB57C }};
        std::array<uint32_t, 1> const c2 = {{ 0xB57C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB57C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11BB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_045)
{
    // B57D;B57D;1104 1163 11BC;B57D;1104 1163 11BC;
    // (땽; 땽; 땽; 땽; 땽; ) HANGUL SYLLABLE DDYANG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB57D }};
        std::array<uint32_t, 1> const c2 = {{ 0xB57D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB57D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11BC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_046)
{
    // B57E;B57E;1104 1163 11BD;B57E;1104 1163 11BD;
    // (땾; 땾; 땾; 땾; 땾; ) HANGUL SYLLABLE DDYAJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB57E }};
        std::array<uint32_t, 1> const c2 = {{ 0xB57E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB57E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11BD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_047)
{
    // B57F;B57F;1104 1163 11BE;B57F;1104 1163 11BE;
    // (땿; 땿; 땿; 땿; 땿; ) HANGUL SYLLABLE DDYAC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB57F }};
        std::array<uint32_t, 1> const c2 = {{ 0xB57F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB57F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11BE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_048)
{
    // B580;B580;1104 1163 11BF;B580;1104 1163 11BF;
    // (떀; 떀; 떀; 떀; 떀; ) HANGUL SYLLABLE DDYAK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB580 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB580 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB580 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11BF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_049)
{
    // B581;B581;1104 1163 11C0;B581;1104 1163 11C0;
    // (떁; 떁; 떁; 떁; 떁; ) HANGUL SYLLABLE DDYAT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB581 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB581 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB581 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11C0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_050)
{
    // B582;B582;1104 1163 11C1;B582;1104 1163 11C1;
    // (떂; 떂; 떂; 떂; 떂; ) HANGUL SYLLABLE DDYAP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB582 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB582 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB582 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11C1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_051)
{
    // B583;B583;1104 1163 11C2;B583;1104 1163 11C2;
    // (떃; 떃; 떃; 떃; 떃; ) HANGUL SYLLABLE DDYAH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB583 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB583 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1163, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB583 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1163, 0x11C2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_052)
{
    // B584;B584;1104 1164;B584;1104 1164;
    // (떄; 떄; 떄; 떄; 떄; ) HANGUL SYLLABLE DDYAE
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB584 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB584 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1104, 0x1164 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB584 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1104, 0x1164 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_053)
{
    // B585;B585;1104 1164 11A8;B585;1104 1164 11A8;
    // (떅; 떅; 떅; 떅; 떅; ) HANGUL SYLLABLE DDYAEG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB585 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB585 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB585 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11A8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_054)
{
    // B586;B586;1104 1164 11A9;B586;1104 1164 11A9;
    // (떆; 떆; 떆; 떆; 떆; ) HANGUL SYLLABLE DDYAEGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB586 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB586 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB586 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11A9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_055)
{
    // B587;B587;1104 1164 11AA;B587;1104 1164 11AA;
    // (떇; 떇; 떇; 떇; 떇; ) HANGUL SYLLABLE DDYAEGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB587 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB587 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB587 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11AA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_056)
{
    // B588;B588;1104 1164 11AB;B588;1104 1164 11AB;
    // (떈; 떈; 떈; 떈; 떈; ) HANGUL SYLLABLE DDYAEN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB588 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB588 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB588 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11AB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_057)
{
    // B589;B589;1104 1164 11AC;B589;1104 1164 11AC;
    // (떉; 떉; 떉; 떉; 떉; ) HANGUL SYLLABLE DDYAENJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB589 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB589 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB589 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11AC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_058)
{
    // B58A;B58A;1104 1164 11AD;B58A;1104 1164 11AD;
    // (떊; 떊; 떊; 떊; 떊; ) HANGUL SYLLABLE DDYAENH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB58A }};
        std::array<uint32_t, 1> const c2 = {{ 0xB58A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB58A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11AD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_059)
{
    // B58B;B58B;1104 1164 11AE;B58B;1104 1164 11AE;
    // (떋; 떋; 떋; 떋; 떋; ) HANGUL SYLLABLE DDYAED
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB58B }};
        std::array<uint32_t, 1> const c2 = {{ 0xB58B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB58B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11AE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_060)
{
    // B58C;B58C;1104 1164 11AF;B58C;1104 1164 11AF;
    // (떌; 떌; 떌; 떌; 떌; ) HANGUL SYLLABLE DDYAEL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB58C }};
        std::array<uint32_t, 1> const c2 = {{ 0xB58C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB58C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11AF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_061)
{
    // B58D;B58D;1104 1164 11B0;B58D;1104 1164 11B0;
    // (떍; 떍; 떍; 떍; 떍; ) HANGUL SYLLABLE DDYAELG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB58D }};
        std::array<uint32_t, 1> const c2 = {{ 0xB58D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB58D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_062)
{
    // B58E;B58E;1104 1164 11B1;B58E;1104 1164 11B1;
    // (떎; 떎; 떎; 떎; 떎; ) HANGUL SYLLABLE DDYAELM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB58E }};
        std::array<uint32_t, 1> const c2 = {{ 0xB58E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB58E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_063)
{
    // B58F;B58F;1104 1164 11B2;B58F;1104 1164 11B2;
    // (떏; 떏; 떏; 떏; 떏; ) HANGUL SYLLABLE DDYAELB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB58F }};
        std::array<uint32_t, 1> const c2 = {{ 0xB58F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB58F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_064)
{
    // B590;B590;1104 1164 11B3;B590;1104 1164 11B3;
    // (떐; 떐; 떐; 떐; 떐; ) HANGUL SYLLABLE DDYAELS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB590 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB590 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB590 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B3 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_065)
{
    // B591;B591;1104 1164 11B4;B591;1104 1164 11B4;
    // (떑; 떑; 떑; 떑; 떑; ) HANGUL SYLLABLE DDYAELT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB591 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB591 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB591 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B4 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_066)
{
    // B592;B592;1104 1164 11B5;B592;1104 1164 11B5;
    // (떒; 떒; 떒; 떒; 떒; ) HANGUL SYLLABLE DDYAELP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB592 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB592 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB592 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B5 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_067)
{
    // B593;B593;1104 1164 11B6;B593;1104 1164 11B6;
    // (떓; 떓; 떓; 떓; 떓; ) HANGUL SYLLABLE DDYAELH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB593 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB593 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB593 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B6 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_068)
{
    // B594;B594;1104 1164 11B7;B594;1104 1164 11B7;
    // (떔; 떔; 떔; 떔; 떔; ) HANGUL SYLLABLE DDYAEM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB594 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB594 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB594 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B7 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_069)
{
    // B595;B595;1104 1164 11B8;B595;1104 1164 11B8;
    // (떕; 떕; 떕; 떕; 떕; ) HANGUL SYLLABLE DDYAEB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB595 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB595 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB595 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_070)
{
    // B596;B596;1104 1164 11B9;B596;1104 1164 11B9;
    // (떖; 떖; 떖; 떖; 떖; ) HANGUL SYLLABLE DDYAEBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB596 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB596 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB596 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11B9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_071)
{
    // B597;B597;1104 1164 11BA;B597;1104 1164 11BA;
    // (떗; 떗; 떗; 떗; 떗; ) HANGUL SYLLABLE DDYAES
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB597 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB597 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB597 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11BA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_072)
{
    // B598;B598;1104 1164 11BB;B598;1104 1164 11BB;
    // (떘; 떘; 떘; 떘; 떘; ) HANGUL SYLLABLE DDYAESS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB598 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB598 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB598 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11BB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_073)
{
    // B599;B599;1104 1164 11BC;B599;1104 1164 11BC;
    // (떙; 떙; 떙; 떙; 떙; ) HANGUL SYLLABLE DDYAENG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB599 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB599 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB599 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11BC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_074)
{
    // B59A;B59A;1104 1164 11BD;B59A;1104 1164 11BD;
    // (떚; 떚; 떚; 떚; 떚; ) HANGUL SYLLABLE DDYAEJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB59A }};
        std::array<uint32_t, 1> const c2 = {{ 0xB59A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB59A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11BD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_075)
{
    // B59B;B59B;1104 1164 11BE;B59B;1104 1164 11BE;
    // (떛; 떛; 떛; 떛; 떛; ) HANGUL SYLLABLE DDYAEC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB59B }};
        std::array<uint32_t, 1> const c2 = {{ 0xB59B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB59B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11BE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_076)
{
    // B59C;B59C;1104 1164 11BF;B59C;1104 1164 11BF;
    // (떜; 떜; 떜; 떜; 떜; ) HANGUL SYLLABLE DDYAEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB59C }};
        std::array<uint32_t, 1> const c2 = {{ 0xB59C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB59C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11BF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_077)
{
    // B59D;B59D;1104 1164 11C0;B59D;1104 1164 11C0;
    // (떝; 떝; 떝; 떝; 떝; ) HANGUL SYLLABLE DDYAET
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB59D }};
        std::array<uint32_t, 1> const c2 = {{ 0xB59D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB59D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11C0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_078)
{
    // B59E;B59E;1104 1164 11C1;B59E;1104 1164 11C1;
    // (떞; 떞; 떞; 떞; 떞; ) HANGUL SYLLABLE DDYAEP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB59E }};
        std::array<uint32_t, 1> const c2 = {{ 0xB59E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB59E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11C1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_079)
{
    // B59F;B59F;1104 1164 11C2;B59F;1104 1164 11C2;
    // (떟; 떟; 떟; 떟; 떟; ) HANGUL SYLLABLE DDYAEH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB59F }};
        std::array<uint32_t, 1> const c2 = {{ 0xB59F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1164, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB59F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1164, 0x11C2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_080)
{
    // B5A0;B5A0;1104 1165;B5A0;1104 1165;
    // (떠; 떠; 떠; 떠; 떠; ) HANGUL SYLLABLE DDEO
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A0 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1104, 0x1165 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A0 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1104, 0x1165 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_081)
{
    // B5A1;B5A1;1104 1165 11A8;B5A1;1104 1165 11A8;
    // (떡; 떡; 떡; 떡; 떡; ) HANGUL SYLLABLE DDEOG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11A8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_082)
{
    // B5A2;B5A2;1104 1165 11A9;B5A2;1104 1165 11A9;
    // (떢; 떢; 떢; 떢; 떢; ) HANGUL SYLLABLE DDEOGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11A9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_083)
{
    // B5A3;B5A3;1104 1165 11AA;B5A3;1104 1165 11AA;
    // (떣; 떣; 떣; 떣; 떣; ) HANGUL SYLLABLE DDEOGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11AA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_084)
{
    // B5A4;B5A4;1104 1165 11AB;B5A4;1104 1165 11AB;
    // (떤; 떤; 떤; 떤; 떤; ) HANGUL SYLLABLE DDEON
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11AB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_085)
{
    // B5A5;B5A5;1104 1165 11AC;B5A5;1104 1165 11AC;
    // (떥; 떥; 떥; 떥; 떥; ) HANGUL SYLLABLE DDEONJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11AC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_086)
{
    // B5A6;B5A6;1104 1165 11AD;B5A6;1104 1165 11AD;
    // (떦; 떦; 떦; 떦; 떦; ) HANGUL SYLLABLE DDEONH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11AD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_087)
{
    // B5A7;B5A7;1104 1165 11AE;B5A7;1104 1165 11AE;
    // (떧; 떧; 떧; 떧; 떧; ) HANGUL SYLLABLE DDEOD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11AE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_088)
{
    // B5A8;B5A8;1104 1165 11AF;B5A8;1104 1165 11AF;
    // (떨; 떨; 떨; 떨; 떨; ) HANGUL SYLLABLE DDEOL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11AF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_089)
{
    // B5A9;B5A9;1104 1165 11B0;B5A9;1104 1165 11B0;
    // (떩; 떩; 떩; 떩; 떩; ) HANGUL SYLLABLE DDEOLG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5A9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5A9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5A9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_090)
{
    // B5AA;B5AA;1104 1165 11B1;B5AA;1104 1165 11B1;
    // (떪; 떪; 떪; 떪; 떪; ) HANGUL SYLLABLE DDEOLM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5AA }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5AA }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5AA }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_091)
{
    // B5AB;B5AB;1104 1165 11B2;B5AB;1104 1165 11B2;
    // (떫; 떫; 떫; 떫; 떫; ) HANGUL SYLLABLE DDEOLB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5AB }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5AB }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5AB }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_092)
{
    // B5AC;B5AC;1104 1165 11B3;B5AC;1104 1165 11B3;
    // (떬; 떬; 떬; 떬; 떬; ) HANGUL SYLLABLE DDEOLS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5AC }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5AC }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5AC }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B3 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_093)
{
    // B5AD;B5AD;1104 1165 11B4;B5AD;1104 1165 11B4;
    // (떭; 떭; 떭; 떭; 떭; ) HANGUL SYLLABLE DDEOLT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5AD }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5AD }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5AD }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B4 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_094)
{
    // B5AE;B5AE;1104 1165 11B5;B5AE;1104 1165 11B5;
    // (떮; 떮; 떮; 떮; 떮; ) HANGUL SYLLABLE DDEOLP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5AE }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5AE }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5AE }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B5 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_095)
{
    // B5AF;B5AF;1104 1165 11B6;B5AF;1104 1165 11B6;
    // (떯; 떯; 떯; 떯; 떯; ) HANGUL SYLLABLE DDEOLH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5AF }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5AF }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5AF }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B6 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_096)
{
    // B5B0;B5B0;1104 1165 11B7;B5B0;1104 1165 11B7;
    // (떰; 떰; 떰; 떰; 떰; ) HANGUL SYLLABLE DDEOM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B7 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_097)
{
    // B5B1;B5B1;1104 1165 11B8;B5B1;1104 1165 11B8;
    // (떱; 떱; 떱; 떱; 떱; ) HANGUL SYLLABLE DDEOB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_098)
{
    // B5B2;B5B2;1104 1165 11B9;B5B2;1104 1165 11B9;
    // (떲; 떲; 떲; 떲; 떲; ) HANGUL SYLLABLE DDEOBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11B9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_099)
{
    // B5B3;B5B3;1104 1165 11BA;B5B3;1104 1165 11BA;
    // (떳; 떳; 떳; 떳; 떳; ) HANGUL SYLLABLE DDEOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11BA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_100)
{
    // B5B4;B5B4;1104 1165 11BB;B5B4;1104 1165 11BB;
    // (떴; 떴; 떴; 떴; 떴; ) HANGUL SYLLABLE DDEOSS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11BB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_101)
{
    // B5B5;B5B5;1104 1165 11BC;B5B5;1104 1165 11BC;
    // (떵; 떵; 떵; 떵; 떵; ) HANGUL SYLLABLE DDEONG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11BC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_102)
{
    // B5B6;B5B6;1104 1165 11BD;B5B6;1104 1165 11BD;
    // (떶; 떶; 떶; 떶; 떶; ) HANGUL SYLLABLE DDEOJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11BD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_103)
{
    // B5B7;B5B7;1104 1165 11BE;B5B7;1104 1165 11BE;
    // (떷; 떷; 떷; 떷; 떷; ) HANGUL SYLLABLE DDEOC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11BE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_104)
{
    // B5B8;B5B8;1104 1165 11BF;B5B8;1104 1165 11BF;
    // (떸; 떸; 떸; 떸; 떸; ) HANGUL SYLLABLE DDEOK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11BF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_105)
{
    // B5B9;B5B9;1104 1165 11C0;B5B9;1104 1165 11C0;
    // (떹; 떹; 떹; 떹; 떹; ) HANGUL SYLLABLE DDEOT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5B9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5B9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5B9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11C0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_106)
{
    // B5BA;B5BA;1104 1165 11C1;B5BA;1104 1165 11C1;
    // (떺; 떺; 떺; 떺; 떺; ) HANGUL SYLLABLE DDEOP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5BA }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5BA }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5BA }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11C1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_107)
{
    // B5BB;B5BB;1104 1165 11C2;B5BB;1104 1165 11C2;
    // (떻; 떻; 떻; 떻; 떻; ) HANGUL SYLLABLE DDEOH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5BB }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5BB }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1165, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5BB }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1165, 0x11C2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_108)
{
    // B5BC;B5BC;1104 1166;B5BC;1104 1166;
    // (떼; 떼; 떼; 떼; 떼; ) HANGUL SYLLABLE DDE
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5BC }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5BC }};
        std::array<uint32_t, 2> const c3 = {{ 0x1104, 0x1166 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5BC }};
        std::array<uint32_t, 2> const c5 = {{ 0x1104, 0x1166 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_109)
{
    // B5BD;B5BD;1104 1166 11A8;B5BD;1104 1166 11A8;
    // (떽; 떽; 떽; 떽; 떽; ) HANGUL SYLLABLE DDEG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5BD }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5BD }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5BD }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11A8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_110)
{
    // B5BE;B5BE;1104 1166 11A9;B5BE;1104 1166 11A9;
    // (떾; 떾; 떾; 떾; 떾; ) HANGUL SYLLABLE DDEGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5BE }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5BE }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5BE }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11A9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_111)
{
    // B5BF;B5BF;1104 1166 11AA;B5BF;1104 1166 11AA;
    // (떿; 떿; 떿; 떿; 떿; ) HANGUL SYLLABLE DDEGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5BF }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5BF }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5BF }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11AA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_112)
{
    // B5C0;B5C0;1104 1166 11AB;B5C0;1104 1166 11AB;
    // (뗀; 뗀; 뗀; 뗀; 뗀; ) HANGUL SYLLABLE DDEN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11AB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_113)
{
    // B5C1;B5C1;1104 1166 11AC;B5C1;1104 1166 11AC;
    // (뗁; 뗁; 뗁; 뗁; 뗁; ) HANGUL SYLLABLE DDENJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11AC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_114)
{
    // B5C2;B5C2;1104 1166 11AD;B5C2;1104 1166 11AD;
    // (뗂; 뗂; 뗂; 뗂; 뗂; ) HANGUL SYLLABLE DDENH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11AD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_115)
{
    // B5C3;B5C3;1104 1166 11AE;B5C3;1104 1166 11AE;
    // (뗃; 뗃; 뗃; 뗃; 뗃; ) HANGUL SYLLABLE DDED
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11AE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_116)
{
    // B5C4;B5C4;1104 1166 11AF;B5C4;1104 1166 11AF;
    // (뗄; 뗄; 뗄; 뗄; 뗄; ) HANGUL SYLLABLE DDEL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11AF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_117)
{
    // B5C5;B5C5;1104 1166 11B0;B5C5;1104 1166 11B0;
    // (뗅; 뗅; 뗅; 뗅; 뗅; ) HANGUL SYLLABLE DDELG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_118)
{
    // B5C6;B5C6;1104 1166 11B1;B5C6;1104 1166 11B1;
    // (뗆; 뗆; 뗆; 뗆; 뗆; ) HANGUL SYLLABLE DDELM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_119)
{
    // B5C7;B5C7;1104 1166 11B2;B5C7;1104 1166 11B2;
    // (뗇; 뗇; 뗇; 뗇; 뗇; ) HANGUL SYLLABLE DDELB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_120)
{
    // B5C8;B5C8;1104 1166 11B3;B5C8;1104 1166 11B3;
    // (뗈; 뗈; 뗈; 뗈; 뗈; ) HANGUL SYLLABLE DDELS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B3 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_121)
{
    // B5C9;B5C9;1104 1166 11B4;B5C9;1104 1166 11B4;
    // (뗉; 뗉; 뗉; 뗉; 뗉; ) HANGUL SYLLABLE DDELT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5C9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5C9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5C9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B4 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_122)
{
    // B5CA;B5CA;1104 1166 11B5;B5CA;1104 1166 11B5;
    // (뗊; 뗊; 뗊; 뗊; 뗊; ) HANGUL SYLLABLE DDELP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5CA }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5CA }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5CA }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B5 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_123)
{
    // B5CB;B5CB;1104 1166 11B6;B5CB;1104 1166 11B6;
    // (뗋; 뗋; 뗋; 뗋; 뗋; ) HANGUL SYLLABLE DDELH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5CB }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5CB }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5CB }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B6 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_124)
{
    // B5CC;B5CC;1104 1166 11B7;B5CC;1104 1166 11B7;
    // (뗌; 뗌; 뗌; 뗌; 뗌; ) HANGUL SYLLABLE DDEM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5CC }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5CC }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5CC }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B7 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_125)
{
    // B5CD;B5CD;1104 1166 11B8;B5CD;1104 1166 11B8;
    // (뗍; 뗍; 뗍; 뗍; 뗍; ) HANGUL SYLLABLE DDEB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5CD }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5CD }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5CD }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_126)
{
    // B5CE;B5CE;1104 1166 11B9;B5CE;1104 1166 11B9;
    // (뗎; 뗎; 뗎; 뗎; 뗎; ) HANGUL SYLLABLE DDEBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5CE }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5CE }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5CE }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11B9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_127)
{
    // B5CF;B5CF;1104 1166 11BA;B5CF;1104 1166 11BA;
    // (뗏; 뗏; 뗏; 뗏; 뗏; ) HANGUL SYLLABLE DDES
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5CF }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5CF }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5CF }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11BA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_128)
{
    // B5D0;B5D0;1104 1166 11BB;B5D0;1104 1166 11BB;
    // (뗐; 뗐; 뗐; 뗐; 뗐; ) HANGUL SYLLABLE DDESS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11BB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_129)
{
    // B5D1;B5D1;1104 1166 11BC;B5D1;1104 1166 11BC;
    // (뗑; 뗑; 뗑; 뗑; 뗑; ) HANGUL SYLLABLE DDENG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11BC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_130)
{
    // B5D2;B5D2;1104 1166 11BD;B5D2;1104 1166 11BD;
    // (뗒; 뗒; 뗒; 뗒; 뗒; ) HANGUL SYLLABLE DDEJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11BD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_131)
{
    // B5D3;B5D3;1104 1166 11BE;B5D3;1104 1166 11BE;
    // (뗓; 뗓; 뗓; 뗓; 뗓; ) HANGUL SYLLABLE DDEC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11BE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_132)
{
    // B5D4;B5D4;1104 1166 11BF;B5D4;1104 1166 11BF;
    // (뗔; 뗔; 뗔; 뗔; 뗔; ) HANGUL SYLLABLE DDEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11BF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_133)
{
    // B5D5;B5D5;1104 1166 11C0;B5D5;1104 1166 11C0;
    // (뗕; 뗕; 뗕; 뗕; 뗕; ) HANGUL SYLLABLE DDET
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11C0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_134)
{
    // B5D6;B5D6;1104 1166 11C1;B5D6;1104 1166 11C1;
    // (뗖; 뗖; 뗖; 뗖; 뗖; ) HANGUL SYLLABLE DDEP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11C1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_135)
{
    // B5D7;B5D7;1104 1166 11C2;B5D7;1104 1166 11C2;
    // (뗗; 뗗; 뗗; 뗗; 뗗; ) HANGUL SYLLABLE DDEH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1166, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1166, 0x11C2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_136)
{
    // B5D8;B5D8;1104 1167;B5D8;1104 1167;
    // (뗘; 뗘; 뗘; 뗘; 뗘; ) HANGUL SYLLABLE DDYEO
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D8 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1104, 0x1167 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D8 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1104, 0x1167 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_137)
{
    // B5D9;B5D9;1104 1167 11A8;B5D9;1104 1167 11A8;
    // (뗙; 뗙; 뗙; 뗙; 뗙; ) HANGUL SYLLABLE DDYEOG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5D9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5D9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5D9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11A8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_138)
{
    // B5DA;B5DA;1104 1167 11A9;B5DA;1104 1167 11A9;
    // (뗚; 뗚; 뗚; 뗚; 뗚; ) HANGUL SYLLABLE DDYEOGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5DA }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5DA }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5DA }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11A9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_139)
{
    // B5DB;B5DB;1104 1167 11AA;B5DB;1104 1167 11AA;
    // (뗛; 뗛; 뗛; 뗛; 뗛; ) HANGUL SYLLABLE DDYEOGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5DB }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5DB }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5DB }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11AA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_140)
{
    // B5DC;B5DC;1104 1167 11AB;B5DC;1104 1167 11AB;
    // (뗜; 뗜; 뗜; 뗜; 뗜; ) HANGUL SYLLABLE DDYEON
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5DC }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5DC }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5DC }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11AB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_141)
{
    // B5DD;B5DD;1104 1167 11AC;B5DD;1104 1167 11AC;
    // (뗝; 뗝; 뗝; 뗝; 뗝; ) HANGUL SYLLABLE DDYEONJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5DD }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5DD }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5DD }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11AC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_142)
{
    // B5DE;B5DE;1104 1167 11AD;B5DE;1104 1167 11AD;
    // (뗞; 뗞; 뗞; 뗞; 뗞; ) HANGUL SYLLABLE DDYEONH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5DE }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5DE }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5DE }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11AD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_143)
{
    // B5DF;B5DF;1104 1167 11AE;B5DF;1104 1167 11AE;
    // (뗟; 뗟; 뗟; 뗟; 뗟; ) HANGUL SYLLABLE DDYEOD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5DF }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5DF }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5DF }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11AE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_144)
{
    // B5E0;B5E0;1104 1167 11AF;B5E0;1104 1167 11AF;
    // (뗠; 뗠; 뗠; 뗠; 뗠; ) HANGUL SYLLABLE DDYEOL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11AF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_145)
{
    // B5E1;B5E1;1104 1167 11B0;B5E1;1104 1167 11B0;
    // (뗡; 뗡; 뗡; 뗡; 뗡; ) HANGUL SYLLABLE DDYEOLG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_146)
{
    // B5E2;B5E2;1104 1167 11B1;B5E2;1104 1167 11B1;
    // (뗢; 뗢; 뗢; 뗢; 뗢; ) HANGUL SYLLABLE DDYEOLM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_147)
{
    // B5E3;B5E3;1104 1167 11B2;B5E3;1104 1167 11B2;
    // (뗣; 뗣; 뗣; 뗣; 뗣; ) HANGUL SYLLABLE DDYEOLB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_148)
{
    // B5E4;B5E4;1104 1167 11B3;B5E4;1104 1167 11B3;
    // (뗤; 뗤; 뗤; 뗤; 뗤; ) HANGUL SYLLABLE DDYEOLS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B3 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_149)
{
    // B5E5;B5E5;1104 1167 11B4;B5E5;1104 1167 11B4;
    // (뗥; 뗥; 뗥; 뗥; 뗥; ) HANGUL SYLLABLE DDYEOLT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B4 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_150)
{
    // B5E6;B5E6;1104 1167 11B5;B5E6;1104 1167 11B5;
    // (뗦; 뗦; 뗦; 뗦; 뗦; ) HANGUL SYLLABLE DDYEOLP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B5 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_151)
{
    // B5E7;B5E7;1104 1167 11B6;B5E7;1104 1167 11B6;
    // (뗧; 뗧; 뗧; 뗧; 뗧; ) HANGUL SYLLABLE DDYEOLH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B6 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_152)
{
    // B5E8;B5E8;1104 1167 11B7;B5E8;1104 1167 11B7;
    // (뗨; 뗨; 뗨; 뗨; 뗨; ) HANGUL SYLLABLE DDYEOM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B7 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_153)
{
    // B5E9;B5E9;1104 1167 11B8;B5E9;1104 1167 11B8;
    // (뗩; 뗩; 뗩; 뗩; 뗩; ) HANGUL SYLLABLE DDYEOB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5E9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5E9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5E9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_154)
{
    // B5EA;B5EA;1104 1167 11B9;B5EA;1104 1167 11B9;
    // (뗪; 뗪; 뗪; 뗪; 뗪; ) HANGUL SYLLABLE DDYEOBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5EA }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5EA }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5EA }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11B9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_155)
{
    // B5EB;B5EB;1104 1167 11BA;B5EB;1104 1167 11BA;
    // (뗫; 뗫; 뗫; 뗫; 뗫; ) HANGUL SYLLABLE DDYEOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5EB }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5EB }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5EB }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11BA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_156)
{
    // B5EC;B5EC;1104 1167 11BB;B5EC;1104 1167 11BB;
    // (뗬; 뗬; 뗬; 뗬; 뗬; ) HANGUL SYLLABLE DDYEOSS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5EC }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5EC }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5EC }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11BB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_157)
{
    // B5ED;B5ED;1104 1167 11BC;B5ED;1104 1167 11BC;
    // (뗭; 뗭; 뗭; 뗭; 뗭; ) HANGUL SYLLABLE DDYEONG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5ED }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5ED }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5ED }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11BC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_158)
{
    // B5EE;B5EE;1104 1167 11BD;B5EE;1104 1167 11BD;
    // (뗮; 뗮; 뗮; 뗮; 뗮; ) HANGUL SYLLABLE DDYEOJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5EE }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5EE }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5EE }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11BD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_159)
{
    // B5EF;B5EF;1104 1167 11BE;B5EF;1104 1167 11BE;
    // (뗯; 뗯; 뗯; 뗯; 뗯; ) HANGUL SYLLABLE DDYEOC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5EF }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5EF }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5EF }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11BE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_160)
{
    // B5F0;B5F0;1104 1167 11BF;B5F0;1104 1167 11BF;
    // (뗰; 뗰; 뗰; 뗰; 뗰; ) HANGUL SYLLABLE DDYEOK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11BF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_161)
{
    // B5F1;B5F1;1104 1167 11C0;B5F1;1104 1167 11C0;
    // (뗱; 뗱; 뗱; 뗱; 뗱; ) HANGUL SYLLABLE DDYEOT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11C0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_162)
{
    // B5F2;B5F2;1104 1167 11C1;B5F2;1104 1167 11C1;
    // (뗲; 뗲; 뗲; 뗲; 뗲; ) HANGUL SYLLABLE DDYEOP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11C1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_163)
{
    // B5F3;B5F3;1104 1167 11C2;B5F3;1104 1167 11C2;
    // (뗳; 뗳; 뗳; 뗳; 뗳; ) HANGUL SYLLABLE DDYEOH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1167, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1167, 0x11C2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_164)
{
    // B5F4;B5F4;1104 1168;B5F4;1104 1168;
    // (뗴; 뗴; 뗴; 뗴; 뗴; ) HANGUL SYLLABLE DDYE
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F4 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1104, 0x1168 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F4 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1104, 0x1168 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_165)
{
    // B5F5;B5F5;1104 1168 11A8;B5F5;1104 1168 11A8;
    // (뗵; 뗵; 뗵; 뗵; 뗵; ) HANGUL SYLLABLE DDYEG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11A8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_166)
{
    // B5F6;B5F6;1104 1168 11A9;B5F6;1104 1168 11A9;
    // (뗶; 뗶; 뗶; 뗶; 뗶; ) HANGUL SYLLABLE DDYEGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11A9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_167)
{
    // B5F7;B5F7;1104 1168 11AA;B5F7;1104 1168 11AA;
    // (뗷; 뗷; 뗷; 뗷; 뗷; ) HANGUL SYLLABLE DDYEGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11AA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_168)
{
    // B5F8;B5F8;1104 1168 11AB;B5F8;1104 1168 11AB;
    // (뗸; 뗸; 뗸; 뗸; 뗸; ) HANGUL SYLLABLE DDYEN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11AB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_169)
{
    // B5F9;B5F9;1104 1168 11AC;B5F9;1104 1168 11AC;
    // (뗹; 뗹; 뗹; 뗹; 뗹; ) HANGUL SYLLABLE DDYENJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5F9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5F9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5F9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11AC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_170)
{
    // B5FA;B5FA;1104 1168 11AD;B5FA;1104 1168 11AD;
    // (뗺; 뗺; 뗺; 뗺; 뗺; ) HANGUL SYLLABLE DDYENH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5FA }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5FA }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5FA }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11AD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_171)
{
    // B5FB;B5FB;1104 1168 11AE;B5FB;1104 1168 11AE;
    // (뗻; 뗻; 뗻; 뗻; 뗻; ) HANGUL SYLLABLE DDYED
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5FB }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5FB }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5FB }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11AE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_172)
{
    // B5FC;B5FC;1104 1168 11AF;B5FC;1104 1168 11AF;
    // (뗼; 뗼; 뗼; 뗼; 뗼; ) HANGUL SYLLABLE DDYEL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5FC }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5FC }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5FC }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11AF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_173)
{
    // B5FD;B5FD;1104 1168 11B0;B5FD;1104 1168 11B0;
    // (뗽; 뗽; 뗽; 뗽; 뗽; ) HANGUL SYLLABLE DDYELG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5FD }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5FD }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5FD }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_174)
{
    // B5FE;B5FE;1104 1168 11B1;B5FE;1104 1168 11B1;
    // (뗾; 뗾; 뗾; 뗾; 뗾; ) HANGUL SYLLABLE DDYELM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5FE }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5FE }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5FE }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_175)
{
    // B5FF;B5FF;1104 1168 11B2;B5FF;1104 1168 11B2;
    // (뗿; 뗿; 뗿; 뗿; 뗿; ) HANGUL SYLLABLE DDYELB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB5FF }};
        std::array<uint32_t, 1> const c2 = {{ 0xB5FF }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB5FF }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_176)
{
    // B600;B600;1104 1168 11B3;B600;1104 1168 11B3;
    // (똀; 똀; 똀; 똀; 똀; ) HANGUL SYLLABLE DDYELS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB600 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB600 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB600 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B3 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_177)
{
    // B601;B601;1104 1168 11B4;B601;1104 1168 11B4;
    // (똁; 똁; 똁; 똁; 똁; ) HANGUL SYLLABLE DDYELT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB601 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB601 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB601 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B4 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_178)
{
    // B602;B602;1104 1168 11B5;B602;1104 1168 11B5;
    // (똂; 똂; 똂; 똂; 똂; ) HANGUL SYLLABLE DDYELP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB602 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB602 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB602 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B5 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_179)
{
    // B603;B603;1104 1168 11B6;B603;1104 1168 11B6;
    // (똃; 똃; 똃; 똃; 똃; ) HANGUL SYLLABLE DDYELH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB603 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB603 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB603 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B6 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_180)
{
    // B604;B604;1104 1168 11B7;B604;1104 1168 11B7;
    // (똄; 똄; 똄; 똄; 똄; ) HANGUL SYLLABLE DDYEM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB604 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB604 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB604 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B7 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_181)
{
    // B605;B605;1104 1168 11B8;B605;1104 1168 11B8;
    // (똅; 똅; 똅; 똅; 똅; ) HANGUL SYLLABLE DDYEB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB605 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB605 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB605 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_182)
{
    // B606;B606;1104 1168 11B9;B606;1104 1168 11B9;
    // (똆; 똆; 똆; 똆; 똆; ) HANGUL SYLLABLE DDYEBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB606 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB606 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB606 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11B9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_183)
{
    // B607;B607;1104 1168 11BA;B607;1104 1168 11BA;
    // (똇; 똇; 똇; 똇; 똇; ) HANGUL SYLLABLE DDYES
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB607 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB607 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB607 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11BA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_184)
{
    // B608;B608;1104 1168 11BB;B608;1104 1168 11BB;
    // (똈; 똈; 똈; 똈; 똈; ) HANGUL SYLLABLE DDYESS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB608 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB608 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB608 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11BB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_185)
{
    // B609;B609;1104 1168 11BC;B609;1104 1168 11BC;
    // (똉; 똉; 똉; 똉; 똉; ) HANGUL SYLLABLE DDYENG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB609 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB609 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB609 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11BC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_186)
{
    // B60A;B60A;1104 1168 11BD;B60A;1104 1168 11BD;
    // (똊; 똊; 똊; 똊; 똊; ) HANGUL SYLLABLE DDYEJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB60A }};
        std::array<uint32_t, 1> const c2 = {{ 0xB60A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB60A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11BD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_187)
{
    // B60B;B60B;1104 1168 11BE;B60B;1104 1168 11BE;
    // (똋; 똋; 똋; 똋; 똋; ) HANGUL SYLLABLE DDYEC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB60B }};
        std::array<uint32_t, 1> const c2 = {{ 0xB60B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB60B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11BE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_188)
{
    // B60C;B60C;1104 1168 11BF;B60C;1104 1168 11BF;
    // (똌; 똌; 똌; 똌; 똌; ) HANGUL SYLLABLE DDYEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB60C }};
        std::array<uint32_t, 1> const c2 = {{ 0xB60C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xB60C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11BF }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_189)
{
    // B60D;B60D;1104 1168 11C0;B60D;1104 1168 11C0;
    // (똍; 똍; 똍; 똍; 똍; ) HANGUL SYLLABLE DDYET
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB60D }};
        std::array<uint32_t, 1> const c2 = {{ 0xB60D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB60D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11C0 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_190)
{
    // B60E;B60E;1104 1168 11C1;B60E;1104 1168 11C1;
    // (똎; 똎; 똎; 똎; 똎; ) HANGUL SYLLABLE DDYEP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB60E }};
        std::array<uint32_t, 1> const c2 = {{ 0xB60E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB60E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11C1 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_191)
{
    // B60F;B60F;1104 1168 11C2;B60F;1104 1168 11C2;
    // (똏; 똏; 똏; 똏; 똏; ) HANGUL SYLLABLE DDYEH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB60F }};
        std::array<uint32_t, 1> const c2 = {{ 0xB60F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1168, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB60F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1168, 0x11C2 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_192)
{
    // B610;B610;1104 1169;B610;1104 1169;
    // (또; 또; 또; 또; 또; ) HANGUL SYLLABLE DDO
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB610 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB610 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1104, 0x1169 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB610 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1104, 0x1169 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_193)
{
    // B611;B611;1104 1169 11A8;B611;1104 1169 11A8;
    // (똑; 똑; 똑; 똑; 똑; ) HANGUL SYLLABLE DDOG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB611 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB611 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1169, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB611 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1169, 0x11A8 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_194)
{
    // B612;B612;1104 1169 11A9;B612;1104 1169 11A9;
    // (똒; 똒; 똒; 똒; 똒; ) HANGUL SYLLABLE DDOGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB612 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB612 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1169, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xB612 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1169, 0x11A9 }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_195)
{
    // B613;B613;1104 1169 11AA;B613;1104 1169 11AA;
    // (똓; 똓; 똓; 똓; 똓; ) HANGUL SYLLABLE DDOGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB613 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB613 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1169, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xB613 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1169, 0x11AA }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_196)
{
    // B614;B614;1104 1169 11AB;B614;1104 1169 11AB;
    // (똔; 똔; 똔; 똔; 똔; ) HANGUL SYLLABLE DDON
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB614 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB614 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1169, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xB614 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1169, 0x11AB }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_197)
{
    // B615;B615;1104 1169 11AC;B615;1104 1169 11AC;
    // (똕; 똕; 똕; 똕; 똕; ) HANGUL SYLLABLE DDONJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB615 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB615 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1169, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xB615 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1169, 0x11AC }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_198)
{
    // B616;B616;1104 1169 11AD;B616;1104 1169 11AD;
    // (똖; 똖; 똖; 똖; 똖; ) HANGUL SYLLABLE DDONH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB616 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB616 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1169, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xB616 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1169, 0x11AD }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkd_024_199)
{
    // B617;B617;1104 1169 11AE;B617;1104 1169 11AE;
    // (똗; 똗; 똗; 똗; 똗; ) HANGUL SYLLABLE DDOD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xB617 }};
        std::array<uint32_t, 1> const c2 = {{ 0xB617 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1104, 0x1169, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xB617 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1104, 0x1169, 0x11AE }};

        EXPECT_TRUE(boost::text::normalized_nfc(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized_nfc(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized_nfkc(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized_nfd(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized_nfkd(c5.begin(), c5.end()));

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize_to_nfkd(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c5.size());
            auto c5_it = c5.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c5_it) << "iteration " << i;
                ++c5_it;
                ++i;
            }
        }

    }
}

max_stars_repo_name: eightysquirrels/text

max_issues_repo_name: eightysquirrels/text

max_forks_repo_name: eightysquirrels/text