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, nfkc_016_000)
{
    // AF10;AF10;1101 1168;AF10;1101 1168;
    // (꼐; 꼐; 꼐; 꼐; 꼐; ) HANGUL SYLLABLE GGYE
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF10 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF10 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1101, 0x1168 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF10 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_001)
{
    // AF11;AF11;1101 1168 11A8;AF11;1101 1168 11A8;
    // (꼑; 꼑; 꼑; 꼑; 꼑; ) HANGUL SYLLABLE GGYEG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF11 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF11 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF11 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_002)
{
    // AF12;AF12;1101 1168 11A9;AF12;1101 1168 11A9;
    // (꼒; 꼒; 꼒; 꼒; 꼒; ) HANGUL SYLLABLE GGYEGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF12 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF12 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF12 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_003)
{
    // AF13;AF13;1101 1168 11AA;AF13;1101 1168 11AA;
    // (꼓; 꼓; 꼓; 꼓; 꼓; ) HANGUL SYLLABLE GGYEGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF13 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF13 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF13 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_004)
{
    // AF14;AF14;1101 1168 11AB;AF14;1101 1168 11AB;
    // (꼔; 꼔; 꼔; 꼔; 꼔; ) HANGUL SYLLABLE GGYEN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF14 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF14 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF14 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_005)
{
    // AF15;AF15;1101 1168 11AC;AF15;1101 1168 11AC;
    // (꼕; 꼕; 꼕; 꼕; 꼕; ) HANGUL SYLLABLE GGYENJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF15 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF15 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF15 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_006)
{
    // AF16;AF16;1101 1168 11AD;AF16;1101 1168 11AD;
    // (꼖; 꼖; 꼖; 꼖; 꼖; ) HANGUL SYLLABLE GGYENH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF16 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF16 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF16 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_007)
{
    // AF17;AF17;1101 1168 11AE;AF17;1101 1168 11AE;
    // (꼗; 꼗; 꼗; 꼗; 꼗; ) HANGUL SYLLABLE GGYED
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF17 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF17 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF17 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_008)
{
    // AF18;AF18;1101 1168 11AF;AF18;1101 1168 11AF;
    // (꼘; 꼘; 꼘; 꼘; 꼘; ) HANGUL SYLLABLE GGYEL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF18 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF18 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF18 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_009)
{
    // AF19;AF19;1101 1168 11B0;AF19;1101 1168 11B0;
    // (꼙; 꼙; 꼙; 꼙; 꼙; ) HANGUL SYLLABLE GGYELG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF19 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF19 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF19 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_010)
{
    // AF1A;AF1A;1101 1168 11B1;AF1A;1101 1168 11B1;
    // (꼚; 꼚; 꼚; 꼚; 꼚; ) HANGUL SYLLABLE GGYELM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF1A }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF1A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF1A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_011)
{
    // AF1B;AF1B;1101 1168 11B2;AF1B;1101 1168 11B2;
    // (꼛; 꼛; 꼛; 꼛; 꼛; ) HANGUL SYLLABLE GGYELB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF1B }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF1B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF1B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_012)
{
    // AF1C;AF1C;1101 1168 11B3;AF1C;1101 1168 11B3;
    // (꼜; 꼜; 꼜; 꼜; 꼜; ) HANGUL SYLLABLE GGYELS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF1C }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF1C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF1C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_013)
{
    // AF1D;AF1D;1101 1168 11B4;AF1D;1101 1168 11B4;
    // (꼝; 꼝; 꼝; 꼝; 꼝; ) HANGUL SYLLABLE GGYELT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF1D }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF1D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF1D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_014)
{
    // AF1E;AF1E;1101 1168 11B5;AF1E;1101 1168 11B5;
    // (꼞; 꼞; 꼞; 꼞; 꼞; ) HANGUL SYLLABLE GGYELP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF1E }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF1E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF1E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_015)
{
    // AF1F;AF1F;1101 1168 11B6;AF1F;1101 1168 11B6;
    // (꼟; 꼟; 꼟; 꼟; 꼟; ) HANGUL SYLLABLE GGYELH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF1F }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF1F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF1F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_016)
{
    // AF20;AF20;1101 1168 11B7;AF20;1101 1168 11B7;
    // (꼠; 꼠; 꼠; 꼠; 꼠; ) HANGUL SYLLABLE GGYEM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF20 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF20 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF20 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_017)
{
    // AF21;AF21;1101 1168 11B8;AF21;1101 1168 11B8;
    // (꼡; 꼡; 꼡; 꼡; 꼡; ) HANGUL SYLLABLE GGYEB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF21 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF21 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF21 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_018)
{
    // AF22;AF22;1101 1168 11B9;AF22;1101 1168 11B9;
    // (꼢; 꼢; 꼢; 꼢; 꼢; ) HANGUL SYLLABLE GGYEBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF22 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF22 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF22 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_019)
{
    // AF23;AF23;1101 1168 11BA;AF23;1101 1168 11BA;
    // (꼣; 꼣; 꼣; 꼣; 꼣; ) HANGUL SYLLABLE GGYES
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF23 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF23 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF23 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_020)
{
    // AF24;AF24;1101 1168 11BB;AF24;1101 1168 11BB;
    // (꼤; 꼤; 꼤; 꼤; 꼤; ) HANGUL SYLLABLE GGYESS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF24 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF24 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF24 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_021)
{
    // AF25;AF25;1101 1168 11BC;AF25;1101 1168 11BC;
    // (꼥; 꼥; 꼥; 꼥; 꼥; ) HANGUL SYLLABLE GGYENG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF25 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF25 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF25 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_022)
{
    // AF26;AF26;1101 1168 11BD;AF26;1101 1168 11BD;
    // (꼦; 꼦; 꼦; 꼦; 꼦; ) HANGUL SYLLABLE GGYEJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF26 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF26 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF26 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_023)
{
    // AF27;AF27;1101 1168 11BE;AF27;1101 1168 11BE;
    // (꼧; 꼧; 꼧; 꼧; 꼧; ) HANGUL SYLLABLE GGYEC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF27 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF27 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF27 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_024)
{
    // AF28;AF28;1101 1168 11BF;AF28;1101 1168 11BF;
    // (꼨; 꼨; 꼨; 꼨; 꼨; ) HANGUL SYLLABLE GGYEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF28 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF28 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF28 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_025)
{
    // AF29;AF29;1101 1168 11C0;AF29;1101 1168 11C0;
    // (꼩; 꼩; 꼩; 꼩; 꼩; ) HANGUL SYLLABLE GGYET
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF29 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF29 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF29 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_026)
{
    // AF2A;AF2A;1101 1168 11C1;AF2A;1101 1168 11C1;
    // (꼪; 꼪; 꼪; 꼪; 꼪; ) HANGUL SYLLABLE GGYEP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF2A }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF2A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF2A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_027)
{
    // AF2B;AF2B;1101 1168 11C2;AF2B;1101 1168 11C2;
    // (꼫; 꼫; 꼫; 꼫; 꼫; ) HANGUL SYLLABLE GGYEH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF2B }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF2B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1168, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF2B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_028)
{
    // AF2C;AF2C;1101 1169;AF2C;1101 1169;
    // (꼬; 꼬; 꼬; 꼬; 꼬; ) HANGUL SYLLABLE GGO
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF2C }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF2C }};
        std::array<uint32_t, 2> const c3 = {{ 0x1101, 0x1169 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF2C }};
        std::array<uint32_t, 2> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_029)
{
    // AF2D;AF2D;1101 1169 11A8;AF2D;1101 1169 11A8;
    // (꼭; 꼭; 꼭; 꼭; 꼭; ) HANGUL SYLLABLE GGOG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF2D }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF2D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF2D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_030)
{
    // AF2E;AF2E;1101 1169 11A9;AF2E;1101 1169 11A9;
    // (꼮; 꼮; 꼮; 꼮; 꼮; ) HANGUL SYLLABLE GGOGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF2E }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF2E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF2E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_031)
{
    // AF2F;AF2F;1101 1169 11AA;AF2F;1101 1169 11AA;
    // (꼯; 꼯; 꼯; 꼯; 꼯; ) HANGUL SYLLABLE GGOGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF2F }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF2F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF2F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_032)
{
    // AF30;AF30;1101 1169 11AB;AF30;1101 1169 11AB;
    // (꼰; 꼰; 꼰; 꼰; 꼰; ) HANGUL SYLLABLE GGON
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF30 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF30 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF30 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_033)
{
    // AF31;AF31;1101 1169 11AC;AF31;1101 1169 11AC;
    // (꼱; 꼱; 꼱; 꼱; 꼱; ) HANGUL SYLLABLE GGONJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF31 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF31 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF31 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_034)
{
    // AF32;AF32;1101 1169 11AD;AF32;1101 1169 11AD;
    // (꼲; 꼲; 꼲; 꼲; 꼲; ) HANGUL SYLLABLE GGONH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF32 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF32 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF32 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_035)
{
    // AF33;AF33;1101 1169 11AE;AF33;1101 1169 11AE;
    // (꼳; 꼳; 꼳; 꼳; 꼳; ) HANGUL SYLLABLE GGOD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF33 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF33 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF33 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_036)
{
    // AF34;AF34;1101 1169 11AF;AF34;1101 1169 11AF;
    // (꼴; 꼴; 꼴; 꼴; 꼴; ) HANGUL SYLLABLE GGOL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF34 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF34 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF34 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_037)
{
    // AF35;AF35;1101 1169 11B0;AF35;1101 1169 11B0;
    // (꼵; 꼵; 꼵; 꼵; 꼵; ) HANGUL SYLLABLE GGOLG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF35 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF35 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF35 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_038)
{
    // AF36;AF36;1101 1169 11B1;AF36;1101 1169 11B1;
    // (꼶; 꼶; 꼶; 꼶; 꼶; ) HANGUL SYLLABLE GGOLM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF36 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF36 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF36 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_039)
{
    // AF37;AF37;1101 1169 11B2;AF37;1101 1169 11B2;
    // (꼷; 꼷; 꼷; 꼷; 꼷; ) HANGUL SYLLABLE GGOLB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF37 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF37 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF37 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_040)
{
    // AF38;AF38;1101 1169 11B3;AF38;1101 1169 11B3;
    // (꼸; 꼸; 꼸; 꼸; 꼸; ) HANGUL SYLLABLE GGOLS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF38 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF38 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF38 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_041)
{
    // AF39;AF39;1101 1169 11B4;AF39;1101 1169 11B4;
    // (꼹; 꼹; 꼹; 꼹; 꼹; ) HANGUL SYLLABLE GGOLT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF39 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF39 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF39 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_042)
{
    // AF3A;AF3A;1101 1169 11B5;AF3A;1101 1169 11B5;
    // (꼺; 꼺; 꼺; 꼺; 꼺; ) HANGUL SYLLABLE GGOLP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF3A }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF3A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF3A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_043)
{
    // AF3B;AF3B;1101 1169 11B6;AF3B;1101 1169 11B6;
    // (꼻; 꼻; 꼻; 꼻; 꼻; ) HANGUL SYLLABLE GGOLH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF3B }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF3B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF3B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_044)
{
    // AF3C;AF3C;1101 1169 11B7;AF3C;1101 1169 11B7;
    // (꼼; 꼼; 꼼; 꼼; 꼼; ) HANGUL SYLLABLE GGOM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF3C }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF3C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF3C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_045)
{
    // AF3D;AF3D;1101 1169 11B8;AF3D;1101 1169 11B8;
    // (꼽; 꼽; 꼽; 꼽; 꼽; ) HANGUL SYLLABLE GGOB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF3D }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF3D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF3D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_046)
{
    // AF3E;AF3E;1101 1169 11B9;AF3E;1101 1169 11B9;
    // (꼾; 꼾; 꼾; 꼾; 꼾; ) HANGUL SYLLABLE GGOBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF3E }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF3E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF3E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_047)
{
    // AF3F;AF3F;1101 1169 11BA;AF3F;1101 1169 11BA;
    // (꼿; 꼿; 꼿; 꼿; 꼿; ) HANGUL SYLLABLE GGOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF3F }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF3F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF3F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_048)
{
    // AF40;AF40;1101 1169 11BB;AF40;1101 1169 11BB;
    // (꽀; 꽀; 꽀; 꽀; 꽀; ) HANGUL SYLLABLE GGOSS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF40 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF40 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF40 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_049)
{
    // AF41;AF41;1101 1169 11BC;AF41;1101 1169 11BC;
    // (꽁; 꽁; 꽁; 꽁; 꽁; ) HANGUL SYLLABLE GGONG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF41 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF41 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF41 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_050)
{
    // AF42;AF42;1101 1169 11BD;AF42;1101 1169 11BD;
    // (꽂; 꽂; 꽂; 꽂; 꽂; ) HANGUL SYLLABLE GGOJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF42 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF42 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF42 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_051)
{
    // AF43;AF43;1101 1169 11BE;AF43;1101 1169 11BE;
    // (꽃; 꽃; 꽃; 꽃; 꽃; ) HANGUL SYLLABLE GGOC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF43 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF43 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF43 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_052)
{
    // AF44;AF44;1101 1169 11BF;AF44;1101 1169 11BF;
    // (꽄; 꽄; 꽄; 꽄; 꽄; ) HANGUL SYLLABLE GGOK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF44 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF44 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF44 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_053)
{
    // AF45;AF45;1101 1169 11C0;AF45;1101 1169 11C0;
    // (꽅; 꽅; 꽅; 꽅; 꽅; ) HANGUL SYLLABLE GGOT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF45 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF45 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF45 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_054)
{
    // AF46;AF46;1101 1169 11C1;AF46;1101 1169 11C1;
    // (꽆; 꽆; 꽆; 꽆; 꽆; ) HANGUL SYLLABLE GGOP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF46 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF46 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF46 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_055)
{
    // AF47;AF47;1101 1169 11C2;AF47;1101 1169 11C2;
    // (꽇; 꽇; 꽇; 꽇; 꽇; ) HANGUL SYLLABLE GGOH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF47 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF47 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x1169, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF47 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x1169, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_056)
{
    // AF48;AF48;1101 116A;AF48;1101 116A;
    // (꽈; 꽈; 꽈; 꽈; 꽈; ) HANGUL SYLLABLE GGWA
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF48 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF48 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1101, 0x116A }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF48 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1101, 0x116A }};

        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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_057)
{
    // AF49;AF49;1101 116A 11A8;AF49;1101 116A 11A8;
    // (꽉; 꽉; 꽉; 꽉; 꽉; ) HANGUL SYLLABLE GGWAG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF49 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF49 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF49 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_058)
{
    // AF4A;AF4A;1101 116A 11A9;AF4A;1101 116A 11A9;
    // (꽊; 꽊; 꽊; 꽊; 꽊; ) HANGUL SYLLABLE GGWAGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF4A }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF4A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF4A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_059)
{
    // AF4B;AF4B;1101 116A 11AA;AF4B;1101 116A 11AA;
    // (꽋; 꽋; 꽋; 꽋; 꽋; ) HANGUL SYLLABLE GGWAGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF4B }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF4B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF4B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_060)
{
    // AF4C;AF4C;1101 116A 11AB;AF4C;1101 116A 11AB;
    // (꽌; 꽌; 꽌; 꽌; 꽌; ) HANGUL SYLLABLE GGWAN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF4C }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF4C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF4C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_061)
{
    // AF4D;AF4D;1101 116A 11AC;AF4D;1101 116A 11AC;
    // (꽍; 꽍; 꽍; 꽍; 꽍; ) HANGUL SYLLABLE GGWANJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF4D }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF4D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF4D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_062)
{
    // AF4E;AF4E;1101 116A 11AD;AF4E;1101 116A 11AD;
    // (꽎; 꽎; 꽎; 꽎; 꽎; ) HANGUL SYLLABLE GGWANH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF4E }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF4E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF4E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_063)
{
    // AF4F;AF4F;1101 116A 11AE;AF4F;1101 116A 11AE;
    // (꽏; 꽏; 꽏; 꽏; 꽏; ) HANGUL SYLLABLE GGWAD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF4F }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF4F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF4F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_064)
{
    // AF50;AF50;1101 116A 11AF;AF50;1101 116A 11AF;
    // (꽐; 꽐; 꽐; 꽐; 꽐; ) HANGUL SYLLABLE GGWAL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF50 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF50 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF50 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_065)
{
    // AF51;AF51;1101 116A 11B0;AF51;1101 116A 11B0;
    // (꽑; 꽑; 꽑; 꽑; 꽑; ) HANGUL SYLLABLE GGWALG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF51 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF51 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF51 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_066)
{
    // AF52;AF52;1101 116A 11B1;AF52;1101 116A 11B1;
    // (꽒; 꽒; 꽒; 꽒; 꽒; ) HANGUL SYLLABLE GGWALM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF52 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF52 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF52 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_067)
{
    // AF53;AF53;1101 116A 11B2;AF53;1101 116A 11B2;
    // (꽓; 꽓; 꽓; 꽓; 꽓; ) HANGUL SYLLABLE GGWALB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF53 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF53 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF53 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_068)
{
    // AF54;AF54;1101 116A 11B3;AF54;1101 116A 11B3;
    // (꽔; 꽔; 꽔; 꽔; 꽔; ) HANGUL SYLLABLE GGWALS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF54 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF54 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF54 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_069)
{
    // AF55;AF55;1101 116A 11B4;AF55;1101 116A 11B4;
    // (꽕; 꽕; 꽕; 꽕; 꽕; ) HANGUL SYLLABLE GGWALT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF55 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF55 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF55 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_070)
{
    // AF56;AF56;1101 116A 11B5;AF56;1101 116A 11B5;
    // (꽖; 꽖; 꽖; 꽖; 꽖; ) HANGUL SYLLABLE GGWALP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF56 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF56 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF56 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_071)
{
    // AF57;AF57;1101 116A 11B6;AF57;1101 116A 11B6;
    // (꽗; 꽗; 꽗; 꽗; 꽗; ) HANGUL SYLLABLE GGWALH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF57 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF57 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF57 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_072)
{
    // AF58;AF58;1101 116A 11B7;AF58;1101 116A 11B7;
    // (꽘; 꽘; 꽘; 꽘; 꽘; ) HANGUL SYLLABLE GGWAM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF58 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF58 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF58 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_073)
{
    // AF59;AF59;1101 116A 11B8;AF59;1101 116A 11B8;
    // (꽙; 꽙; 꽙; 꽙; 꽙; ) HANGUL SYLLABLE GGWAB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF59 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF59 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF59 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_074)
{
    // AF5A;AF5A;1101 116A 11B9;AF5A;1101 116A 11B9;
    // (꽚; 꽚; 꽚; 꽚; 꽚; ) HANGUL SYLLABLE GGWABS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF5A }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF5A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF5A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_075)
{
    // AF5B;AF5B;1101 116A 11BA;AF5B;1101 116A 11BA;
    // (꽛; 꽛; 꽛; 꽛; 꽛; ) HANGUL SYLLABLE GGWAS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF5B }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF5B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF5B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_076)
{
    // AF5C;AF5C;1101 116A 11BB;AF5C;1101 116A 11BB;
    // (꽜; 꽜; 꽜; 꽜; 꽜; ) HANGUL SYLLABLE GGWASS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF5C }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF5C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF5C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_077)
{
    // AF5D;AF5D;1101 116A 11BC;AF5D;1101 116A 11BC;
    // (꽝; 꽝; 꽝; 꽝; 꽝; ) HANGUL SYLLABLE GGWANG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF5D }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF5D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF5D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_078)
{
    // AF5E;AF5E;1101 116A 11BD;AF5E;1101 116A 11BD;
    // (꽞; 꽞; 꽞; 꽞; 꽞; ) HANGUL SYLLABLE GGWAJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF5E }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF5E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF5E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_079)
{
    // AF5F;AF5F;1101 116A 11BE;AF5F;1101 116A 11BE;
    // (꽟; 꽟; 꽟; 꽟; 꽟; ) HANGUL SYLLABLE GGWAC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF5F }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF5F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF5F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_080)
{
    // AF60;AF60;1101 116A 11BF;AF60;1101 116A 11BF;
    // (꽠; 꽠; 꽠; 꽠; 꽠; ) HANGUL SYLLABLE GGWAK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF60 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF60 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF60 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_081)
{
    // AF61;AF61;1101 116A 11C0;AF61;1101 116A 11C0;
    // (꽡; 꽡; 꽡; 꽡; 꽡; ) HANGUL SYLLABLE GGWAT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF61 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF61 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF61 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_082)
{
    // AF62;AF62;1101 116A 11C1;AF62;1101 116A 11C1;
    // (꽢; 꽢; 꽢; 꽢; 꽢; ) HANGUL SYLLABLE GGWAP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF62 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF62 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF62 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_083)
{
    // AF63;AF63;1101 116A 11C2;AF63;1101 116A 11C2;
    // (꽣; 꽣; 꽣; 꽣; 꽣; ) HANGUL SYLLABLE GGWAH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF63 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF63 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116A, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF63 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116A, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_084)
{
    // AF64;AF64;1101 116B;AF64;1101 116B;
    // (꽤; 꽤; 꽤; 꽤; 꽤; ) HANGUL SYLLABLE GGWAE
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF64 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF64 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1101, 0x116B }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF64 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1101, 0x116B }};

        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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_085)
{
    // AF65;AF65;1101 116B 11A8;AF65;1101 116B 11A8;
    // (꽥; 꽥; 꽥; 꽥; 꽥; ) HANGUL SYLLABLE GGWAEG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF65 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF65 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF65 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_086)
{
    // AF66;AF66;1101 116B 11A9;AF66;1101 116B 11A9;
    // (꽦; 꽦; 꽦; 꽦; 꽦; ) HANGUL SYLLABLE GGWAEGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF66 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF66 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF66 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_087)
{
    // AF67;AF67;1101 116B 11AA;AF67;1101 116B 11AA;
    // (꽧; 꽧; 꽧; 꽧; 꽧; ) HANGUL SYLLABLE GGWAEGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF67 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF67 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF67 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_088)
{
    // AF68;AF68;1101 116B 11AB;AF68;1101 116B 11AB;
    // (꽨; 꽨; 꽨; 꽨; 꽨; ) HANGUL SYLLABLE GGWAEN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF68 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF68 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF68 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_089)
{
    // AF69;AF69;1101 116B 11AC;AF69;1101 116B 11AC;
    // (꽩; 꽩; 꽩; 꽩; 꽩; ) HANGUL SYLLABLE GGWAENJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF69 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF69 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF69 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_090)
{
    // AF6A;AF6A;1101 116B 11AD;AF6A;1101 116B 11AD;
    // (꽪; 꽪; 꽪; 꽪; 꽪; ) HANGUL SYLLABLE GGWAENH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF6A }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF6A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF6A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_091)
{
    // AF6B;AF6B;1101 116B 11AE;AF6B;1101 116B 11AE;
    // (꽫; 꽫; 꽫; 꽫; 꽫; ) HANGUL SYLLABLE GGWAED
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF6B }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF6B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF6B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_092)
{
    // AF6C;AF6C;1101 116B 11AF;AF6C;1101 116B 11AF;
    // (꽬; 꽬; 꽬; 꽬; 꽬; ) HANGUL SYLLABLE GGWAEL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF6C }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF6C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF6C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_093)
{
    // AF6D;AF6D;1101 116B 11B0;AF6D;1101 116B 11B0;
    // (꽭; 꽭; 꽭; 꽭; 꽭; ) HANGUL SYLLABLE GGWAELG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF6D }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF6D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF6D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_094)
{
    // AF6E;AF6E;1101 116B 11B1;AF6E;1101 116B 11B1;
    // (꽮; 꽮; 꽮; 꽮; 꽮; ) HANGUL SYLLABLE GGWAELM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF6E }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF6E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF6E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_095)
{
    // AF6F;AF6F;1101 116B 11B2;AF6F;1101 116B 11B2;
    // (꽯; 꽯; 꽯; 꽯; 꽯; ) HANGUL SYLLABLE GGWAELB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF6F }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF6F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF6F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_096)
{
    // AF70;AF70;1101 116B 11B3;AF70;1101 116B 11B3;
    // (꽰; 꽰; 꽰; 꽰; 꽰; ) HANGUL SYLLABLE GGWAELS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF70 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF70 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF70 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_097)
{
    // AF71;AF71;1101 116B 11B4;AF71;1101 116B 11B4;
    // (꽱; 꽱; 꽱; 꽱; 꽱; ) HANGUL SYLLABLE GGWAELT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF71 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF71 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF71 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_098)
{
    // AF72;AF72;1101 116B 11B5;AF72;1101 116B 11B5;
    // (꽲; 꽲; 꽲; 꽲; 꽲; ) HANGUL SYLLABLE GGWAELP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF72 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF72 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF72 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_099)
{
    // AF73;AF73;1101 116B 11B6;AF73;1101 116B 11B6;
    // (꽳; 꽳; 꽳; 꽳; 꽳; ) HANGUL SYLLABLE GGWAELH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF73 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF73 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF73 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_100)
{
    // AF74;AF74;1101 116B 11B7;AF74;1101 116B 11B7;
    // (꽴; 꽴; 꽴; 꽴; 꽴; ) HANGUL SYLLABLE GGWAEM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF74 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF74 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF74 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_101)
{
    // AF75;AF75;1101 116B 11B8;AF75;1101 116B 11B8;
    // (꽵; 꽵; 꽵; 꽵; 꽵; ) HANGUL SYLLABLE GGWAEB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF75 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF75 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF75 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_102)
{
    // AF76;AF76;1101 116B 11B9;AF76;1101 116B 11B9;
    // (꽶; 꽶; 꽶; 꽶; 꽶; ) HANGUL SYLLABLE GGWAEBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF76 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF76 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF76 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_103)
{
    // AF77;AF77;1101 116B 11BA;AF77;1101 116B 11BA;
    // (꽷; 꽷; 꽷; 꽷; 꽷; ) HANGUL SYLLABLE GGWAES
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF77 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF77 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF77 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_104)
{
    // AF78;AF78;1101 116B 11BB;AF78;1101 116B 11BB;
    // (꽸; 꽸; 꽸; 꽸; 꽸; ) HANGUL SYLLABLE GGWAESS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF78 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF78 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF78 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_105)
{
    // AF79;AF79;1101 116B 11BC;AF79;1101 116B 11BC;
    // (꽹; 꽹; 꽹; 꽹; 꽹; ) HANGUL SYLLABLE GGWAENG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF79 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF79 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF79 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_106)
{
    // AF7A;AF7A;1101 116B 11BD;AF7A;1101 116B 11BD;
    // (꽺; 꽺; 꽺; 꽺; 꽺; ) HANGUL SYLLABLE GGWAEJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF7A }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF7A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF7A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_107)
{
    // AF7B;AF7B;1101 116B 11BE;AF7B;1101 116B 11BE;
    // (꽻; 꽻; 꽻; 꽻; 꽻; ) HANGUL SYLLABLE GGWAEC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF7B }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF7B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF7B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_108)
{
    // AF7C;AF7C;1101 116B 11BF;AF7C;1101 116B 11BF;
    // (꽼; 꽼; 꽼; 꽼; 꽼; ) HANGUL SYLLABLE GGWAEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF7C }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF7C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF7C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_109)
{
    // AF7D;AF7D;1101 116B 11C0;AF7D;1101 116B 11C0;
    // (꽽; 꽽; 꽽; 꽽; 꽽; ) HANGUL SYLLABLE GGWAET
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF7D }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF7D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF7D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_110)
{
    // AF7E;AF7E;1101 116B 11C1;AF7E;1101 116B 11C1;
    // (꽾; 꽾; 꽾; 꽾; 꽾; ) HANGUL SYLLABLE GGWAEP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF7E }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF7E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF7E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_111)
{
    // AF7F;AF7F;1101 116B 11C2;AF7F;1101 116B 11C2;
    // (꽿; 꽿; 꽿; 꽿; 꽿; ) HANGUL SYLLABLE GGWAEH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF7F }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF7F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116B, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF7F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116B, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_112)
{
    // AF80;AF80;1101 116C;AF80;1101 116C;
    // (꾀; 꾀; 꾀; 꾀; 꾀; ) HANGUL SYLLABLE GGOE
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF80 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF80 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1101, 0x116C }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF80 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1101, 0x116C }};

        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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_113)
{
    // AF81;AF81;1101 116C 11A8;AF81;1101 116C 11A8;
    // (꾁; 꾁; 꾁; 꾁; 꾁; ) HANGUL SYLLABLE GGOEG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF81 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF81 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF81 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_114)
{
    // AF82;AF82;1101 116C 11A9;AF82;1101 116C 11A9;
    // (꾂; 꾂; 꾂; 꾂; 꾂; ) HANGUL SYLLABLE GGOEGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF82 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF82 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF82 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_115)
{
    // AF83;AF83;1101 116C 11AA;AF83;1101 116C 11AA;
    // (꾃; 꾃; 꾃; 꾃; 꾃; ) HANGUL SYLLABLE GGOEGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF83 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF83 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF83 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_116)
{
    // AF84;AF84;1101 116C 11AB;AF84;1101 116C 11AB;
    // (꾄; 꾄; 꾄; 꾄; 꾄; ) HANGUL SYLLABLE GGOEN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF84 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF84 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF84 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_117)
{
    // AF85;AF85;1101 116C 11AC;AF85;1101 116C 11AC;
    // (꾅; 꾅; 꾅; 꾅; 꾅; ) HANGUL SYLLABLE GGOENJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF85 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF85 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF85 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_118)
{
    // AF86;AF86;1101 116C 11AD;AF86;1101 116C 11AD;
    // (꾆; 꾆; 꾆; 꾆; 꾆; ) HANGUL SYLLABLE GGOENH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF86 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF86 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF86 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_119)
{
    // AF87;AF87;1101 116C 11AE;AF87;1101 116C 11AE;
    // (꾇; 꾇; 꾇; 꾇; 꾇; ) HANGUL SYLLABLE GGOED
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF87 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF87 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF87 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_120)
{
    // AF88;AF88;1101 116C 11AF;AF88;1101 116C 11AF;
    // (꾈; 꾈; 꾈; 꾈; 꾈; ) HANGUL SYLLABLE GGOEL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF88 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF88 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF88 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_121)
{
    // AF89;AF89;1101 116C 11B0;AF89;1101 116C 11B0;
    // (꾉; 꾉; 꾉; 꾉; 꾉; ) HANGUL SYLLABLE GGOELG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF89 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF89 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF89 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_122)
{
    // AF8A;AF8A;1101 116C 11B1;AF8A;1101 116C 11B1;
    // (꾊; 꾊; 꾊; 꾊; 꾊; ) HANGUL SYLLABLE GGOELM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF8A }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF8A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF8A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_123)
{
    // AF8B;AF8B;1101 116C 11B2;AF8B;1101 116C 11B2;
    // (꾋; 꾋; 꾋; 꾋; 꾋; ) HANGUL SYLLABLE GGOELB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF8B }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF8B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF8B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_124)
{
    // AF8C;AF8C;1101 116C 11B3;AF8C;1101 116C 11B3;
    // (꾌; 꾌; 꾌; 꾌; 꾌; ) HANGUL SYLLABLE GGOELS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF8C }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF8C }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF8C }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_125)
{
    // AF8D;AF8D;1101 116C 11B4;AF8D;1101 116C 11B4;
    // (꾍; 꾍; 꾍; 꾍; 꾍; ) HANGUL SYLLABLE GGOELT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF8D }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF8D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF8D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_126)
{
    // AF8E;AF8E;1101 116C 11B5;AF8E;1101 116C 11B5;
    // (꾎; 꾎; 꾎; 꾎; 꾎; ) HANGUL SYLLABLE GGOELP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF8E }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF8E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF8E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_127)
{
    // AF8F;AF8F;1101 116C 11B6;AF8F;1101 116C 11B6;
    // (꾏; 꾏; 꾏; 꾏; 꾏; ) HANGUL SYLLABLE GGOELH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF8F }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF8F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF8F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_128)
{
    // AF90;AF90;1101 116C 11B7;AF90;1101 116C 11B7;
    // (꾐; 꾐; 꾐; 꾐; 꾐; ) HANGUL SYLLABLE GGOEM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF90 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF90 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF90 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_129)
{
    // AF91;AF91;1101 116C 11B8;AF91;1101 116C 11B8;
    // (꾑; 꾑; 꾑; 꾑; 꾑; ) HANGUL SYLLABLE GGOEB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF91 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF91 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF91 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_130)
{
    // AF92;AF92;1101 116C 11B9;AF92;1101 116C 11B9;
    // (꾒; 꾒; 꾒; 꾒; 꾒; ) HANGUL SYLLABLE GGOEBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF92 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF92 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF92 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_131)
{
    // AF93;AF93;1101 116C 11BA;AF93;1101 116C 11BA;
    // (꾓; 꾓; 꾓; 꾓; 꾓; ) HANGUL SYLLABLE GGOES
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF93 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF93 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF93 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_132)
{
    // AF94;AF94;1101 116C 11BB;AF94;1101 116C 11BB;
    // (꾔; 꾔; 꾔; 꾔; 꾔; ) HANGUL SYLLABLE GGOESS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF94 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF94 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF94 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_133)
{
    // AF95;AF95;1101 116C 11BC;AF95;1101 116C 11BC;
    // (꾕; 꾕; 꾕; 꾕; 꾕; ) HANGUL SYLLABLE GGOENG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF95 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF95 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF95 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_134)
{
    // AF96;AF96;1101 116C 11BD;AF96;1101 116C 11BD;
    // (꾖; 꾖; 꾖; 꾖; 꾖; ) HANGUL SYLLABLE GGOEJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF96 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF96 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF96 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_135)
{
    // AF97;AF97;1101 116C 11BE;AF97;1101 116C 11BE;
    // (꾗; 꾗; 꾗; 꾗; 꾗; ) HANGUL SYLLABLE GGOEC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF97 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF97 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF97 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_136)
{
    // AF98;AF98;1101 116C 11BF;AF98;1101 116C 11BF;
    // (꾘; 꾘; 꾘; 꾘; 꾘; ) HANGUL SYLLABLE GGOEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF98 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF98 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF98 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_137)
{
    // AF99;AF99;1101 116C 11C0;AF99;1101 116C 11C0;
    // (꾙; 꾙; 꾙; 꾙; 꾙; ) HANGUL SYLLABLE GGOET
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF99 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF99 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF99 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_138)
{
    // AF9A;AF9A;1101 116C 11C1;AF9A;1101 116C 11C1;
    // (꾚; 꾚; 꾚; 꾚; 꾚; ) HANGUL SYLLABLE GGOEP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF9A }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF9A }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF9A }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_139)
{
    // AF9B;AF9B;1101 116C 11C2;AF9B;1101 116C 11C2;
    // (꾛; 꾛; 꾛; 꾛; 꾛; ) HANGUL SYLLABLE GGOEH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF9B }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF9B }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116C, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF9B }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116C, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_140)
{
    // AF9C;AF9C;1101 116D;AF9C;1101 116D;
    // (꾜; 꾜; 꾜; 꾜; 꾜; ) HANGUL SYLLABLE GGYO
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF9C }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF9C }};
        std::array<uint32_t, 2> const c3 = {{ 0x1101, 0x116D }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF9C }};
        std::array<uint32_t, 2> const c5 = {{ 0x1101, 0x116D }};

        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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_141)
{
    // AF9D;AF9D;1101 116D 11A8;AF9D;1101 116D 11A8;
    // (꾝; 꾝; 꾝; 꾝; 꾝; ) HANGUL SYLLABLE GGYOG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF9D }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF9D }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF9D }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_142)
{
    // AF9E;AF9E;1101 116D 11A9;AF9E;1101 116D 11A9;
    // (꾞; 꾞; 꾞; 꾞; 꾞; ) HANGUL SYLLABLE GGYOGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF9E }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF9E }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF9E }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_143)
{
    // AF9F;AF9F;1101 116D 11AA;AF9F;1101 116D 11AA;
    // (꾟; 꾟; 꾟; 꾟; 꾟; ) HANGUL SYLLABLE GGYOGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAF9F }};
        std::array<uint32_t, 1> const c2 = {{ 0xAF9F }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAF9F }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_144)
{
    // AFA0;AFA0;1101 116D 11AB;AFA0;1101 116D 11AB;
    // (꾠; 꾠; 꾠; 꾠; 꾠; ) HANGUL SYLLABLE GGYON
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_145)
{
    // AFA1;AFA1;1101 116D 11AC;AFA1;1101 116D 11AC;
    // (꾡; 꾡; 꾡; 꾡; 꾡; ) HANGUL SYLLABLE GGYONJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_146)
{
    // AFA2;AFA2;1101 116D 11AD;AFA2;1101 116D 11AD;
    // (꾢; 꾢; 꾢; 꾢; 꾢; ) HANGUL SYLLABLE GGYONH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_147)
{
    // AFA3;AFA3;1101 116D 11AE;AFA3;1101 116D 11AE;
    // (꾣; 꾣; 꾣; 꾣; 꾣; ) HANGUL SYLLABLE GGYOD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_148)
{
    // AFA4;AFA4;1101 116D 11AF;AFA4;1101 116D 11AF;
    // (꾤; 꾤; 꾤; 꾤; 꾤; ) HANGUL SYLLABLE GGYOL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_149)
{
    // AFA5;AFA5;1101 116D 11B0;AFA5;1101 116D 11B0;
    // (꾥; 꾥; 꾥; 꾥; 꾥; ) HANGUL SYLLABLE GGYOLG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_150)
{
    // AFA6;AFA6;1101 116D 11B1;AFA6;1101 116D 11B1;
    // (꾦; 꾦; 꾦; 꾦; 꾦; ) HANGUL SYLLABLE GGYOLM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_151)
{
    // AFA7;AFA7;1101 116D 11B2;AFA7;1101 116D 11B2;
    // (꾧; 꾧; 꾧; 꾧; 꾧; ) HANGUL SYLLABLE GGYOLB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_152)
{
    // AFA8;AFA8;1101 116D 11B3;AFA8;1101 116D 11B3;
    // (꾨; 꾨; 꾨; 꾨; 꾨; ) HANGUL SYLLABLE GGYOLS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_153)
{
    // AFA9;AFA9;1101 116D 11B4;AFA9;1101 116D 11B4;
    // (꾩; 꾩; 꾩; 꾩; 꾩; ) HANGUL SYLLABLE GGYOLT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFA9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFA9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFA9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_154)
{
    // AFAA;AFAA;1101 116D 11B5;AFAA;1101 116D 11B5;
    // (꾪; 꾪; 꾪; 꾪; 꾪; ) HANGUL SYLLABLE GGYOLP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFAA }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFAA }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFAA }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_155)
{
    // AFAB;AFAB;1101 116D 11B6;AFAB;1101 116D 11B6;
    // (꾫; 꾫; 꾫; 꾫; 꾫; ) HANGUL SYLLABLE GGYOLH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFAB }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFAB }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFAB }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_156)
{
    // AFAC;AFAC;1101 116D 11B7;AFAC;1101 116D 11B7;
    // (꾬; 꾬; 꾬; 꾬; 꾬; ) HANGUL SYLLABLE GGYOM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFAC }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFAC }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFAC }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_157)
{
    // AFAD;AFAD;1101 116D 11B8;AFAD;1101 116D 11B8;
    // (꾭; 꾭; 꾭; 꾭; 꾭; ) HANGUL SYLLABLE GGYOB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFAD }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFAD }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFAD }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_158)
{
    // AFAE;AFAE;1101 116D 11B9;AFAE;1101 116D 11B9;
    // (꾮; 꾮; 꾮; 꾮; 꾮; ) HANGUL SYLLABLE GGYOBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFAE }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFAE }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFAE }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_159)
{
    // AFAF;AFAF;1101 116D 11BA;AFAF;1101 116D 11BA;
    // (꾯; 꾯; 꾯; 꾯; 꾯; ) HANGUL SYLLABLE GGYOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFAF }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFAF }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFAF }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_160)
{
    // AFB0;AFB0;1101 116D 11BB;AFB0;1101 116D 11BB;
    // (꾰; 꾰; 꾰; 꾰; 꾰; ) HANGUL SYLLABLE GGYOSS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_161)
{
    // AFB1;AFB1;1101 116D 11BC;AFB1;1101 116D 11BC;
    // (꾱; 꾱; 꾱; 꾱; 꾱; ) HANGUL SYLLABLE GGYONG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_162)
{
    // AFB2;AFB2;1101 116D 11BD;AFB2;1101 116D 11BD;
    // (꾲; 꾲; 꾲; 꾲; 꾲; ) HANGUL SYLLABLE GGYOJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_163)
{
    // AFB3;AFB3;1101 116D 11BE;AFB3;1101 116D 11BE;
    // (꾳; 꾳; 꾳; 꾳; 꾳; ) HANGUL SYLLABLE GGYOC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_164)
{
    // AFB4;AFB4;1101 116D 11BF;AFB4;1101 116D 11BF;
    // (꾴; 꾴; 꾴; 꾴; 꾴; ) HANGUL SYLLABLE GGYOK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_165)
{
    // AFB5;AFB5;1101 116D 11C0;AFB5;1101 116D 11C0;
    // (꾵; 꾵; 꾵; 꾵; 꾵; ) HANGUL SYLLABLE GGYOT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_166)
{
    // AFB6;AFB6;1101 116D 11C1;AFB6;1101 116D 11C1;
    // (꾶; 꾶; 꾶; 꾶; 꾶; ) HANGUL SYLLABLE GGYOP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_167)
{
    // AFB7;AFB7;1101 116D 11C2;AFB7;1101 116D 11C2;
    // (꾷; 꾷; 꾷; 꾷; 꾷; ) HANGUL SYLLABLE GGYOH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116D, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116D, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_168)
{
    // AFB8;AFB8;1101 116E;AFB8;1101 116E;
    // (꾸; 꾸; 꾸; 꾸; 꾸; ) HANGUL SYLLABLE GGU
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB8 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1101, 0x116E }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB8 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1101, 0x116E }};

        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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_169)
{
    // AFB9;AFB9;1101 116E 11A8;AFB9;1101 116E 11A8;
    // (꾹; 꾹; 꾹; 꾹; 꾹; ) HANGUL SYLLABLE GGUG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFB9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFB9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFB9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_170)
{
    // AFBA;AFBA;1101 116E 11A9;AFBA;1101 116E 11A9;
    // (꾺; 꾺; 꾺; 꾺; 꾺; ) HANGUL SYLLABLE GGUGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFBA }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFBA }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFBA }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_171)
{
    // AFBB;AFBB;1101 116E 11AA;AFBB;1101 116E 11AA;
    // (꾻; 꾻; 꾻; 꾻; 꾻; ) HANGUL SYLLABLE GGUGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFBB }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFBB }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFBB }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_172)
{
    // AFBC;AFBC;1101 116E 11AB;AFBC;1101 116E 11AB;
    // (꾼; 꾼; 꾼; 꾼; 꾼; ) HANGUL SYLLABLE GGUN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFBC }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFBC }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFBC }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_173)
{
    // AFBD;AFBD;1101 116E 11AC;AFBD;1101 116E 11AC;
    // (꾽; 꾽; 꾽; 꾽; 꾽; ) HANGUL SYLLABLE GGUNJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFBD }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFBD }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFBD }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_174)
{
    // AFBE;AFBE;1101 116E 11AD;AFBE;1101 116E 11AD;
    // (꾾; 꾾; 꾾; 꾾; 꾾; ) HANGUL SYLLABLE GGUNH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFBE }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFBE }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFBE }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_175)
{
    // AFBF;AFBF;1101 116E 11AE;AFBF;1101 116E 11AE;
    // (꾿; 꾿; 꾿; 꾿; 꾿; ) HANGUL SYLLABLE GGUD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFBF }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFBF }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFBF }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_176)
{
    // AFC0;AFC0;1101 116E 11AF;AFC0;1101 116E 11AF;
    // (꿀; 꿀; 꿀; 꿀; 꿀; ) HANGUL SYLLABLE GGUL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_177)
{
    // AFC1;AFC1;1101 116E 11B0;AFC1;1101 116E 11B0;
    // (꿁; 꿁; 꿁; 꿁; 꿁; ) HANGUL SYLLABLE GGULG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_178)
{
    // AFC2;AFC2;1101 116E 11B1;AFC2;1101 116E 11B1;
    // (꿂; 꿂; 꿂; 꿂; 꿂; ) HANGUL SYLLABLE GGULM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_179)
{
    // AFC3;AFC3;1101 116E 11B2;AFC3;1101 116E 11B2;
    // (꿃; 꿃; 꿃; 꿃; 꿃; ) HANGUL SYLLABLE GGULB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_180)
{
    // AFC4;AFC4;1101 116E 11B3;AFC4;1101 116E 11B3;
    // (꿄; 꿄; 꿄; 꿄; 꿄; ) HANGUL SYLLABLE GGULS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_181)
{
    // AFC5;AFC5;1101 116E 11B4;AFC5;1101 116E 11B4;
    // (꿅; 꿅; 꿅; 꿅; 꿅; ) HANGUL SYLLABLE GGULT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_182)
{
    // AFC6;AFC6;1101 116E 11B5;AFC6;1101 116E 11B5;
    // (꿆; 꿆; 꿆; 꿆; 꿆; ) HANGUL SYLLABLE GGULP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_183)
{
    // AFC7;AFC7;1101 116E 11B6;AFC7;1101 116E 11B6;
    // (꿇; 꿇; 꿇; 꿇; 꿇; ) HANGUL SYLLABLE GGULH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_184)
{
    // AFC8;AFC8;1101 116E 11B7;AFC8;1101 116E 11B7;
    // (꿈; 꿈; 꿈; 꿈; 꿈; ) HANGUL SYLLABLE GGUM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_185)
{
    // AFC9;AFC9;1101 116E 11B8;AFC9;1101 116E 11B8;
    // (꿉; 꿉; 꿉; 꿉; 꿉; ) HANGUL SYLLABLE GGUB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFC9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFC9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFC9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_186)
{
    // AFCA;AFCA;1101 116E 11B9;AFCA;1101 116E 11B9;
    // (꿊; 꿊; 꿊; 꿊; 꿊; ) HANGUL SYLLABLE GGUBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFCA }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFCA }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFCA }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_187)
{
    // AFCB;AFCB;1101 116E 11BA;AFCB;1101 116E 11BA;
    // (꿋; 꿋; 꿋; 꿋; 꿋; ) HANGUL SYLLABLE GGUS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFCB }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFCB }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFCB }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_188)
{
    // AFCC;AFCC;1101 116E 11BB;AFCC;1101 116E 11BB;
    // (꿌; 꿌; 꿌; 꿌; 꿌; ) HANGUL SYLLABLE GGUSS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFCC }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFCC }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFCC }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_189)
{
    // AFCD;AFCD;1101 116E 11BC;AFCD;1101 116E 11BC;
    // (꿍; 꿍; 꿍; 꿍; 꿍; ) HANGUL SYLLABLE GGUNG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFCD }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFCD }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFCD }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_190)
{
    // AFCE;AFCE;1101 116E 11BD;AFCE;1101 116E 11BD;
    // (꿎; 꿎; 꿎; 꿎; 꿎; ) HANGUL SYLLABLE GGUJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFCE }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFCE }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFCE }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_191)
{
    // AFCF;AFCF;1101 116E 11BE;AFCF;1101 116E 11BE;
    // (꿏; 꿏; 꿏; 꿏; 꿏; ) HANGUL SYLLABLE GGUC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFCF }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFCF }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFCF }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_192)
{
    // AFD0;AFD0;1101 116E 11BF;AFD0;1101 116E 11BF;
    // (꿐; 꿐; 꿐; 꿐; 꿐; ) HANGUL SYLLABLE GGUK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFD0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFD0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFD0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_193)
{
    // AFD1;AFD1;1101 116E 11C0;AFD1;1101 116E 11C0;
    // (꿑; 꿑; 꿑; 꿑; 꿑; ) HANGUL SYLLABLE GGUT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFD1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFD1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFD1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_194)
{
    // AFD2;AFD2;1101 116E 11C1;AFD2;1101 116E 11C1;
    // (꿒; 꿒; 꿒; 꿒; 꿒; ) HANGUL SYLLABLE GGUP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFD2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFD2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFD2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_195)
{
    // AFD3;AFD3;1101 116E 11C2;AFD3;1101 116E 11C2;
    // (꿓; 꿓; 꿓; 꿓; 꿓; ) HANGUL SYLLABLE GGUH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFD3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFD3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116E, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFD3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116E, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_196)
{
    // AFD4;AFD4;1101 116F;AFD4;1101 116F;
    // (꿔; 꿔; 꿔; 꿔; 꿔; ) HANGUL SYLLABLE GGWEO
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFD4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFD4 }};
        std::array<uint32_t, 2> const c3 = {{ 0x1101, 0x116F }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFD4 }};
        std::array<uint32_t, 2> const c5 = {{ 0x1101, 0x116F }};

        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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_197)
{
    // AFD5;AFD5;1101 116F 11A8;AFD5;1101 116F 11A8;
    // (꿕; 꿕; 꿕; 꿕; 꿕; ) HANGUL SYLLABLE GGWEOG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFD5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFD5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116F, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFD5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116F, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_198)
{
    // AFD6;AFD6;1101 116F 11A9;AFD6;1101 116F 11A9;
    // (꿖; 꿖; 꿖; 꿖; 꿖; ) HANGUL SYLLABLE GGWEOGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFD6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFD6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116F, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFD6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116F, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

TEST(normalization, nfkc_016_199)
{
    // AFD7;AFD7;1101 116F 11AA;AFD7;1101 116F 11AA;
    // (꿗; 꿗; 꿗; 꿗; 꿗; ) HANGUL SYLLABLE GGWEOGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xAFD7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xAFD7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x1101, 0x116F, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xAFD7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x1101, 0x116F, 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_nfkc(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

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

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

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

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

    }
}

max_stars_repo_name: eightysquirrels/text

max_issues_repo_name: eightysquirrels/text

max_forks_repo_name: eightysquirrels/text