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

#include <gtest/gtest.h>

#include <algorithm>

TEST(normalization, nfc_044_000)
{
    // C4F0;C4F0;110A 1173;C4F0;110A 1173;
    // (쓰; 쓰; 쓰; 쓰; 쓰; ) HANGUL SYLLABLE SSEU
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F0 }};
        std::array<uint32_t, 2> const c3 = {{ 0x110A, 0x1173 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F0 }};
        std::array<uint32_t, 2> const c5 = {{ 0x110A, 0x1173 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_001)
{
    // C4F1;C4F1;110A 1173 11A8;C4F1;110A 1173 11A8;
    // (쓱; 쓱; 쓱; 쓱; 쓱; ) HANGUL SYLLABLE SSEUG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_002)
{
    // C4F2;C4F2;110A 1173 11A9;C4F2;110A 1173 11A9;
    // (쓲; 쓲; 쓲; 쓲; 쓲; ) HANGUL SYLLABLE SSEUGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_003)
{
    // C4F3;C4F3;110A 1173 11AA;C4F3;110A 1173 11AA;
    // (쓳; 쓳; 쓳; 쓳; 쓳; ) HANGUL SYLLABLE SSEUGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_004)
{
    // C4F4;C4F4;110A 1173 11AB;C4F4;110A 1173 11AB;
    // (쓴; 쓴; 쓴; 쓴; 쓴; ) HANGUL SYLLABLE SSEUN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_005)
{
    // C4F5;C4F5;110A 1173 11AC;C4F5;110A 1173 11AC;
    // (쓵; 쓵; 쓵; 쓵; 쓵; ) HANGUL SYLLABLE SSEUNJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_006)
{
    // C4F6;C4F6;110A 1173 11AD;C4F6;110A 1173 11AD;
    // (쓶; 쓶; 쓶; 쓶; 쓶; ) HANGUL SYLLABLE SSEUNH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_007)
{
    // C4F7;C4F7;110A 1173 11AE;C4F7;110A 1173 11AE;
    // (쓷; 쓷; 쓷; 쓷; 쓷; ) HANGUL SYLLABLE SSEUD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_008)
{
    // C4F8;C4F8;110A 1173 11AF;C4F8;110A 1173 11AF;
    // (쓸; 쓸; 쓸; 쓸; 쓸; ) HANGUL SYLLABLE SSEUL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_009)
{
    // C4F9;C4F9;110A 1173 11B0;C4F9;110A 1173 11B0;
    // (쓹; 쓹; 쓹; 쓹; 쓹; ) HANGUL SYLLABLE SSEULG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4F9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4F9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4F9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_010)
{
    // C4FA;C4FA;110A 1173 11B1;C4FA;110A 1173 11B1;
    // (쓺; 쓺; 쓺; 쓺; 쓺; ) HANGUL SYLLABLE SSEULM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4FA }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4FA }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4FA }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_011)
{
    // C4FB;C4FB;110A 1173 11B2;C4FB;110A 1173 11B2;
    // (쓻; 쓻; 쓻; 쓻; 쓻; ) HANGUL SYLLABLE SSEULB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4FB }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4FB }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4FB }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_012)
{
    // C4FC;C4FC;110A 1173 11B3;C4FC;110A 1173 11B3;
    // (쓼; 쓼; 쓼; 쓼; 쓼; ) HANGUL SYLLABLE SSEULS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4FC }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4FC }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4FC }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_013)
{
    // C4FD;C4FD;110A 1173 11B4;C4FD;110A 1173 11B4;
    // (쓽; 쓽; 쓽; 쓽; 쓽; ) HANGUL SYLLABLE SSEULT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4FD }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4FD }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4FD }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_014)
{
    // C4FE;C4FE;110A 1173 11B5;C4FE;110A 1173 11B5;
    // (쓾; 쓾; 쓾; 쓾; 쓾; ) HANGUL SYLLABLE SSEULP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4FE }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4FE }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4FE }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_015)
{
    // C4FF;C4FF;110A 1173 11B6;C4FF;110A 1173 11B6;
    // (쓿; 쓿; 쓿; 쓿; 쓿; ) HANGUL SYLLABLE SSEULH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC4FF }};
        std::array<uint32_t, 1> const c2 = {{ 0xC4FF }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC4FF }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_016)
{
    // C500;C500;110A 1173 11B7;C500;110A 1173 11B7;
    // (씀; 씀; 씀; 씀; 씀; ) HANGUL SYLLABLE SSEUM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC500 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC500 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC500 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_017)
{
    // C501;C501;110A 1173 11B8;C501;110A 1173 11B8;
    // (씁; 씁; 씁; 씁; 씁; ) HANGUL SYLLABLE SSEUB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC501 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC501 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC501 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_018)
{
    // C502;C502;110A 1173 11B9;C502;110A 1173 11B9;
    // (씂; 씂; 씂; 씂; 씂; ) HANGUL SYLLABLE SSEUBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC502 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC502 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC502 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_019)
{
    // C503;C503;110A 1173 11BA;C503;110A 1173 11BA;
    // (씃; 씃; 씃; 씃; 씃; ) HANGUL SYLLABLE SSEUS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC503 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC503 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC503 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_020)
{
    // C504;C504;110A 1173 11BB;C504;110A 1173 11BB;
    // (씄; 씄; 씄; 씄; 씄; ) HANGUL SYLLABLE SSEUSS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC504 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC504 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC504 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_021)
{
    // C505;C505;110A 1173 11BC;C505;110A 1173 11BC;
    // (씅; 씅; 씅; 씅; 씅; ) HANGUL SYLLABLE SSEUNG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC505 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC505 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC505 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_022)
{
    // C506;C506;110A 1173 11BD;C506;110A 1173 11BD;
    // (씆; 씆; 씆; 씆; 씆; ) HANGUL SYLLABLE SSEUJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC506 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC506 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC506 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_023)
{
    // C507;C507;110A 1173 11BE;C507;110A 1173 11BE;
    // (씇; 씇; 씇; 씇; 씇; ) HANGUL SYLLABLE SSEUC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC507 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC507 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC507 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_024)
{
    // C508;C508;110A 1173 11BF;C508;110A 1173 11BF;
    // (씈; 씈; 씈; 씈; 씈; ) HANGUL SYLLABLE SSEUK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC508 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC508 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC508 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_025)
{
    // C509;C509;110A 1173 11C0;C509;110A 1173 11C0;
    // (씉; 씉; 씉; 씉; 씉; ) HANGUL SYLLABLE SSEUT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC509 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC509 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC509 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_026)
{
    // C50A;C50A;110A 1173 11C1;C50A;110A 1173 11C1;
    // (씊; 씊; 씊; 씊; 씊; ) HANGUL SYLLABLE SSEUP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC50A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC50A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC50A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_027)
{
    // C50B;C50B;110A 1173 11C2;C50B;110A 1173 11C2;
    // (씋; 씋; 씋; 씋; 씋; ) HANGUL SYLLABLE SSEUH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC50B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC50B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1173, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC50B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1173, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_028)
{
    // C50C;C50C;110A 1174;C50C;110A 1174;
    // (씌; 씌; 씌; 씌; 씌; ) HANGUL SYLLABLE SSYI
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC50C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC50C }};
        std::array<uint32_t, 2> const c3 = {{ 0x110A, 0x1174 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC50C }};
        std::array<uint32_t, 2> const c5 = {{ 0x110A, 0x1174 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_029)
{
    // C50D;C50D;110A 1174 11A8;C50D;110A 1174 11A8;
    // (씍; 씍; 씍; 씍; 씍; ) HANGUL SYLLABLE SSYIG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC50D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC50D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC50D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_030)
{
    // C50E;C50E;110A 1174 11A9;C50E;110A 1174 11A9;
    // (씎; 씎; 씎; 씎; 씎; ) HANGUL SYLLABLE SSYIGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC50E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC50E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC50E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_031)
{
    // C50F;C50F;110A 1174 11AA;C50F;110A 1174 11AA;
    // (씏; 씏; 씏; 씏; 씏; ) HANGUL SYLLABLE SSYIGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC50F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC50F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC50F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_032)
{
    // C510;C510;110A 1174 11AB;C510;110A 1174 11AB;
    // (씐; 씐; 씐; 씐; 씐; ) HANGUL SYLLABLE SSYIN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC510 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC510 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC510 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_033)
{
    // C511;C511;110A 1174 11AC;C511;110A 1174 11AC;
    // (씑; 씑; 씑; 씑; 씑; ) HANGUL SYLLABLE SSYINJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC511 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC511 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC511 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_034)
{
    // C512;C512;110A 1174 11AD;C512;110A 1174 11AD;
    // (씒; 씒; 씒; 씒; 씒; ) HANGUL SYLLABLE SSYINH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC512 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC512 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC512 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_035)
{
    // C513;C513;110A 1174 11AE;C513;110A 1174 11AE;
    // (씓; 씓; 씓; 씓; 씓; ) HANGUL SYLLABLE SSYID
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC513 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC513 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC513 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_036)
{
    // C514;C514;110A 1174 11AF;C514;110A 1174 11AF;
    // (씔; 씔; 씔; 씔; 씔; ) HANGUL SYLLABLE SSYIL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC514 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC514 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC514 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_037)
{
    // C515;C515;110A 1174 11B0;C515;110A 1174 11B0;
    // (씕; 씕; 씕; 씕; 씕; ) HANGUL SYLLABLE SSYILG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC515 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC515 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC515 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_038)
{
    // C516;C516;110A 1174 11B1;C516;110A 1174 11B1;
    // (씖; 씖; 씖; 씖; 씖; ) HANGUL SYLLABLE SSYILM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC516 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC516 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC516 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_039)
{
    // C517;C517;110A 1174 11B2;C517;110A 1174 11B2;
    // (씗; 씗; 씗; 씗; 씗; ) HANGUL SYLLABLE SSYILB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC517 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC517 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC517 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_040)
{
    // C518;C518;110A 1174 11B3;C518;110A 1174 11B3;
    // (씘; 씘; 씘; 씘; 씘; ) HANGUL SYLLABLE SSYILS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC518 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC518 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC518 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_041)
{
    // C519;C519;110A 1174 11B4;C519;110A 1174 11B4;
    // (씙; 씙; 씙; 씙; 씙; ) HANGUL SYLLABLE SSYILT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC519 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC519 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC519 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_042)
{
    // C51A;C51A;110A 1174 11B5;C51A;110A 1174 11B5;
    // (씚; 씚; 씚; 씚; 씚; ) HANGUL SYLLABLE SSYILP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC51A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC51A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC51A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_043)
{
    // C51B;C51B;110A 1174 11B6;C51B;110A 1174 11B6;
    // (씛; 씛; 씛; 씛; 씛; ) HANGUL SYLLABLE SSYILH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC51B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC51B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC51B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_044)
{
    // C51C;C51C;110A 1174 11B7;C51C;110A 1174 11B7;
    // (씜; 씜; 씜; 씜; 씜; ) HANGUL SYLLABLE SSYIM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC51C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC51C }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC51C }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_045)
{
    // C51D;C51D;110A 1174 11B8;C51D;110A 1174 11B8;
    // (씝; 씝; 씝; 씝; 씝; ) HANGUL SYLLABLE SSYIB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC51D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC51D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC51D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_046)
{
    // C51E;C51E;110A 1174 11B9;C51E;110A 1174 11B9;
    // (씞; 씞; 씞; 씞; 씞; ) HANGUL SYLLABLE SSYIBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC51E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC51E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC51E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_047)
{
    // C51F;C51F;110A 1174 11BA;C51F;110A 1174 11BA;
    // (씟; 씟; 씟; 씟; 씟; ) HANGUL SYLLABLE SSYIS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC51F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC51F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC51F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_048)
{
    // C520;C520;110A 1174 11BB;C520;110A 1174 11BB;
    // (씠; 씠; 씠; 씠; 씠; ) HANGUL SYLLABLE SSYISS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC520 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC520 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC520 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_049)
{
    // C521;C521;110A 1174 11BC;C521;110A 1174 11BC;
    // (씡; 씡; 씡; 씡; 씡; ) HANGUL SYLLABLE SSYING
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC521 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC521 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC521 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_050)
{
    // C522;C522;110A 1174 11BD;C522;110A 1174 11BD;
    // (씢; 씢; 씢; 씢; 씢; ) HANGUL SYLLABLE SSYIJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC522 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC522 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC522 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_051)
{
    // C523;C523;110A 1174 11BE;C523;110A 1174 11BE;
    // (씣; 씣; 씣; 씣; 씣; ) HANGUL SYLLABLE SSYIC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC523 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC523 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC523 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_052)
{
    // C524;C524;110A 1174 11BF;C524;110A 1174 11BF;
    // (씤; 씤; 씤; 씤; 씤; ) HANGUL SYLLABLE SSYIK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC524 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC524 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC524 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_053)
{
    // C525;C525;110A 1174 11C0;C525;110A 1174 11C0;
    // (씥; 씥; 씥; 씥; 씥; ) HANGUL SYLLABLE SSYIT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC525 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC525 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC525 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_054)
{
    // C526;C526;110A 1174 11C1;C526;110A 1174 11C1;
    // (씦; 씦; 씦; 씦; 씦; ) HANGUL SYLLABLE SSYIP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC526 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC526 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC526 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_055)
{
    // C527;C527;110A 1174 11C2;C527;110A 1174 11C2;
    // (씧; 씧; 씧; 씧; 씧; ) HANGUL SYLLABLE SSYIH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC527 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC527 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1174, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC527 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1174, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_056)
{
    // C528;C528;110A 1175;C528;110A 1175;
    // (씨; 씨; 씨; 씨; 씨; ) HANGUL SYLLABLE SSI
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC528 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC528 }};
        std::array<uint32_t, 2> const c3 = {{ 0x110A, 0x1175 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC528 }};
        std::array<uint32_t, 2> const c5 = {{ 0x110A, 0x1175 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_057)
{
    // C529;C529;110A 1175 11A8;C529;110A 1175 11A8;
    // (씩; 씩; 씩; 씩; 씩; ) HANGUL SYLLABLE SSIG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC529 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC529 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC529 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_058)
{
    // C52A;C52A;110A 1175 11A9;C52A;110A 1175 11A9;
    // (씪; 씪; 씪; 씪; 씪; ) HANGUL SYLLABLE SSIGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC52A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC52A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC52A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_059)
{
    // C52B;C52B;110A 1175 11AA;C52B;110A 1175 11AA;
    // (씫; 씫; 씫; 씫; 씫; ) HANGUL SYLLABLE SSIGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC52B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC52B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC52B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_060)
{
    // C52C;C52C;110A 1175 11AB;C52C;110A 1175 11AB;
    // (씬; 씬; 씬; 씬; 씬; ) HANGUL SYLLABLE SSIN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC52C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC52C }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC52C }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_061)
{
    // C52D;C52D;110A 1175 11AC;C52D;110A 1175 11AC;
    // (씭; 씭; 씭; 씭; 씭; ) HANGUL SYLLABLE SSINJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC52D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC52D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC52D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_062)
{
    // C52E;C52E;110A 1175 11AD;C52E;110A 1175 11AD;
    // (씮; 씮; 씮; 씮; 씮; ) HANGUL SYLLABLE SSINH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC52E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC52E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC52E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_063)
{
    // C52F;C52F;110A 1175 11AE;C52F;110A 1175 11AE;
    // (씯; 씯; 씯; 씯; 씯; ) HANGUL SYLLABLE SSID
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC52F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC52F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC52F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_064)
{
    // C530;C530;110A 1175 11AF;C530;110A 1175 11AF;
    // (씰; 씰; 씰; 씰; 씰; ) HANGUL SYLLABLE SSIL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC530 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC530 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC530 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_065)
{
    // C531;C531;110A 1175 11B0;C531;110A 1175 11B0;
    // (씱; 씱; 씱; 씱; 씱; ) HANGUL SYLLABLE SSILG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC531 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC531 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC531 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_066)
{
    // C532;C532;110A 1175 11B1;C532;110A 1175 11B1;
    // (씲; 씲; 씲; 씲; 씲; ) HANGUL SYLLABLE SSILM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC532 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC532 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC532 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_067)
{
    // C533;C533;110A 1175 11B2;C533;110A 1175 11B2;
    // (씳; 씳; 씳; 씳; 씳; ) HANGUL SYLLABLE SSILB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC533 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC533 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC533 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_068)
{
    // C534;C534;110A 1175 11B3;C534;110A 1175 11B3;
    // (씴; 씴; 씴; 씴; 씴; ) HANGUL SYLLABLE SSILS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC534 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC534 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC534 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_069)
{
    // C535;C535;110A 1175 11B4;C535;110A 1175 11B4;
    // (씵; 씵; 씵; 씵; 씵; ) HANGUL SYLLABLE SSILT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC535 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC535 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC535 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_070)
{
    // C536;C536;110A 1175 11B5;C536;110A 1175 11B5;
    // (씶; 씶; 씶; 씶; 씶; ) HANGUL SYLLABLE SSILP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC536 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC536 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC536 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_071)
{
    // C537;C537;110A 1175 11B6;C537;110A 1175 11B6;
    // (씷; 씷; 씷; 씷; 씷; ) HANGUL SYLLABLE SSILH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC537 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC537 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC537 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_072)
{
    // C538;C538;110A 1175 11B7;C538;110A 1175 11B7;
    // (씸; 씸; 씸; 씸; 씸; ) HANGUL SYLLABLE SSIM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC538 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC538 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC538 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_073)
{
    // C539;C539;110A 1175 11B8;C539;110A 1175 11B8;
    // (씹; 씹; 씹; 씹; 씹; ) HANGUL SYLLABLE SSIB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC539 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC539 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC539 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_074)
{
    // C53A;C53A;110A 1175 11B9;C53A;110A 1175 11B9;
    // (씺; 씺; 씺; 씺; 씺; ) HANGUL SYLLABLE SSIBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC53A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC53A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC53A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_075)
{
    // C53B;C53B;110A 1175 11BA;C53B;110A 1175 11BA;
    // (씻; 씻; 씻; 씻; 씻; ) HANGUL SYLLABLE SSIS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC53B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC53B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC53B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_076)
{
    // C53C;C53C;110A 1175 11BB;C53C;110A 1175 11BB;
    // (씼; 씼; 씼; 씼; 씼; ) HANGUL SYLLABLE SSISS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC53C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC53C }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC53C }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_077)
{
    // C53D;C53D;110A 1175 11BC;C53D;110A 1175 11BC;
    // (씽; 씽; 씽; 씽; 씽; ) HANGUL SYLLABLE SSING
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC53D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC53D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC53D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_078)
{
    // C53E;C53E;110A 1175 11BD;C53E;110A 1175 11BD;
    // (씾; 씾; 씾; 씾; 씾; ) HANGUL SYLLABLE SSIJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC53E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC53E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC53E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_079)
{
    // C53F;C53F;110A 1175 11BE;C53F;110A 1175 11BE;
    // (씿; 씿; 씿; 씿; 씿; ) HANGUL SYLLABLE SSIC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC53F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC53F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC53F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_080)
{
    // C540;C540;110A 1175 11BF;C540;110A 1175 11BF;
    // (앀; 앀; 앀; 앀; 앀; ) HANGUL SYLLABLE SSIK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC540 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC540 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC540 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_081)
{
    // C541;C541;110A 1175 11C0;C541;110A 1175 11C0;
    // (앁; 앁; 앁; 앁; 앁; ) HANGUL SYLLABLE SSIT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC541 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC541 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC541 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_082)
{
    // C542;C542;110A 1175 11C1;C542;110A 1175 11C1;
    // (앂; 앂; 앂; 앂; 앂; ) HANGUL SYLLABLE SSIP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC542 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC542 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC542 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_083)
{
    // C543;C543;110A 1175 11C2;C543;110A 1175 11C2;
    // (앃; 앃; 앃; 앃; 앃; ) HANGUL SYLLABLE SSIH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC543 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC543 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110A, 0x1175, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC543 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110A, 0x1175, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_084)
{
    // C544;C544;110B 1161;C544;110B 1161;
    // (아; 아; 아; 아; 아; ) HANGUL SYLLABLE A
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC544 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC544 }};
        std::array<uint32_t, 2> const c3 = {{ 0x110B, 0x1161 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC544 }};
        std::array<uint32_t, 2> const c5 = {{ 0x110B, 0x1161 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_085)
{
    // C545;C545;110B 1161 11A8;C545;110B 1161 11A8;
    // (악; 악; 악; 악; 악; ) HANGUL SYLLABLE AG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC545 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC545 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC545 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_086)
{
    // C546;C546;110B 1161 11A9;C546;110B 1161 11A9;
    // (앆; 앆; 앆; 앆; 앆; ) HANGUL SYLLABLE AGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC546 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC546 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC546 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_087)
{
    // C547;C547;110B 1161 11AA;C547;110B 1161 11AA;
    // (앇; 앇; 앇; 앇; 앇; ) HANGUL SYLLABLE AGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC547 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC547 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC547 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_088)
{
    // C548;C548;110B 1161 11AB;C548;110B 1161 11AB;
    // (안; 안; 안; 안; 안; ) HANGUL SYLLABLE AN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC548 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC548 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC548 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_089)
{
    // C549;C549;110B 1161 11AC;C549;110B 1161 11AC;
    // (앉; 앉; 앉; 앉; 앉; ) HANGUL SYLLABLE ANJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC549 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC549 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC549 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_090)
{
    // C54A;C54A;110B 1161 11AD;C54A;110B 1161 11AD;
    // (않; 않; 않; 않; 않; ) HANGUL SYLLABLE ANH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC54A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC54A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC54A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_091)
{
    // C54B;C54B;110B 1161 11AE;C54B;110B 1161 11AE;
    // (앋; 앋; 앋; 앋; 앋; ) HANGUL SYLLABLE AD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC54B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC54B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC54B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_092)
{
    // C54C;C54C;110B 1161 11AF;C54C;110B 1161 11AF;
    // (알; 알; 알; 알; 알; ) HANGUL SYLLABLE AL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC54C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC54C }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC54C }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_093)
{
    // C54D;C54D;110B 1161 11B0;C54D;110B 1161 11B0;
    // (앍; 앍; 앍; 앍; 앍; ) HANGUL SYLLABLE ALG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC54D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC54D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC54D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_094)
{
    // C54E;C54E;110B 1161 11B1;C54E;110B 1161 11B1;
    // (앎; 앎; 앎; 앎; 앎; ) HANGUL SYLLABLE ALM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC54E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC54E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC54E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_095)
{
    // C54F;C54F;110B 1161 11B2;C54F;110B 1161 11B2;
    // (앏; 앏; 앏; 앏; 앏; ) HANGUL SYLLABLE ALB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC54F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC54F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC54F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_096)
{
    // C550;C550;110B 1161 11B3;C550;110B 1161 11B3;
    // (앐; 앐; 앐; 앐; 앐; ) HANGUL SYLLABLE ALS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC550 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC550 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC550 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_097)
{
    // C551;C551;110B 1161 11B4;C551;110B 1161 11B4;
    // (앑; 앑; 앑; 앑; 앑; ) HANGUL SYLLABLE ALT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC551 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC551 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC551 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_098)
{
    // C552;C552;110B 1161 11B5;C552;110B 1161 11B5;
    // (앒; 앒; 앒; 앒; 앒; ) HANGUL SYLLABLE ALP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC552 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC552 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC552 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_099)
{
    // C553;C553;110B 1161 11B6;C553;110B 1161 11B6;
    // (앓; 앓; 앓; 앓; 앓; ) HANGUL SYLLABLE ALH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC553 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC553 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC553 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_100)
{
    // C554;C554;110B 1161 11B7;C554;110B 1161 11B7;
    // (암; 암; 암; 암; 암; ) HANGUL SYLLABLE AM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC554 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC554 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC554 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_101)
{
    // C555;C555;110B 1161 11B8;C555;110B 1161 11B8;
    // (압; 압; 압; 압; 압; ) HANGUL SYLLABLE AB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC555 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC555 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC555 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_102)
{
    // C556;C556;110B 1161 11B9;C556;110B 1161 11B9;
    // (앖; 앖; 앖; 앖; 앖; ) HANGUL SYLLABLE ABS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC556 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC556 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC556 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_103)
{
    // C557;C557;110B 1161 11BA;C557;110B 1161 11BA;
    // (앗; 앗; 앗; 앗; 앗; ) HANGUL SYLLABLE AS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC557 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC557 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC557 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_104)
{
    // C558;C558;110B 1161 11BB;C558;110B 1161 11BB;
    // (았; 았; 았; 았; 았; ) HANGUL SYLLABLE ASS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC558 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC558 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC558 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_105)
{
    // C559;C559;110B 1161 11BC;C559;110B 1161 11BC;
    // (앙; 앙; 앙; 앙; 앙; ) HANGUL SYLLABLE ANG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC559 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC559 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC559 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_106)
{
    // C55A;C55A;110B 1161 11BD;C55A;110B 1161 11BD;
    // (앚; 앚; 앚; 앚; 앚; ) HANGUL SYLLABLE AJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC55A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC55A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC55A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_107)
{
    // C55B;C55B;110B 1161 11BE;C55B;110B 1161 11BE;
    // (앛; 앛; 앛; 앛; 앛; ) HANGUL SYLLABLE AC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC55B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC55B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC55B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_108)
{
    // C55C;C55C;110B 1161 11BF;C55C;110B 1161 11BF;
    // (앜; 앜; 앜; 앜; 앜; ) HANGUL SYLLABLE AK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC55C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC55C }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC55C }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_109)
{
    // C55D;C55D;110B 1161 11C0;C55D;110B 1161 11C0;
    // (앝; 앝; 앝; 앝; 앝; ) HANGUL SYLLABLE AT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC55D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC55D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC55D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_110)
{
    // C55E;C55E;110B 1161 11C1;C55E;110B 1161 11C1;
    // (앞; 앞; 앞; 앞; 앞; ) HANGUL SYLLABLE AP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC55E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC55E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC55E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_111)
{
    // C55F;C55F;110B 1161 11C2;C55F;110B 1161 11C2;
    // (앟; 앟; 앟; 앟; 앟; ) HANGUL SYLLABLE AH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC55F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC55F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1161, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC55F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1161, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_112)
{
    // C560;C560;110B 1162;C560;110B 1162;
    // (애; 애; 애; 애; 애; ) HANGUL SYLLABLE AE
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC560 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC560 }};
        std::array<uint32_t, 2> const c3 = {{ 0x110B, 0x1162 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC560 }};
        std::array<uint32_t, 2> const c5 = {{ 0x110B, 0x1162 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_113)
{
    // C561;C561;110B 1162 11A8;C561;110B 1162 11A8;
    // (액; 액; 액; 액; 액; ) HANGUL SYLLABLE AEG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC561 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC561 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC561 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_114)
{
    // C562;C562;110B 1162 11A9;C562;110B 1162 11A9;
    // (앢; 앢; 앢; 앢; 앢; ) HANGUL SYLLABLE AEGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC562 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC562 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC562 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_115)
{
    // C563;C563;110B 1162 11AA;C563;110B 1162 11AA;
    // (앣; 앣; 앣; 앣; 앣; ) HANGUL SYLLABLE AEGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC563 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC563 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC563 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 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_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_116)
{
    // C564;C564;110B 1162 11AB;C564;110B 1162 11AB;
    // (앤; 앤; 앤; 앤; 앤; ) HANGUL SYLLABLE AEN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC564 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC564 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC564 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11AB }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_117)
{
    // C565;C565;110B 1162 11AC;C565;110B 1162 11AC;
    // (앥; 앥; 앥; 앥; 앥; ) HANGUL SYLLABLE AENJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC565 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC565 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC565 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11AC }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_118)
{
    // C566;C566;110B 1162 11AD;C566;110B 1162 11AD;
    // (앦; 앦; 앦; 앦; 앦; ) HANGUL SYLLABLE AENH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC566 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC566 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC566 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11AD }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_119)
{
    // C567;C567;110B 1162 11AE;C567;110B 1162 11AE;
    // (앧; 앧; 앧; 앧; 앧; ) HANGUL SYLLABLE AED
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC567 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC567 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC567 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11AE }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_120)
{
    // C568;C568;110B 1162 11AF;C568;110B 1162 11AF;
    // (앨; 앨; 앨; 앨; 앨; ) HANGUL SYLLABLE AEL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC568 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC568 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC568 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11AF }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_121)
{
    // C569;C569;110B 1162 11B0;C569;110B 1162 11B0;
    // (앩; 앩; 앩; 앩; 앩; ) HANGUL SYLLABLE AELG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC569 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC569 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC569 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B0 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_122)
{
    // C56A;C56A;110B 1162 11B1;C56A;110B 1162 11B1;
    // (앪; 앪; 앪; 앪; 앪; ) HANGUL SYLLABLE AELM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC56A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC56A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC56A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B1 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_123)
{
    // C56B;C56B;110B 1162 11B2;C56B;110B 1162 11B2;
    // (앫; 앫; 앫; 앫; 앫; ) HANGUL SYLLABLE AELB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC56B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC56B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC56B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B2 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_124)
{
    // C56C;C56C;110B 1162 11B3;C56C;110B 1162 11B3;
    // (앬; 앬; 앬; 앬; 앬; ) HANGUL SYLLABLE AELS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC56C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC56C }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC56C }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B3 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_125)
{
    // C56D;C56D;110B 1162 11B4;C56D;110B 1162 11B4;
    // (앭; 앭; 앭; 앭; 앭; ) HANGUL SYLLABLE AELT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC56D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC56D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC56D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B4 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_126)
{
    // C56E;C56E;110B 1162 11B5;C56E;110B 1162 11B5;
    // (앮; 앮; 앮; 앮; 앮; ) HANGUL SYLLABLE AELP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC56E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC56E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC56E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B5 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_127)
{
    // C56F;C56F;110B 1162 11B6;C56F;110B 1162 11B6;
    // (앯; 앯; 앯; 앯; 앯; ) HANGUL SYLLABLE AELH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC56F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC56F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC56F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B6 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_128)
{
    // C570;C570;110B 1162 11B7;C570;110B 1162 11B7;
    // (앰; 앰; 앰; 앰; 앰; ) HANGUL SYLLABLE AEM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC570 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC570 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC570 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B7 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_129)
{
    // C571;C571;110B 1162 11B8;C571;110B 1162 11B8;
    // (앱; 앱; 앱; 앱; 앱; ) HANGUL SYLLABLE AEB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC571 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC571 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC571 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B8 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_130)
{
    // C572;C572;110B 1162 11B9;C572;110B 1162 11B9;
    // (앲; 앲; 앲; 앲; 앲; ) HANGUL SYLLABLE AEBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC572 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC572 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC572 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11B9 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_131)
{
    // C573;C573;110B 1162 11BA;C573;110B 1162 11BA;
    // (앳; 앳; 앳; 앳; 앳; ) HANGUL SYLLABLE AES
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC573 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC573 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC573 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11BA }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_132)
{
    // C574;C574;110B 1162 11BB;C574;110B 1162 11BB;
    // (앴; 앴; 앴; 앴; 앴; ) HANGUL SYLLABLE AESS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC574 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC574 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC574 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11BB }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_133)
{
    // C575;C575;110B 1162 11BC;C575;110B 1162 11BC;
    // (앵; 앵; 앵; 앵; 앵; ) HANGUL SYLLABLE AENG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC575 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC575 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC575 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11BC }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_134)
{
    // C576;C576;110B 1162 11BD;C576;110B 1162 11BD;
    // (앶; 앶; 앶; 앶; 앶; ) HANGUL SYLLABLE AEJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC576 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC576 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC576 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11BD }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_135)
{
    // C577;C577;110B 1162 11BE;C577;110B 1162 11BE;
    // (앷; 앷; 앷; 앷; 앷; ) HANGUL SYLLABLE AEC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC577 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC577 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC577 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11BE }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_136)
{
    // C578;C578;110B 1162 11BF;C578;110B 1162 11BF;
    // (앸; 앸; 앸; 앸; 앸; ) HANGUL SYLLABLE AEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC578 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC578 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC578 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11BF }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_137)
{
    // C579;C579;110B 1162 11C0;C579;110B 1162 11C0;
    // (앹; 앹; 앹; 앹; 앹; ) HANGUL SYLLABLE AET
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC579 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC579 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC579 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11C0 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_138)
{
    // C57A;C57A;110B 1162 11C1;C57A;110B 1162 11C1;
    // (앺; 앺; 앺; 앺; 앺; ) HANGUL SYLLABLE AEP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC57A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC57A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC57A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11C1 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_139)
{
    // C57B;C57B;110B 1162 11C2;C57B;110B 1162 11C2;
    // (앻; 앻; 앻; 앻; 앻; ) HANGUL SYLLABLE AEH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC57B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC57B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1162, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC57B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1162, 0x11C2 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_140)
{
    // C57C;C57C;110B 1163;C57C;110B 1163;
    // (야; 야; 야; 야; 야; ) HANGUL SYLLABLE YA
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC57C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC57C }};
        std::array<uint32_t, 2> const c3 = {{ 0x110B, 0x1163 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC57C }};
        std::array<uint32_t, 2> const c5 = {{ 0x110B, 0x1163 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_141)
{
    // C57D;C57D;110B 1163 11A8;C57D;110B 1163 11A8;
    // (약; 약; 약; 약; 약; ) HANGUL SYLLABLE YAG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC57D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC57D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC57D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11A8 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_142)
{
    // C57E;C57E;110B 1163 11A9;C57E;110B 1163 11A9;
    // (앾; 앾; 앾; 앾; 앾; ) HANGUL SYLLABLE YAGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC57E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC57E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC57E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11A9 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_143)
{
    // C57F;C57F;110B 1163 11AA;C57F;110B 1163 11AA;
    // (앿; 앿; 앿; 앿; 앿; ) HANGUL SYLLABLE YAGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC57F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC57F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC57F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11AA }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_144)
{
    // C580;C580;110B 1163 11AB;C580;110B 1163 11AB;
    // (얀; 얀; 얀; 얀; 얀; ) HANGUL SYLLABLE YAN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC580 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC580 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC580 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11AB }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_145)
{
    // C581;C581;110B 1163 11AC;C581;110B 1163 11AC;
    // (얁; 얁; 얁; 얁; 얁; ) HANGUL SYLLABLE YANJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC581 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC581 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC581 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11AC }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_146)
{
    // C582;C582;110B 1163 11AD;C582;110B 1163 11AD;
    // (얂; 얂; 얂; 얂; 얂; ) HANGUL SYLLABLE YANH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC582 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC582 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC582 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11AD }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_147)
{
    // C583;C583;110B 1163 11AE;C583;110B 1163 11AE;
    // (얃; 얃; 얃; 얃; 얃; ) HANGUL SYLLABLE YAD
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC583 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC583 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC583 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11AE }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_148)
{
    // C584;C584;110B 1163 11AF;C584;110B 1163 11AF;
    // (얄; 얄; 얄; 얄; 얄; ) HANGUL SYLLABLE YAL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC584 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC584 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC584 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11AF }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_149)
{
    // C585;C585;110B 1163 11B0;C585;110B 1163 11B0;
    // (얅; 얅; 얅; 얅; 얅; ) HANGUL SYLLABLE YALG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC585 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC585 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC585 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B0 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_150)
{
    // C586;C586;110B 1163 11B1;C586;110B 1163 11B1;
    // (얆; 얆; 얆; 얆; 얆; ) HANGUL SYLLABLE YALM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC586 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC586 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC586 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B1 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_151)
{
    // C587;C587;110B 1163 11B2;C587;110B 1163 11B2;
    // (얇; 얇; 얇; 얇; 얇; ) HANGUL SYLLABLE YALB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC587 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC587 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC587 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B2 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_152)
{
    // C588;C588;110B 1163 11B3;C588;110B 1163 11B3;
    // (얈; 얈; 얈; 얈; 얈; ) HANGUL SYLLABLE YALS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC588 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC588 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC588 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B3 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_153)
{
    // C589;C589;110B 1163 11B4;C589;110B 1163 11B4;
    // (얉; 얉; 얉; 얉; 얉; ) HANGUL SYLLABLE YALT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC589 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC589 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC589 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B4 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_154)
{
    // C58A;C58A;110B 1163 11B5;C58A;110B 1163 11B5;
    // (얊; 얊; 얊; 얊; 얊; ) HANGUL SYLLABLE YALP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC58A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC58A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC58A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B5 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_155)
{
    // C58B;C58B;110B 1163 11B6;C58B;110B 1163 11B6;
    // (얋; 얋; 얋; 얋; 얋; ) HANGUL SYLLABLE YALH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC58B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC58B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC58B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B6 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_156)
{
    // C58C;C58C;110B 1163 11B7;C58C;110B 1163 11B7;
    // (얌; 얌; 얌; 얌; 얌; ) HANGUL SYLLABLE YAM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC58C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC58C }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC58C }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B7 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_157)
{
    // C58D;C58D;110B 1163 11B8;C58D;110B 1163 11B8;
    // (얍; 얍; 얍; 얍; 얍; ) HANGUL SYLLABLE YAB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC58D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC58D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC58D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B8 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_158)
{
    // C58E;C58E;110B 1163 11B9;C58E;110B 1163 11B9;
    // (얎; 얎; 얎; 얎; 얎; ) HANGUL SYLLABLE YABS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC58E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC58E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC58E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11B9 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_159)
{
    // C58F;C58F;110B 1163 11BA;C58F;110B 1163 11BA;
    // (얏; 얏; 얏; 얏; 얏; ) HANGUL SYLLABLE YAS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC58F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC58F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC58F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11BA }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_160)
{
    // C590;C590;110B 1163 11BB;C590;110B 1163 11BB;
    // (얐; 얐; 얐; 얐; 얐; ) HANGUL SYLLABLE YASS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC590 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC590 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC590 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11BB }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_161)
{
    // C591;C591;110B 1163 11BC;C591;110B 1163 11BC;
    // (양; 양; 양; 양; 양; ) HANGUL SYLLABLE YANG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC591 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC591 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC591 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11BC }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_162)
{
    // C592;C592;110B 1163 11BD;C592;110B 1163 11BD;
    // (얒; 얒; 얒; 얒; 얒; ) HANGUL SYLLABLE YAJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC592 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC592 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC592 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11BD }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_163)
{
    // C593;C593;110B 1163 11BE;C593;110B 1163 11BE;
    // (얓; 얓; 얓; 얓; 얓; ) HANGUL SYLLABLE YAC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC593 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC593 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC593 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11BE }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_164)
{
    // C594;C594;110B 1163 11BF;C594;110B 1163 11BF;
    // (얔; 얔; 얔; 얔; 얔; ) HANGUL SYLLABLE YAK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC594 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC594 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC594 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11BF }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_165)
{
    // C595;C595;110B 1163 11C0;C595;110B 1163 11C0;
    // (얕; 얕; 얕; 얕; 얕; ) HANGUL SYLLABLE YAT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC595 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC595 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC595 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11C0 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_166)
{
    // C596;C596;110B 1163 11C1;C596;110B 1163 11C1;
    // (얖; 얖; 얖; 얖; 얖; ) HANGUL SYLLABLE YAP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC596 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC596 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC596 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11C1 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_167)
{
    // C597;C597;110B 1163 11C2;C597;110B 1163 11C2;
    // (얗; 얗; 얗; 얗; 얗; ) HANGUL SYLLABLE YAH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC597 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC597 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1163, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC597 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1163, 0x11C2 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_168)
{
    // C598;C598;110B 1164;C598;110B 1164;
    // (얘; 얘; 얘; 얘; 얘; ) HANGUL SYLLABLE YAE
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC598 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC598 }};
        std::array<uint32_t, 2> const c3 = {{ 0x110B, 0x1164 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC598 }};
        std::array<uint32_t, 2> const c5 = {{ 0x110B, 0x1164 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_169)
{
    // C599;C599;110B 1164 11A8;C599;110B 1164 11A8;
    // (얙; 얙; 얙; 얙; 얙; ) HANGUL SYLLABLE YAEG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC599 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC599 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC599 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11A8 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_170)
{
    // C59A;C59A;110B 1164 11A9;C59A;110B 1164 11A9;
    // (얚; 얚; 얚; 얚; 얚; ) HANGUL SYLLABLE YAEGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC59A }};
        std::array<uint32_t, 1> const c2 = {{ 0xC59A }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC59A }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11A9 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_171)
{
    // C59B;C59B;110B 1164 11AA;C59B;110B 1164 11AA;
    // (얛; 얛; 얛; 얛; 얛; ) HANGUL SYLLABLE YAEGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC59B }};
        std::array<uint32_t, 1> const c2 = {{ 0xC59B }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC59B }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11AA }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_172)
{
    // C59C;C59C;110B 1164 11AB;C59C;110B 1164 11AB;
    // (얜; 얜; 얜; 얜; 얜; ) HANGUL SYLLABLE YAEN
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC59C }};
        std::array<uint32_t, 1> const c2 = {{ 0xC59C }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11AB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC59C }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11AB }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_173)
{
    // C59D;C59D;110B 1164 11AC;C59D;110B 1164 11AC;
    // (얝; 얝; 얝; 얝; 얝; ) HANGUL SYLLABLE YAENJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC59D }};
        std::array<uint32_t, 1> const c2 = {{ 0xC59D }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11AC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC59D }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11AC }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_174)
{
    // C59E;C59E;110B 1164 11AD;C59E;110B 1164 11AD;
    // (얞; 얞; 얞; 얞; 얞; ) HANGUL SYLLABLE YAENH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC59E }};
        std::array<uint32_t, 1> const c2 = {{ 0xC59E }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11AD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC59E }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11AD }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_175)
{
    // C59F;C59F;110B 1164 11AE;C59F;110B 1164 11AE;
    // (얟; 얟; 얟; 얟; 얟; ) HANGUL SYLLABLE YAED
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC59F }};
        std::array<uint32_t, 1> const c2 = {{ 0xC59F }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11AE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC59F }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11AE }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_176)
{
    // C5A0;C5A0;110B 1164 11AF;C5A0;110B 1164 11AF;
    // (얠; 얠; 얠; 얠; 얠; ) HANGUL SYLLABLE YAEL
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11AF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11AF }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_177)
{
    // C5A1;C5A1;110B 1164 11B0;C5A1;110B 1164 11B0;
    // (얡; 얡; 얡; 얡; 얡; ) HANGUL SYLLABLE YAELG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B0 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_178)
{
    // C5A2;C5A2;110B 1164 11B1;C5A2;110B 1164 11B1;
    // (얢; 얢; 얢; 얢; 얢; ) HANGUL SYLLABLE YAELM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B1 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_179)
{
    // C5A3;C5A3;110B 1164 11B2;C5A3;110B 1164 11B2;
    // (얣; 얣; 얣; 얣; 얣; ) HANGUL SYLLABLE YAELB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B2 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_180)
{
    // C5A4;C5A4;110B 1164 11B3;C5A4;110B 1164 11B3;
    // (얤; 얤; 얤; 얤; 얤; ) HANGUL SYLLABLE YAELS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A4 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A4 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B3 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_181)
{
    // C5A5;C5A5;110B 1164 11B4;C5A5;110B 1164 11B4;
    // (얥; 얥; 얥; 얥; 얥; ) HANGUL SYLLABLE YAELT
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B4 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_182)
{
    // C5A6;C5A6;110B 1164 11B5;C5A6;110B 1164 11B5;
    // (얦; 얦; 얦; 얦; 얦; ) HANGUL SYLLABLE YAELP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B5 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_183)
{
    // C5A7;C5A7;110B 1164 11B6;C5A7;110B 1164 11B6;
    // (얧; 얧; 얧; 얧; 얧; ) HANGUL SYLLABLE YAELH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B6 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_184)
{
    // C5A8;C5A8;110B 1164 11B7;C5A8;110B 1164 11B7;
    // (얨; 얨; 얨; 얨; 얨; ) HANGUL SYLLABLE YAEM
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A8 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B7 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_185)
{
    // C5A9;C5A9;110B 1164 11B8;C5A9;110B 1164 11B8;
    // (얩; 얩; 얩; 얩; 얩; ) HANGUL SYLLABLE YAEB
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5A9 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5A9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5A9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B8 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_186)
{
    // C5AA;C5AA;110B 1164 11B9;C5AA;110B 1164 11B9;
    // (얪; 얪; 얪; 얪; 얪; ) HANGUL SYLLABLE YAEBS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5AA }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5AA }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5AA }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11B9 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_187)
{
    // C5AB;C5AB;110B 1164 11BA;C5AB;110B 1164 11BA;
    // (얫; 얫; 얫; 얫; 얫; ) HANGUL SYLLABLE YAES
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5AB }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5AB }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11BA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5AB }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11BA }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_188)
{
    // C5AC;C5AC;110B 1164 11BB;C5AC;110B 1164 11BB;
    // (얬; 얬; 얬; 얬; 얬; ) HANGUL SYLLABLE YAESS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5AC }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5AC }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11BB }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5AC }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11BB }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_189)
{
    // C5AD;C5AD;110B 1164 11BC;C5AD;110B 1164 11BC;
    // (얭; 얭; 얭; 얭; 얭; ) HANGUL SYLLABLE YAENG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5AD }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5AD }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11BC }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5AD }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11BC }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_190)
{
    // C5AE;C5AE;110B 1164 11BD;C5AE;110B 1164 11BD;
    // (얮; 얮; 얮; 얮; 얮; ) HANGUL SYLLABLE YAEJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5AE }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5AE }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11BD }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5AE }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11BD }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_191)
{
    // C5AF;C5AF;110B 1164 11BE;C5AF;110B 1164 11BE;
    // (얯; 얯; 얯; 얯; 얯; ) HANGUL SYLLABLE YAEC
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5AF }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5AF }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11BE }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5AF }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11BE }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_192)
{
    // C5B0;C5B0;110B 1164 11BF;C5B0;110B 1164 11BF;
    // (얰; 얰; 얰; 얰; 얰; ) HANGUL SYLLABLE YAEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5B0 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5B0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11BF }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5B0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11BF }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_193)
{
    // C5B1;C5B1;110B 1164 11C0;C5B1;110B 1164 11C0;
    // (얱; 얱; 얱; 얱; 얱; ) HANGUL SYLLABLE YAET
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5B1 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5B1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11C0 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5B1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11C0 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_194)
{
    // C5B2;C5B2;110B 1164 11C1;C5B2;110B 1164 11C1;
    // (얲; 얲; 얲; 얲; 얲; ) HANGUL SYLLABLE YAEP
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5B2 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5B2 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11C1 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5B2 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11C1 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_195)
{
    // C5B3;C5B3;110B 1164 11C2;C5B3;110B 1164 11C2;
    // (얳; 얳; 얳; 얳; 얳; ) HANGUL SYLLABLE YAEH
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5B3 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5B3 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1164, 0x11C2 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5B3 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1164, 0x11C2 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_196)
{
    // C5B4;C5B4;110B 1165;C5B4;110B 1165;
    // (어; 어; 어; 어; 어; ) HANGUL SYLLABLE EO
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5B4 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5B4 }};
        std::array<uint32_t, 2> const c3 = {{ 0x110B, 0x1165 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5B4 }};
        std::array<uint32_t, 2> const c5 = {{ 0x110B, 0x1165 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_197)
{
    // C5B5;C5B5;110B 1165 11A8;C5B5;110B 1165 11A8;
    // (억; 억; 억; 억; 억; ) HANGUL SYLLABLE EOG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5B5 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5B5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1165, 0x11A8 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5B5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1165, 0x11A8 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_198)
{
    // C5B6;C5B6;110B 1165 11A9;C5B6;110B 1165 11A9;
    // (얶; 얶; 얶; 얶; 얶; ) HANGUL SYLLABLE EOGG
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5B6 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5B6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1165, 0x11A9 }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5B6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1165, 0x11A9 }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

TEST(normalization, nfc_044_199)
{
    // C5B7;C5B7;110B 1165 11AA;C5B7;110B 1165 11AA;
    // (얷; 얷; 얷; 얷; 얷; ) HANGUL SYLLABLE EOGS
    {
        std::array<uint32_t, 1> const c1 = {{ 0xC5B7 }};
        std::array<uint32_t, 1> const c2 = {{ 0xC5B7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x110B, 0x1165, 0x11AA }};
        std::array<uint32_t, 1> const c4 = {{ 0xC5B7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x110B, 0x1165, 0x11AA }};

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

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

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

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

        {
            boost::text::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

        {
            boost::text::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize_to_nfc(str);
            boost::text::utf32_range utf32_range(str);
            EXPECT_EQ(std::distance(utf32_range.begin(), utf32_range.end()), (std::ptrdiff_t)c2.size());
            auto c2_it = c2.begin();
            int i = 0;
            for (auto x : utf32_range) {
                EXPECT_EQ(x, *c2_it) << "iteration " << i;
                ++c2_it;
                ++i;
            }
        }

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

    }
}

ext: cpp

max_stars_repo_name: fmtlib/text

max_issues_repo_name: fmtlib/text